JRuby

File.truncate errors with "No such file or directory" when the file exists.

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: JRuby 1.1.3, JRuby 1.1.4
  • Fix Version/s: JRuby 1.1.5
  • Component/s: Core Classes/Modules
  • Labels:
    None
  • Environment:
    Ubuntu 8.04
    jruby 1.1.4 (ruby 1.8.6 patchlevel 114) (2008-08-28 rev 7570) [i386-java]
    java version "1.6.0_06"
    Java(TM) SE Runtime Environment (build 1.6.0_06-b02)
    Java HotSpot(TM) Server VM (build 10.0-b22, mixed mode)
  • Number of attachments :
    0

Description

JRuby File#truncate raises a Errno::ENOENT error when Matz Ruby does not.

jirb:

irb(main):001:0> f = "/var/run/gem_server.pid"
=> "/var/run/gem_server.pid"
irb(main):002:0> File.exists? f
=> true
irb(main):003:0> File.writable? f
=> true
irb(main):004:0> File.writable_real? f
=> true
irb(main):005:0> File.zero? f
=> false
irb(main):006:0> File.truncate(f, 0)
Errno::ENOENT: No such file or directory - No such file or directory - /var/run/gem_server.pid
irb(main):007:0> exit

irb

irb(main):001:0> f = "/var/run/gem_server.pid"
=> "/var/run/gem_server.pid"
irb(main):002:0> File.exists? f
=> true
irb(main):003:0> File.writable? f
=> true
irb(main):004:0> File.writable_real? f
=> true
irb(main):005:0> File.zero? f
=> false
irb(main):006:0> File.truncate(f, 0)
=> 0
irb(main):007:0> exit

Activity

Hide
Brian Tatnall added a comment -

Should be File::truncate instead of File#truncate.

Show
Brian Tatnall added a comment - Should be File::truncate instead of File#truncate.
Hide
Brian Tatnall added a comment -

Error occurs on trunk as well:
jruby 1.1.4 (ruby 1.8.6 patchlevel 114) (2008-09-30 rev 7803) [i386-java]

Show
Brian Tatnall added a comment - Error occurs on trunk as well: jruby 1.1.4 (ruby 1.8.6 patchlevel 114) (2008-09-30 rev 7803) [i386-java]
Hide
Brian Tatnall added a comment -

The problem was caused by the file_name passed to truncate being an absolute path.

The JRuby truncate method used public File(String parent, String child), which appended the file_name to the current working directory.

This results in the following:

runtime> current_directory = /home/btatnall/working/jruby/trunk/jruby
arg1> filename = /var/run/gem_server.pid
testfile> name = gem_server.pid
testfile> parent = /home/btatnall/working/jruby/trunk/jruby/var/run
testfile> path = /home/btatnall/working/jruby/trunk/jruby/var/run/gem_server.pid
testfile> exists = false

Notice that parent path is the current working directory combined with the dirname of the filename passed in.

Here's a patch that works on my system. I'm having a hard time getting the proper tests to run.

btatnall@btatnall00:~/working/jruby/trunk/jruby$ svn diff
Index: src/org/jruby/RubyFile.java
===================================================================
--- src/org/jruby/RubyFile.java	(revision 7803)
+++ src/org/jruby/RubyFile.java	(working copy)
@@ -1432,8 +1432,17 @@
         Ruby runtime = context.getRuntime();
         RubyString filename = arg1.convertToString(); // TODO: SafeStringValue here
         RubyInteger newLength = arg2.convertToInteger(); 
-        
-        if (!new File(runtime.getCurrentDirectory(), filename.getByteList().toString()).exists()) {
+
+        File testFile ;
+        File childFile = new File(filename.getByteList().toString() );
+
+        if ( childFile.isAbsolute() ) {
+          testFile = childFile ;
+        } else {
+          testFile = new File(runtime.getCurrentDirectory(), filename.getByteList().toString());
+        }
+
+        if (!testFile.exists()) {
             throw runtime.newErrnoENOENTError(
                     "No such file or directory - " + filename.getByteList().toString());
         }
@@ -1441,7 +1450,7 @@
         if (newLength.getLongValue() < 0) {
             throw runtime.newErrnoEINVALError("invalid argument: " + filename);
         }
-        
+
         IRubyObject[] args = new IRubyObject[] { filename, runtime.newString("r+") };
         RubyFile file = (RubyFile) open(context, recv, args, Block.NULL_BLOCK);
         file.truncate(context, newLength);
Show
Brian Tatnall added a comment - The problem was caused by the file_name passed to truncate being an absolute path. The JRuby truncate method used public File(String parent, String child), which appended the file_name to the current working directory. This results in the following:
runtime> current_directory = /home/btatnall/working/jruby/trunk/jruby
arg1> filename = /var/run/gem_server.pid
testfile> name = gem_server.pid
testfile> parent = /home/btatnall/working/jruby/trunk/jruby/var/run
testfile> path = /home/btatnall/working/jruby/trunk/jruby/var/run/gem_server.pid
testfile> exists = false
Notice that parent path is the current working directory combined with the dirname of the filename passed in. Here's a patch that works on my system. I'm having a hard time getting the proper tests to run.
btatnall@btatnall00:~/working/jruby/trunk/jruby$ svn diff
Index: src/org/jruby/RubyFile.java
===================================================================
--- src/org/jruby/RubyFile.java	(revision 7803)
+++ src/org/jruby/RubyFile.java	(working copy)
@@ -1432,8 +1432,17 @@
         Ruby runtime = context.getRuntime();
         RubyString filename = arg1.convertToString(); // TODO: SafeStringValue here
         RubyInteger newLength = arg2.convertToInteger(); 
-        
-        if (!new File(runtime.getCurrentDirectory(), filename.getByteList().toString()).exists()) {
+
+        File testFile ;
+        File childFile = new File(filename.getByteList().toString() );
+
+        if ( childFile.isAbsolute() ) {
+          testFile = childFile ;
+        } else {
+          testFile = new File(runtime.getCurrentDirectory(), filename.getByteList().toString());
+        }
+
+        if (!testFile.exists()) {
             throw runtime.newErrnoENOENTError(
                     "No such file or directory - " + filename.getByteList().toString());
         }
@@ -1441,7 +1450,7 @@
         if (newLength.getLongValue() < 0) {
             throw runtime.newErrnoEINVALError("invalid argument: " + filename);
         }
-        
+
         IRubyObject[] args = new IRubyObject[] { filename, runtime.newString("r+") };
         RubyFile file = (RubyFile) open(context, recv, args, Block.NULL_BLOCK);
         file.truncate(context, newLength);
Hide
Brian Tatnall added a comment -

I've added a spec to the RubySpecs project here:
http://rubyspec.org/projects/rubyspec/issues/show?id=70

Show
Brian Tatnall added a comment - I've added a spec to the RubySpecs project here: http://rubyspec.org/projects/rubyspec/issues/show?id=70
Hide
Charles Oliver Nutter added a comment -

Good find, marking for 1.1.5. Testing now.

Show
Charles Oliver Nutter added a comment - Good find, marking for 1.1.5. Testing now.
Hide
Charles Oliver Nutter added a comment -

Tests appear to run ok, so I went ahead with it. Thanks for the patch and rubyspecs update!

Show
Charles Oliver Nutter added a comment - Tests appear to run ok, so I went ahead with it. Thanks for the patch and rubyspecs update!

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: