Date: Sun, 12 Jan 2003 16:01:53 +0000 From: "Richard Dawe" Sender: rich AT phekda DOT freeserve DOT co DOT uk To: djgpp-workers AT delorie DOT com X-Mailer: Emacs 21.3.50 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6 Subject: fstat, fd_props and inventing inodes [PATCH] Message-Id: Reply-To: djgpp-workers AT delorie DOT com Hello. Below is a revision of Andrew's patch to make fstat generate the same inode for a file irrespective of which file name was used to open the file or how many times fstat has been called. (Calling fstat multiple times on file descriptor gives different inode values each time on Windows '98 SE.) Basically: The patch uses fd_props to obtain the file name used to open a file. It fixes up the file name and then uses that as the input to _invent_inode. Changes over Andrew's patch: * Moved _fixpath out of #ifndef NO_ST_BLKSIZE/#endif conditional, so that it'll still work when NO_ST_BLKSIZE is defined. * Updated the comments in fstat.c slightly. * Updated fstat docs. * Add a changelog entry. I tested with fileutils 4.1 and I didn't see any regressions. I tested with src/libc/posix/sys/stat/fstat.c compiled with -DTEST. OK to commit? Thanks, bye, Rich =] Index: src/libc/posix/sys/stat/fstat.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/fstat.c,v retrieving revision 1.10 diff -p -c -3 -r1.10 fstat.c *** src/libc/posix/sys/stat/fstat.c 14 Dec 2002 12:41:15 -0000 1.10 --- src/libc/posix/sys/stat/fstat.c 12 Jan 2003 15:55:56 -0000 *************** fstat_assist(int fhandle, struct stat *s *** 380,385 **** --- 380,387 ---- unsigned short trusted_ftime = 0, trusted_fdate = 0; long trusted_fsize = 0; int is_link = 0; + const char *filename; + char fixed_filename[PATH_MAX + 1]; if ((dev_info = _get_dev_info(fhandle)) == -1) return -1; /* errno set by _get_dev_info() */ *************** fstat_assist(int fhandle, struct stat *s *** 396,401 **** --- 398,404 ---- /* Initialize buffers. */ memset(stat_buf, 0, sizeof(struct stat)); + memset(fixed_filename, 0, sizeof(fixed_filename)); dos_ftime = 0; /* Get some info about this handle by conventional DOS calls. These *************** fstat_assist(int fhandle, struct stat *s *** 433,447 **** stat_buf->st_gid = getgid(); stat_buf->st_nlink = 1; ! /* Get the block size for the device associated with `fhandle'. */ ! #ifndef NO_ST_BLKSIZE if (__get_fd_name(fhandle)) { - const char *filename; - char fixed_filename[PATH_MAX + 1]; - filename = __get_fd_name(fhandle); _fixpath(filename, fixed_filename); stat_buf->st_blksize = _get_cached_blksize(fixed_filename); if (stat_buf->st_blksize == -1) return -1; /* errno set by _get_cached_blksize() */ --- 436,453 ---- stat_buf->st_gid = getgid(); stat_buf->st_nlink = 1; ! /* Get the file name from the file descriptor properties (fd_props), ! * if possible, and fix it up. */ if (__get_fd_name(fhandle)) { filename = __get_fd_name(fhandle); _fixpath(filename, fixed_filename); + } + + /* Get the block size for the device associated with `fhandle'. */ + #ifndef NO_ST_BLKSIZE + if (*fixed_filename) + { stat_buf->st_blksize = _get_cached_blksize(fixed_filename); if (stat_buf->st_blksize == -1) return -1; /* errno set by _get_cached_blksize() */ *************** fstat_assist(int fhandle, struct stat *s *** 803,815 **** } else { ! /* Regular file. The inode will be arbitrary, as we don't have ! * this file's name. Sigh... */ if ( (_djstat_flags & _STAT_INODE) == 0 ) { _djstat_fail_bits |= _STFAIL_HASH; ! stat_buf->st_ino = _invent_inode("", dos_ftime, trusted_fsize); } if (trusted_fsize == 510) --- 809,824 ---- } else { ! /* Regular file. We may have obtained this file's name ! * from the file descriptor properties (fd_props). Otherwise ! * the inode will be arbitrary each time fstat is called. ! * Sigh... */ if ( (_djstat_flags & _STAT_INODE) == 0 ) { _djstat_fail_bits |= _STFAIL_HASH; ! stat_buf->st_ino ! = _invent_inode(fixed_filename, dos_ftime, trusted_fsize); } if (trusted_fsize == 510) Index: src/libc/posix/sys/stat/fstat.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/fstat.txh,v retrieving revision 1.9 diff -p -c -3 -r1.9 fstat.txh *** src/libc/posix/sys/stat/fstat.txh 1 Dec 2001 20:22:37 -0000 1.9 --- src/libc/posix/sys/stat/fstat.txh 12 Jan 2003 15:55:56 -0000 *************** files for identity should include compar *** 84,93 **** member.) 3. On all versions of Windows except Windows 3.X, the inode number is ! invented. As Windows doesn't provide enough information to identify ! files by the handle on which they are open, @code{fstat} always returns ! different inode numbers for any two files open on different handles, ! even if the same file is open twice on two different handles. 4. The WRITE access mode bit is set only for the user (unless the file is read-only, hidden or system). EXECUTE bit is set for directories, files --- 84,97 ---- member.) 3. On all versions of Windows except Windows 3.X, the inode number is ! invented using the file name. @code{fstat} can probably use the file name ! that was used to open the file, when generating the inode. This is done ! such that the same inode will be generated irrespective of the actual path ! used to open the file (e.g.: @samp{foo.txt}, @samp{./foo.txt}, ! @samp{../somedir/foo.txt}). If file names cannot be used, @code{fstat} ! always returns different inode numbers for any two files open ! on different handles, even if the same file is open twice ! on two different handles. 4. The WRITE access mode bit is set only for the user (unless the file is read-only, hidden or system). EXECUTE bit is set for directories, files Index: src/docs/kb/wc204.txi =================================================================== RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v retrieving revision 1.132 diff -p -c -3 -r1.132 wc204.txi *** src/docs/kb/wc204.txi 8 Jan 2003 20:18:00 -0000 1.132 --- src/docs/kb/wc204.txi 12 Jan 2003 15:56:01 -0000 *************** to @code{getenv} which are not needed. *** 836,838 **** --- 836,845 ---- @findex strtof The function @code{strtof} was added. + + @findex fstat AT r{, and inodes} + @code{fstat} will now use the file name used to open the file, + when inventing inodes. This is done so that the same inode is generated + irrespective of the actual file path used to open the file. This also + fixes the problem where multiple calls to fstat + on the same file descriptor would give different inodes.