Skip to content

Commit

Permalink
Support File#truncate and File#ftruncate correctly
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
chuckremes committed Oct 2, 2015
1 parent f4bd9c7 commit 4072455
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 11 deletions.
4 changes: 2 additions & 2 deletions kernel/common/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,7 @@ def self.truncate(path, length)

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

prim_truncate(path, length)
FileDescriptor.truncate(path, length)
end

##
Expand Down Expand Up @@ -1270,7 +1270,7 @@ def truncate(length)

flush
reset_buffering
prim_ftruncate(length)
@fd.ftruncate(length)
end

def inspect
Expand Down
26 changes: 17 additions & 9 deletions kernel/common/io.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def self.choose_type(fd)
when "socket"
raise "cannot make socket yet"
when "directory"
raise "cannot make a directory"
DirectoryFileDescriptor.new(fd, stat)
when "blockSpecial"
raise "cannot make block special"
when "link"
Expand Down Expand Up @@ -110,6 +110,14 @@ def self.pagesize
@pagesize ||= FFI::Platform::POSIX.getpagesize
end

def self.truncate(name, offset)
raise RangeError, "bignum too big to convert into `long'" if offset.kind_of?(Bignum)

status = FFI::Platform::POSIX.truncate(name, offset)
Errno.handle("truncate(2) failed") if FFI.call_failed?(status)
return status
end

def self.update_max_fd(new_fd)
@@max_descriptors.get_and_set(new_fd)
end
Expand Down Expand Up @@ -272,6 +280,11 @@ def write(str)
left -= bytes_written
buffer += bytes_written
@offset += bytes_written

if @offset > @total_size
@total_size = @offset
@eof = false # only a failed read can set EOF!
end
end

Errno.handle("write failed") if error
Expand Down Expand Up @@ -469,14 +482,6 @@ def ftruncate(offset)
return status
end

def truncate(name, offset)
# FIXME: fail if +offset+ is too large, see C++ code

status = FFI::Platform::POSIX.truncate(name, offset)
Errno.handle("truncate(2) failed") if FFI.call_failed?(status)
return status
end

##
# Returns true if ios is associated with a terminal device (tty), false otherwise.
#
Expand Down Expand Up @@ -685,6 +690,9 @@ def sysseek(offset, whence=SEEK_SET)
end
end # class FIFOFileDescriptor

class DirectoryFileDescriptor < FileDescriptor
end # class DirectoryFileDescriptor

# Encapsulates all of the logic necessary for handling #select.
class Select
#eval(Rubinius::Config['rbx.platform.timeval.class'])
Expand Down

0 comments on commit 4072455

Please sign in to comment.