Hi, >From: "Berger, Daniel" <Daniel.Berger / qwest.com> >Reply-To: ruby-talk / ruby-lang.org >To: ruby-talk / ruby-lang.org (ruby-talk ML) >Subject: Trying to get stat, Win32API to work >Date: Sat, 1 Apr 2006 05:46:36 +0900 > >Hi all, > >Ruby 1.8.4 >Windows XP > >I'm trying to make a pure Ruby version of File::Stat. Something seems >to go wrong around the time I get rdev. I think I just need another set >of eyes to see what I'm doing wrong here. > >Thanks, > >Dan > ># stat.rb > ... > It is due to the structure alignment. Applications should generally align structure members at addresses that are ¡°natural¡± for the data type and the processor involved. For example, a 4-byte data member should have an address that is a multiple of four. Refer to http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_core_structure_alignment.asp Your code should be like this: # stat.rb require 'Win32API' # Based on what I see in sys/types.h: # # ino_t - unsigned short # dev_t - unsigned int # off_t - long # time_t - long =begin struct _stat { _dev_t st_dev; # 'I', 4 _ino_t st_ino; # 'S', 2 unsigned short st_mode; # 'S', 2 short st_nlink; # 's', 2 short st_uid; # 's', 2 short st_gid; # 's', 2 short padding; # 's', 2 ---> invisible padding 2 bytes for structure alignment _dev_t st_rdev; # 'I', 4 _off_t st_size; # 'l', 4 time_t st_atime; # 'l', 4 time_t st_mtime; # 'l', 4 time_t st_ctime; # 'l', 4 }; =end class File::Stat @@stat = Win32API.new('msvcrt', '_stat', 'PP', 'I') def initialize(file) stat_buf = [0,0,0,0,0,0,0,0,0,0,0,0].pack('ISSssssIllll') @@stat.call(file, stat_buf) @dev = stat_buf[0..3].unpack('I').first @ino = stat_buf[4..5].unpack('S').first @mode = stat_buf[6..7].unpack('S').first @nlink = stat_buf[8..9].unpack('s').first @uid = stat_buf[10..11].unpack('s').first @gid = stat_buf[12..13].unpack('s').first @rdev = stat_buf[16..19].unpack('I').first @size = stat_buf[20..23].unpack('l').first @atime = stat_buf[24..27].unpack('l').first @mtime = stat_buf[28..31].unpack('l').first @ctime = stat_buf[32..35].unpack('l').first puts "Dev: [#{@dev}]" puts "Ino: [#{@ino}]" puts "Mode: [#{@mode}]" puts "Nlink: [#{@nlink}]" puts "Uid: [#{@uid}]" puts "Gid: [#{@gid}]" puts "RDev: [#{@rdev}]" # Things start to look wrong here... puts "Size: [#{@size}]" puts "Atime: [" + Time.at(@atime).to_s + "]" puts "Mtime: [" + Time.at(@mtime).to_s + "]" puts "Ctime: [" + Time.at(@ctime).to_s + "]" end end if $0 == __FILE__ File::Stat.new('r.rb') end Regards, Park Heesob