[Win32utils-devel] [ win32utils-Bugs-23746 ] File.size fails on locked file (and causes major rdebug wierdness)

noreply at rubyforge.org noreply at rubyforge.org
Sat Jan 31 07:01:10 EST 2009


Bugs item #23746, was opened at 2009-01-29 20:17
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=411&aid=23746&group_id=85

Category: None
Group: None
Status: Open
Resolution: Accepted
Priority: 3
Submitted By: Montgomery Kosma (mkosma)
Assigned to: Nobody (None)
Summary: File.size fails on locked file (and causes major rdebug wierdness)

Initial Comment:
Running the following script fails in an ugly fashion.  Note that the default File.size does not fail (but it also returns an incorrect result, a negative number).  

#test.rb
require 'win32/file'
x = File.size('c:/pagefile.sys')
puts x

C:\docs\Prog\PSTTools>test.rb
c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:586:
in `get_file_type': unknown error - The process cannot access the file because it is being used by another process. (SystemCallError)
        from c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:58:in `initialize'
        from c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `new'
        from c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `size'
        from C:/docs/Prog/PSTTools/test.rb:3


So I tried to dig into the win32-file source to see where it's failing -- a size command really shouldn't need to lock the file.  The really puzzling thing is that I cannot successfully run rdebug on this.  Even if I set a breakpoint before the call to File.size, rdebug errors out before it arrives.  I'm not skilled enough (yet) to determine if this is related to the win32-size bug, or a problem with rdebug (ver 0.10.3).  Here's what happens:

C:\docs\Prog\PSTTools>rdebug test.rb
C:/docs/Prog/PSTTools/test.rb:1
require 'win32/file'
(rdb:1) list
[-4, 5] in C:/docs/Prog/PSTTools/test.rb
=> 1  require 'win32/file'
   2
   3  x = File.size('c:/pagefile.sys')
   4  puts x
   5
(rdb:1) b 3
Breakpoint 1 file C:/docs/Prog/PSTTools/test.rb, line 3
(rdb:1) n
INTERNAL ERROR!!! no implicit conversion from nil to integer
        c:/ruby/lib/ruby/1.8/pathname.rb:269:in `[]'
        c:/ruby/lib/ruby/1.8/pathname.rb:269:in `chop_basename'
        c:/ruby/lib/ruby/1.8/pathname.rb:322:in `cleanpath_aggressive'
        c:/ruby/lib/ruby/1.8/pathname.rb:310:in `cleanpath'
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:93:in `canonic_file'
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:98:in `print_location_and_text'
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:243:in `process_commands'
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/cli/ruby-debug/processor.rb:171:in `__at_line'
        (eval):5:in `at_line'
        (eval):3:in `synchronize'
        (eval):3:in `at_line'
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-base-0.10.3-x86-mswin32/lib/ruby-debug-base.rb:54:in `at_line'
        C:/docs/Prog/PSTTools/test.rb:3
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_load'
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_program'
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:412
        c:/ruby/bin/rdebug:19:in `load'
        c:/ruby/bin/rdebug:19   c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:586:in `get_file_type'
        c:/ruby/lib/ruby/gems/1.8/gems/win32-file-stat-1.3.2/lib/win32/file/stat.rb:58:in `initialize'
        c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `new'
        c:/ruby/lib/ruby/gems/1.8/gems/win32-file-0.6.0/lib/win32/file.rb:669:in `size'
        C:/docs/Prog/PSTTools/test.rb:3
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_load'
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:125:in `debug_program'
        c:/ruby/lib/ruby/gems/1.8/gems/ruby-debug-0.10.3/bin/rdebug:412
        c:/ruby/bin/rdebug:19:in `load'
        c:/ruby/bin/rdebug:19
Uncaught exception: unknown error - The process cannot access the file because it is being used by another process.


----------------------------------------------------------------------

>Comment By: Daniel Berger (djberg96)
Date: 2009-01-31 05:01

Message:
That will work, thanks. The problem with that approach, however, is that it would result in having two separate implementations - one for File.size, and one for File::Stat#size.

The also noticed that GetFileAttributes fails on that file, so it's double trouble.

Maybe I should replace the Win32::File::Stat implementation with one that uses FindFirstFile, since the WIN32_FIND_DATA struct stores attribute information as well.

Dan

----------------------------------------------------------------------

Comment By: Park Heesob  (phasis68)
Date: 2009-01-30 07:30

Message:
There are two issues in this error.

First, the Standard API function CreateFile cannot open file locked by "System" such as "pagefile.sys".
We need other workaround to handle system locked file.

Second, the complex stat call is not needed to get only the file size. 
Here is a usable size method for win32-file:

      def size(file)
        # File::Stat.new(file).size
        buffer = 0.chr * 512
        h = FindFirstFile(file,buffer)
        if h == INVALID_HANDLE_VALUE
           raise SystemCallError,get_last_error()
        end
        FindClose(h)
        (buffer[28,4].unpack('L').first << 32) + buffer[32,4].unpack('L').first
      end

Regards,

Park Heesob




----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=411&aid=23746&group_id=85


More information about the win32utils-devel mailing list