Issue Details (XML | Word | Printable)

Key: JRUBY-3025
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Unassigned
Reporter: Brian Tatnall
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
JRuby

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

Created: 30/Sep/08 08:57 AM   Updated: 12/Jan/09 04:28 PM
Component/s: Core Classes/Modules
Affects Version/s: JRuby 1.1.3, JRuby 1.1.4
Fix Version/s: JRuby 1.1.5

Time Tracking:
Not Specified

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)


 Description  « Hide
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


 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Brian Tatnall added a comment - 30/Sep/08 09:03 AM
Should be File::truncate instead of File#truncate.

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

Brian Tatnall added a comment - 30/Sep/08 10:43 AM
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);

Brian Tatnall added a comment - 30/Sep/08 01:10 PM
I've added a spec to the RubySpecs project here:
http://rubyspec.org/projects/rubyspec/issues/show?id=70

Charles Oliver Nutter added a comment - 01/Oct/08 03:16 PM
Good find, marking for 1.1.5. Testing now.

Charles Oliver Nutter added a comment - 01/Oct/08 03:30 PM
Tests appear to run ok, so I went ahead with it. Thanks for the patch and rubyspecs update!