Skip to content

Commit 4072455

Browse files
committedOct 2, 2015
Support File#truncate and File#ftruncate correctly
Turns out that #truncate needed to be a class method, so I moved it to a class method of FileDescriptor. Also added support for creating a DirectoryFileDescriptor. It merely inherits from FileDescriptor now. We will see if it needs any new behavior or if default behavior needs to be curtailed.
1 parent f4bd9c7 commit 4072455

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed
 

‎kernel/common/file.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,7 @@ def self.truncate(path, length)
10351035

10361036
length = Rubinius::Type.coerce_to length, Integer, :to_int
10371037

1038-
prim_truncate(path, length)
1038+
FileDescriptor.truncate(path, length)
10391039
end
10401040

10411041
##
@@ -1270,7 +1270,7 @@ def truncate(length)
12701270

12711271
flush
12721272
reset_buffering
1273-
prim_ftruncate(length)
1273+
@fd.ftruncate(length)
12741274
end
12751275

12761276
def inspect

‎kernel/common/io.rb

+17-9
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def self.choose_type(fd)
6363
when "socket"
6464
raise "cannot make socket yet"
6565
when "directory"
66-
raise "cannot make a directory"
66+
DirectoryFileDescriptor.new(fd, stat)
6767
when "blockSpecial"
6868
raise "cannot make block special"
6969
when "link"
@@ -110,6 +110,14 @@ def self.pagesize
110110
@pagesize ||= FFI::Platform::POSIX.getpagesize
111111
end
112112

113+
def self.truncate(name, offset)
114+
raise RangeError, "bignum too big to convert into `long'" if offset.kind_of?(Bignum)
115+
116+
status = FFI::Platform::POSIX.truncate(name, offset)
117+
Errno.handle("truncate(2) failed") if FFI.call_failed?(status)
118+
return status
119+
end
120+
113121
def self.update_max_fd(new_fd)
114122
@@max_descriptors.get_and_set(new_fd)
115123
end
@@ -272,6 +280,11 @@ def write(str)
272280
left -= bytes_written
273281
buffer += bytes_written
274282
@offset += bytes_written
283+
284+
if @offset > @total_size
285+
@total_size = @offset
286+
@eof = false # only a failed read can set EOF!
287+
end
275288
end
276289

277290
Errno.handle("write failed") if error
@@ -469,14 +482,6 @@ def ftruncate(offset)
469482
return status
470483
end
471484

472-
def truncate(name, offset)
473-
# FIXME: fail if +offset+ is too large, see C++ code
474-
475-
status = FFI::Platform::POSIX.truncate(name, offset)
476-
Errno.handle("truncate(2) failed") if FFI.call_failed?(status)
477-
return status
478-
end
479-
480485
##
481486
# Returns true if ios is associated with a terminal device (tty), false otherwise.
482487
#
@@ -685,6 +690,9 @@ def sysseek(offset, whence=SEEK_SET)
685690
end
686691
end # class FIFOFileDescriptor
687692

693+
class DirectoryFileDescriptor < FileDescriptor
694+
end # class DirectoryFileDescriptor
695+
688696
# Encapsulates all of the logic necessary for handling #select.
689697
class Select
690698
#eval(Rubinius::Config['rbx.platform.timeval.class'])

0 commit comments

Comments
 (0)
Please sign in to comment.