Sender: rich AT phekda DOT freeserve DOT co DOT uk Message-ID: <3BEE6BCC.C6164CD0@phekda.freeserve.co.uk> Date: Sun, 11 Nov 2001 12:15:08 +0000 From: Richard Dawe X-Mailer: Mozilla 4.77 [en] (X11; U; Linux 2.2.19 i586) X-Accept-Language: de,fr MIME-Version: 1.0 To: DJGPP workers Subject: RESEND: Patch to computer st_blksize in struct stat Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp-workers AT delorie DOT com Hello. Below is a patch to compute st_blksize in struct stat. This is basically the st_blocks patch with the st_blocks stuff removed. OK to commit? Bye, Rich =] -- Richard Dawe http://www.phekda.freeserve.co.uk/richdawe/ Index: include/sys/types.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/sys/types.h,v retrieving revision 1.6 diff -p -c -3 -r1.6 types.h *** include/sys/types.h 2000/12/05 14:05:53 1.6 --- include/sys/types.h 2001/11/10 09:25:14 *************** extern "C" { *** 13,19 **** #ifndef __STRICT_ANSI__ #include ! typedef int dev_t; typedef int ino_t; typedef int mode_t; --- 13,21 ---- #ifndef __STRICT_ANSI__ #include ! ! typedef int blkcnt_t; ! typedef int blksize_t; typedef int dev_t; typedef int ino_t; typedef int mode_t; Index: include/sys/stat.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/sys/stat.h,v retrieving revision 1.4 diff -p -c -3 -r1.4 stat.h *** include/sys/stat.h 2000/12/05 14:05:53 1.4 --- include/sys/stat.h 2001/11/10 09:25:17 *************** struct stat { *** 49,55 **** time_t st_mtime; nlink_t st_nlink; off_t st_size; ! off_t st_blksize; uid_t st_uid; dev_t st_rdev; /* unused */ }; --- 49,55 ---- time_t st_mtime; nlink_t st_nlink; off_t st_size; ! blksize_t st_blksize; uid_t st_uid; dev_t st_rdev; /* unused */ }; Index: include/libc/fd_props.h =================================================================== RCS file: /cvs/djgpp/djgpp/include/libc/fd_props.h,v retrieving revision 1.6 diff -p -c -3 -r1.6 fd_props.h *** include/libc/fd_props.h 2001/06/06 21:09:50 1.6 --- include/libc/fd_props.h 2001/11/10 09:25:22 *************** extern "C" { *** 8,13 **** --- 8,15 ---- #ifndef __dj_ENFORCE_ANSI_FREESTANDING + #include + #ifndef __STRICT_ANSI__ #ifndef _POSIX_SOURCE *************** static __inline__ void __clear_fd_flags( *** 63,68 **** --- 65,75 ---- static __inline__ unsigned long __get_fd_flags(int _fd) { return __has_fd_properties(_fd) ? __fd_properties[_fd]->flags : 0; + } + + static __inline__ const char * __get_fd_name(int _fd) + { + return __has_fd_properties(_fd) ? __fd_properties[_fd]->filename : NULL; } #endif /* !_POSIX_SOURCE */ Index: src/libc/posix/sys/stat/fstat.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/fstat.c,v retrieving revision 1.7 diff -p -c -3 -r1.7 fstat.c *** src/libc/posix/sys/stat/fstat.c 2001/09/25 01:00:52 1.7 --- src/libc/posix/sys/stat/fstat.c 2001/11/10 09:25:31 *************** *** 106,111 **** --- 106,112 ---- #include #include #include + #include #include #include *************** fstat_assist(int fhandle, struct stat *s *** 434,440 **** stat_buf->st_gid = getgid(); stat_buf->st_nlink = 1; #ifndef NO_ST_BLKSIZE ! stat_buf->st_blksize = _go32_info_block.size_of_transfer_buffer; #endif /* If SFT entry for our handle is required and available, we will use it. */ --- 435,451 ---- stat_buf->st_gid = getgid(); stat_buf->st_nlink = 1; #ifndef NO_ST_BLKSIZE ! if (__get_fd_name(fhandle)) ! { ! const char *filename = __get_fd_name(fhandle); ! stat_buf->st_blksize = _get_cached_blksize(filename); ! } ! else ! { ! /* Fall back on transfer buffer size, if we can't determine file name ! * (which gives the drive letter and then the drive's cluster size). */ ! stat_buf->st_blksize = _go32_info_block.size_of_transfer_buffer; ! } #endif /* If SFT entry for our handle is required and available, we will use it. */ *************** int main(int argc, char *argv[]) *** 936,941 **** --- 947,955 ---- _djstat_describe_lossage(stderr); } + if (!argc) + return EXIT_SUCCESS; + /* Now call fstat() for each command-line argument. */ while (++argv, --argc) { *************** int main(int argc, char *argv[]) *** 956,961 **** --- 970,977 ---- fprintf (stderr, "\t\t\tTimes: %lu %lu\n", (unsigned long)stat_buf.st_atime, (unsigned long)stat_buf.st_ctime); + fprintf(stderr, "\t\t\tBlock size: %d\n", + stat_buf.st_blksize); _djstat_describe_lossage(stderr); } else *************** int main(int argc, char *argv[]) *** 965,971 **** _djstat_describe_lossage(stderr); } } ! return 0; } #endif /* TEST */ --- 981,987 ---- _djstat_describe_lossage(stderr); } } ! return EXIT_SUCCESS; } #endif /* TEST */ Index: src/libc/posix/sys/stat/lstat.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/lstat.c,v retrieving revision 1.7 diff -p -c -3 -r1.7 lstat.c *** src/libc/posix/sys/stat/lstat.c 2001/10/17 05:08:39 1.7 --- src/libc/posix/sys/stat/lstat.c 2001/11/10 09:25:42 *************** stat_assist(const char *path, struct sta *** 445,451 **** statbuf->st_gid = getgid(); statbuf->st_nlink = 1; #ifndef NO_ST_BLKSIZE ! statbuf->st_blksize = _go32_info_block.size_of_transfer_buffer; #endif /* Make the path explicit. This makes the rest of our job much --- 445,451 ---- statbuf->st_gid = getgid(); statbuf->st_nlink = 1; #ifndef NO_ST_BLKSIZE ! statbuf->st_blksize = _get_cached_blksize(path); #endif /* Make the path explicit. This makes the rest of our job much *************** lstat(const char *path, struct stat *sta *** 932,940 **** #ifdef TEST unsigned short _djstat_flags = 0; ! void main(int argc, char *argv[]) { struct stat stat_buf; --- 932,942 ---- #ifdef TEST + #include + unsigned short _djstat_flags = 0; ! int main(int argc, char *argv[]) { struct stat stat_buf; *************** main(int argc, char *argv[]) *** 943,949 **** if (argc < 2) { fprintf (stderr, "Usage: %s <_djstat_flags> \n", argv[0]); ! exit(0); } if (lstat(*argv, &stat_buf) != 0) --- 945,951 ---- if (argc < 2) { fprintf (stderr, "Usage: %s <_djstat_flags> \n", argv[0]); ! return (EXIT_FAILURE); } if (lstat(*argv, &stat_buf) != 0) *************** main(int argc, char *argv[]) *** 968,973 **** --- 970,977 ---- (long)stat_buf.st_size, (unsigned long)stat_buf.st_mtime, ctime(&stat_buf.st_mtime)); + fprintf(stderr, "\t\t\tBlock size: %d\n", + stat_buf.st_blksize); _djstat_describe_lossage(stderr); } else *************** main(int argc, char *argv[]) *** 980,986 **** ++argv; } ! exit (0); } #endif --- 984,990 ---- ++argv; } ! return (EXIT_SUCCESS); } #endif Index: src/libc/posix/sys/stat/xstat.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/xstat.c,v retrieving revision 1.3 diff -p -c -3 -r1.3 xstat.c *** src/libc/posix/sys/stat/xstat.c 2000/08/05 16:53:46 1.3 --- src/libc/posix/sys/stat/xstat.c 2001/11/10 09:25:52 *************** *** 19,24 **** --- 19,26 ---- #include #include #include + #include + #include #include #include #include *************** _getftime(int fhandle, unsigned int *dos *** 116,121 **** --- 118,175 ---- *dos_ftime = ((unsigned int)regs.x.dx << 16) + (unsigned int)regs.x.cx; return 0; + } + + /* Cache the cluster size (aka block size) for each drive letter, so we can + * populate the st_blksize of struct stat easily. The cluster size is + * measured in bytes. + */ + + /* Comment copied from DJGPP 2.03's src/libc/compat/mntent/mntent.c: + * + * There may be a maximum of 32 block devices. Novell Netware indeed + * allows for 32 disks (A-Z plus 6 more characters from '[' to '\'') + */ + static blksize_t cache_blksize[32]; + static int cache_blksize_count = -1; + + blksize_t + _get_cached_blksize (const char *path) + { + char fixed_path[PATH_MAX + 1]; + struct statfs sbuf; + int d; /* drive */ + static int overmax_d = sizeof(cache_blksize) / sizeof(cache_blksize[0]); + + /* Force initialization in restarted programs (emacs). */ + if (cache_blksize_count != __bss_count) + { + cache_blksize_count = __bss_count; + memset(cache_blksize, 0, sizeof(cache_blksize)); + } + + _fixpath(path, fixed_path); + d = tolower(path[0]) - 'a'; + + if ((d < 0) || (d >= overmax_d)) + { + errno = ENODEV; + return -1; + } + + if (!cache_blksize[d]) + { + /* No entry => retrieve cluster size */ + if (statfs(path, &sbuf) != 0) + { + /* Failed, pass error through */ + return -1; + } + + cache_blksize[d] = sbuf.f_bsize; + } + + return cache_blksize[d]; } /* Invent an inode number for those files which don't have valid DOS Index: src/libc/posix/sys/stat/stat.c =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/stat.c,v retrieving revision 1.10 diff -p -c -3 -r1.10 stat.c *** src/libc/posix/sys/stat/stat.c 2000/08/22 18:45:07 1.10 --- src/libc/posix/sys/stat/stat.c 2001/11/10 09:25:57 *************** stat(const char *path, struct stat *stat *** 31,39 **** #ifdef TEST unsigned short _djstat_flags = 0; ! void main(int argc, char *argv[]) { struct stat stat_buf; --- 31,41 ---- #ifdef TEST + #include + unsigned short _djstat_flags = 0; ! int main(int argc, char *argv[]) { struct stat stat_buf; *************** main(int argc, char *argv[]) *** 42,48 **** if (argc < 2) { fprintf (stderr, "Usage: %s <_djstat_flags> \n", argv[0]); ! exit(0); } if (stat(*argv, &stat_buf) != 0) --- 44,50 ---- if (argc < 2) { fprintf (stderr, "Usage: %s <_djstat_flags> \n", argv[0]); ! return (EXIT_FAILURE); } if (stat(*argv, &stat_buf) != 0) *************** main(int argc, char *argv[]) *** 67,72 **** --- 69,76 ---- (long)stat_buf.st_size, (unsigned long)stat_buf.st_mtime, ctime(&stat_buf.st_mtime)); + fprintf(stderr, "\t\t\tBlock size: %d\n", + stat_buf.st_blksize); _djstat_describe_lossage(stderr); } else *************** main(int argc, char *argv[]) *** 79,85 **** ++argv; } ! exit (0); } #endif --- 83,89 ---- ++argv; } ! return (EXIT_SUCCESS); } #endif Index: src/libc/posix/sys/stat/xstat.h =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/xstat.h,v retrieving revision 1.4 diff -p -c -3 -r1.4 xstat.h *** src/libc/posix/sys/stat/xstat.h 2000/08/05 16:53:46 1.4 --- src/libc/posix/sys/stat/xstat.h 2001/11/10 09:26:02 *************** extern long __filelength(int *** 68,72 **** --- 68,73 ---- extern int _is_remote_handle(int); extern void _djstat_describe_lossage(FILE *); extern int _getftime(int, unsigned int *); + extern blksize_t _get_cached_blksize (const char *path); #endif /* __XSTAT_H */ Index: src/libc/posix/sys/stat/lstat.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/lstat.txh,v retrieving revision 1.3 diff -p -c -3 -r1.3 lstat.txh *** src/libc/posix/sys/stat/lstat.txh 2001/08/01 10:31:02 1.3 --- src/libc/posix/sys/stat/lstat.txh 2001/11/10 09:26:13 *************** it in @var{sbuf}, which has this structu *** 14,30 **** @smallexample struct stat @{ ! time_t st_atime; /* time of last access */ ! time_t st_ctime; /* time of file's creation */ ! dev_t st_dev; /* The drive number (0 = a:) */ ! gid_t st_gid; /* what getgid() returns */ ! ino_t st_ino; /* starting cluster or unique identifier */ ! mode_t st_mode; /* file mode - S_IF* and S_IRUSR/S_IWUSR */ ! time_t st_mtime; /* time that the file was last written */ ! nlink_t st_nlink; /* 2 + number of subdirs, or 1 for files */ ! off_t st_size; /* size of file in bytes */ ! off_t st_blksize; /* the size of transfer buffer */ ! uid_t st_uid; /* what getuid() returns */ @}; @end smallexample --- 14,30 ---- @smallexample struct stat @{ ! time_t st_atime; /* time of last access */ ! time_t st_ctime; /* time of file's creation */ ! dev_t st_dev; /* The drive number (0 = a:) */ ! gid_t st_gid; /* what getgid() returns */ ! ino_t st_ino; /* starting cluster or unique identifier */ ! mode_t st_mode; /* file mode - S_IF* and S_IRUSR/S_IWUSR */ ! time_t st_mtime; /* time that the file was last written */ ! nlink_t st_nlink; /* 2 + number of subdirs, or 1 for files */ ! off_t st_size; /* size of file in bytes */ ! blksize_t st_blksize; /* block size in bytes*/ ! uid_t st_uid; /* what getuid() returns */ @}; @end smallexample Index: src/libc/posix/sys/stat/stat.txh =================================================================== RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/stat.txh,v retrieving revision 1.8 diff -p -c -3 -r1.8 stat.txh *** src/libc/posix/sys/stat/stat.txh 2001/08/01 10:31:02 1.8 --- src/libc/posix/sys/stat/stat.txh 2001/11/10 09:26:19 *************** it in @var{sbuf}, which has this structu *** 14,30 **** @smallexample struct stat @{ ! time_t st_atime; /* time of last access */ ! time_t st_ctime; /* time of file's creation */ ! dev_t st_dev; /* The drive number (0 = a:) */ ! gid_t st_gid; /* what getgid() returns */ ! ino_t st_ino; /* starting cluster or unique identifier */ ! mode_t st_mode; /* file mode - S_IF* and S_IRUSR/S_IWUSR */ ! time_t st_mtime; /* time that the file was last written */ ! nlink_t st_nlink; /* 2 + number of subdirs, or 1 for files */ ! off_t st_size; /* size of file in bytes */ ! off_t st_blksize; /* the size of transfer buffer */ ! uid_t st_uid; /* what getuid() returns */ @}; @end smallexample --- 14,30 ---- @smallexample struct stat @{ ! time_t st_atime; /* time of last access */ ! time_t st_ctime; /* time of file's creation */ ! dev_t st_dev; /* The drive number (0 = a:) */ ! gid_t st_gid; /* what getgid() returns */ ! ino_t st_ino; /* starting cluster or unique identifier */ ! mode_t st_mode; /* file mode - S_IF* and S_IRUSR/S_IWUSR */ ! time_t st_mtime; /* time that the file was last written */ ! nlink_t st_nlink; /* 2 + number of subdirs, or 1 for files */ ! off_t st_size; /* size of file in bytes */ ! blksize_t st_blksize; /* block size in bytes*/ ! uid_t st_uid; /* what getuid() returns */ @}; @end smallexample Index: src/docs/kb/wc204.txi =================================================================== RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v retrieving revision 1.100 diff -p -c -3 -r1.100 wc204.txi *** src/docs/kb/wc204.txi 2001/10/17 05:19:49 1.100 --- src/docs/kb/wc204.txi 2001/11/10 09:26:31 *************** case lowering. This replaces the functi *** 675,677 **** --- 675,684 ---- which is hopelessly buggy on Windows 2000 and XP. New function used in @file{srchpath.c}, @file{readdir.c}, @file{glob.c}, @file{fixpath.c}, @file{lstat.c} and @file{getcwd.c}. + + @findex stat AT r{, and block size} + @findex lstat AT r{, and block size} + @findex fstat AT r{, and block size} + The functions @code{stat}, @code{lstat} and @code{fstat} now fill + the @code{st_blksize} member of @code{struct stat} with the correct block + size for the device where the file is located.