From: Tietew Date: 2003-11-18T22:28:55+09:00 Subject: [ruby-dev:21951] Re: [ruby-cvs] ruby, ruby/lib, ruby/test/fileutils: * lib/fileutils.rb (fu_same?): check by inode instead of path name, to detect two hard links pointing to the same content. On Tue, 18 Nov 2003 21:45:24 +0900 In article <20031118214513.689341.eban@os.rim.or.jp> [[ruby-dev:21950] Re: [ruby-cvs] ruby, ruby/lib, ruby/test/fileutils: * lib/fileutils.rb (fu_same?): check by inode instead of path name, to detect two hard links pointing to the same content.] WATANABE Hirofumi wrote: > > rb_w32_stat に手を加えて st_ino に有効な値(それでも NTFS オンリー > > だが)が入るようにしようと思ったら,NTFS のインデクス番号は > > 64bit で (see BY_HANDLE_INFORMATION),st_ino (_ino_t == unsigned short!) > > には絶対に入らない! がーん!! > > そのためにCygwinではino_tが64ビットになってます。 む,無理矢理 64bit 化パッチ (^^;; # 注: このままだと File::Stat#size が 64bit size に対応できてない。 ? win32/ino.patch Index: win32/Makefile.sub =================================================================== RCS file: /src/ruby/win32/Makefile.sub,v retrieving revision 1.54 diff -p -u -2 -r1.54 Makefile.sub --- win32/Makefile.sub 5 Nov 2003 02:15:27 -0000 1.54 +++ win32/Makefile.sub 18 Nov 2003 13:26:15 -0000 @@ -281,4 +281,5 @@ config.h: #define FILE_COUNT _cnt #define FILE_READPTR _ptr +#define HUGE_ST_INO 1 #define DEFAULT_KCODE KCODE_NONE #define DLEXT ".so" Index: win32/win32.c =================================================================== RCS file: /src/ruby/win32/win32.c,v retrieving revision 1.101 diff -p -u -2 -r1.101 win32.c --- win32/win32.c 6 Nov 2003 02:42:10 -0000 1.101 +++ win32/win32.c 18 Nov 2003 13:26:15 -0000 @@ -1332,5 +1332,5 @@ rb_w32_opendir(const char *filename) char scannamespc[PATHLEN]; char *scanname = scannamespc; - struct stat sbuf; + struct rb_w32_stat sbuf; struct _finddata_t fd; long fh; @@ -2703,9 +2703,36 @@ isUNCRoot(const char *path) } +static int +convert_stat(HANDLE fh, struct rb_w32_stat *st, const struct _stat *st2) +{ + BY_HANDLE_FILE_INFORMATION fi; + + st->st_dev = st2->st_dev; + st->st_ino = st2->st_ino; + st->st_mode = st2->st_mode & ~(S_IWGRP | S_IWOTH); + st->st_nlink = st2->st_nlink; + st->st_uid = st2->st_uid; + st->st_gid = st2->st_gid; + st->st_rdev = st2->st_rdev; + st->st_size = st2->st_size; + st->st_atime = st2->st_atime; + st->st_mtime = st2->st_mtime; + st->st_ctime = st2->st_ctime; + if(!GetFileInformationByHandle(fh, &fi)) { + errno = map_errno(GetLastError()); + return -1; + } + st->st_ino = ((unsigned __int64)fi.nFileIndexHigh<<32) | fi.nFileIndexLow; + st->st_nlink = fi.nNumberOfLinks; + st->st_size = ((unsigned __int64)fi.nFileSizeHigh<<32) | fi.nFileSizeLow; + return 0; +} + int -rb_w32_stat(const char *path, struct stat *st) +rb_w32_stat(const char *path, struct rb_w32_stat *st) { const char *p; char *buf1, *buf2, *s; + struct _stat st2; int len; int ret; @@ -2737,7 +2764,14 @@ rb_w32_stat(const char *path, struct sta buf2 = ALLOCA_N(char, MAXPATHLEN); if (_fullpath(buf2, buf1, MAXPATHLEN)) { - ret = stat(buf2, st); + ret = _stat(buf2, &st2); if (ret == 0) { - st->st_mode &= ~(S_IWGRP | S_IWOTH); + HANDLE fh; + fh = CreateFile(buf2, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, NULL); + if(fh != INVALID_HANDLE_VALUE) { + ret = convert_stat(fh, st, &st2); + CloseHandle(fh); + } } return ret; @@ -2747,4 +2781,16 @@ rb_w32_stat(const char *path, struct sta } +int +rb_w32_fstat(int h, struct rb_w32_stat *st) +{ + struct _stat st2; + int ret; + + ret = _fstat(h, &st2); + if(ret == 0) + return convert_stat((HANDLE)_get_osfhandle(h), st, &st2); + return ret; +} + static long filetime_to_clock(FILETIME *ft) @@ -3227,5 +3273,5 @@ rb_w32_utime(const char *path, struct ut FILETIME atime, mtime; struct tm *tm; - struct stat stat; + struct rb_w32_stat stat; int ret = 0; Index: win32/win32.h =================================================================== RCS file: /src/ruby/win32/win32.h,v retrieving revision 1.44 diff -p -u -2 -r1.44 win32.h --- win32/win32.h 26 Aug 2003 20:17:18 -0000 1.44 +++ win32/win32.h 18 Nov 2003 13:26:15 -0000 @@ -117,5 +117,20 @@ extern "C++" { #define fsync(h) _commit(h) #undef stat -#define stat(path,st) rb_w32_stat(path,st) +#define stat rb_w32_stat +#define fstat(h, st) rb_w32_fstat(h, st) + +struct rb_w32_stat { + _dev_t st_dev; + unsigned __int64 st_ino; + unsigned short st_mode; + unsigned long st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + unsigned __int64 st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +}; #ifdef __MINGW32__ @@ -480,4 +495,6 @@ int rb_w32_close(int); int rb_w32_fclose(FILE*); int rb_w32_utime(const char *, struct utimbuf *); +int rb_w32_stat(const char *, struct rb_w32_stat *); +int rb_w32_fstat(int, struct rb_w32_stat *); #define Sleep(msec) (void)rb_w32_sleep(msec) —[ Tietew ]—————————————————————————— メ : tietew@tietew.net / tietew@raug.net / tietew@masuclub.net ホペ: http://www.tietew.net/ Tietew Windows Lab. http://www.masuclub.net/ 鱒倶楽部 指紋: 26CB 71BB B595 09C4 0153 81C4 773C 963A D51B 8CAA