From: James Youngman Date: Sat, 11 Jun 2011 00:15:39 +0000 (+0100) Subject: New module 'stat-size'. X-Git-Tag: v0.1~2624 X-Git-Url: http://erislabs.org.uk/gitweb/?a=commitdiff_plain;h=9fc77bc59374e21e1174742df416af186a368e14;p=gnulib.git New module 'stat-size'. * modules/stat-size: New module. Provides macros for accessing file size information in instances of struct stat. Depends on the fileblocks module because it calls st_blocks. * lib/stat-size.h: New file, adapted from coreutils' system.h. * doc/gnulib.texi: Include stat-size.texi. * doc/stat-size.texi: Documentation for this module. * m4/stat-size.m4: New file; defines gl_STAT_SIZE. * m4/fileblocks.m4: Mention that stat-size depends on the call to AC_STRUCT_ST_BLOCKS. --- diff --git a/ChangeLog b/ChangeLog index 69e4e0364..6df3b4d13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2011-06-11 James Youngman + + New module 'stat-size'. + * modules/stat-size: New module. Provides macros for accessing + file size information in instances of struct stat. Depends on the + fileblocks module because it calls st_blocks. + * lib/stat-size.h: New file, adapted from coreutils' system.h. + * doc/gnulib.texi: Include stat-size.texi. + * doc/stat-size.texi: Documentation for this module. + * m4/stat-size.m4: New file; defines gl_STAT_SIZE. + * m4/fileblocks.m4: Mention that stat-size depends on the call to + AC_STRUCT_ST_BLOCKS. + 2011-06-09 Bruno Haible thread: Support pthreads-win32. diff --git a/doc/gnulib.texi b/doc/gnulib.texi index 1e1ad40fa..e126c6f44 100644 --- a/doc/gnulib.texi +++ b/doc/gnulib.texi @@ -6512,6 +6512,7 @@ This list of functions is sorted according to the header that declares them. * warnings:: * manywarnings:: * Running self-tests under valgrind:: +* stat-size:: @end menu @node alloca @@ -6608,6 +6609,9 @@ ASCII characters. @include valgrind-tests.texi +@include stat-size.texi + + @node Regular expressions @chapter Regular expressions diff --git a/doc/stat-size.texi b/doc/stat-size.texi new file mode 100644 index 000000000..17b5be97f --- /dev/null +++ b/doc/stat-size.texi @@ -0,0 +1,25 @@ +@node stat-size +@section stat-size + +The @code{stat-size} module provides a small number of macros +intended for interpreting the file size information in an instance of +@code{struct stat}. + +@c We deliberately don't document DEV_BSIZE (it looks to James +@c Youngman as if the ST_NBLOCKSIZE macro should be used instead). + +@findex ST_NBLOCKS +@findex ST_NBLOCKSIZE +@cindex block size +On POSIX systems, the @code{st_blocks} member of @code{struct stat} +contains the number of disk blocks occupied by a file. The +@code{ST_NBLOCKS} macro is used to estimate this quantity on systems +which don't actually have @code{st_blocks}. Each of these blocks +contains @code{ST_NBLOCKSIZE} bytes. + +@findex ST_BLKSIZE +The value of @code{ST_NBLOCKSIZE} is often quite small, small enough +that performing I/O in chunks that size would be inefficient. +@code{ST_BLKSIZE} is the I/O block size recommended for I/O to this +file. This is not guaranteed to give optimum performance, but it +should be reasonably efficient. diff --git a/lib/stat-size.h b/lib/stat-size.h new file mode 100644 index 000000000..1e4750059 --- /dev/null +++ b/lib/stat-size.h @@ -0,0 +1,111 @@ +/* macros useful in interpreting size-related values in struct stat. + Copyright (C) 1989, 1991-2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ +/* + Macros defined by this file (s is an rvalue of type struct stat): + + DEV_BSIZE: The device blocksize. But use ST_NBLOCKSIZE instead. + ST_BLKSIZE(s): Preferred (in the sense of best performance) I/O blocksize + for the file, in bytes. + ST_NBLOCKS(s): Number of blocks in the file, including indirect blocks. + ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. + */ +#ifndef STAT_SIZE_H +#define STAT_SIZE_H + +/* sys/param.h may define DEV_BSIZE */ +#if HAVE_SYS_PARAM_H +# include +#endif + + +/* Much of the remainder of this file is not indented consistently + with the above, in order to make it easier to see that the text + is almost identical to part of the system.h header in coreutils. +*/ +/* Get or fake the disk device blocksize. + Usually defined by sys/param.h (if at all). */ +#if !defined DEV_BSIZE && defined BSIZE +# define DEV_BSIZE BSIZE +#endif +#if !defined DEV_BSIZE && defined BBSIZE /* SGI sys/param.h */ +# define DEV_BSIZE BBSIZE +#endif +#ifndef DEV_BSIZE +# define DEV_BSIZE 4096 +#endif + + + +/* Extract or fake data from a `struct stat'. + ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes. + ST_NBLOCKS: Number of blocks in the file, including indirect blocks. + ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */ +#ifndef HAVE_STRUCT_STAT_ST_BLOCKS +# define ST_BLKSIZE(statbuf) DEV_BSIZE + /* coreutils' fileblocks.c also uses BSIZE. */ +# if defined _POSIX_SOURCE || !defined BSIZE +# define ST_NBLOCKS(statbuf) \ + ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0)) +# else + /* This definition calls st_blocks, which is in the fileblocks module. */ +# define ST_NBLOCKS(statbuf) \ + (S_ISREG ((statbuf).st_mode) || S_ISDIR ((statbuf).st_mode) ? \ + st_blocks ((statbuf).st_size) : 0) +# endif +#else +/* Some systems, like Sequents, return st_blksize of 0 on pipes. + Also, when running `rsh hpux11-system cat any-file', cat would + determine that the output stream had an st_blksize of 2147421096. + Conversely st_blksize can be 2 GiB (or maybe even larger) with XFS + on 64-bit hosts. Somewhat arbitrarily, limit the `optimal' block + size to SIZE_MAX / 8 + 1. (Dividing SIZE_MAX by only 4 wouldn't + suffice, since "cat" sometimes multiplies the result by 4.) If + anyone knows of a system for which this limit is too small, please + report it as a bug in this code. */ +# define ST_BLKSIZE(statbuf) ((0 < (statbuf).st_blksize \ + && (statbuf).st_blksize <= ((size_t)-1) / 8 + 1) \ + ? (statbuf).st_blksize : DEV_BSIZE) +# if defined hpux || defined __hpux__ || defined __hpux + /* HP-UX counts st_blocks in 1024-byte units. + This loses when mixing HP-UX and BSD file systems with NFS. */ +# define ST_NBLOCKSIZE 1024 +# else /* !hpux */ +# if defined _AIX && defined _I386 + /* AIX PS/2 counts st_blocks in 4K units. */ +# define ST_NBLOCKSIZE (4 * 1024) +# else +# if defined _CRAY +# define ST_NBLOCKS(statbuf) \ + (S_ISREG ((statbuf).st_mode) || S_ISDIR ((statbuf).st_mode) \ + ? (statbuf).st_blocks * ST_BLKSIZE (statbuf) / ST_NBLOCKSIZE : 0) +# endif +# endif +# endif +#endif + +#ifndef ST_NBLOCKS +# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks) +#endif + +#ifndef ST_NBLOCKSIZE +# ifdef S_BLKSIZE +# define ST_NBLOCKSIZE S_BLKSIZE +# else +# define ST_NBLOCKSIZE 512 +# endif +#endif + +#endif /* STAT_SIZE_H */ diff --git a/m4/fileblocks.m4 b/m4/fileblocks.m4 index c8f99621b..8700edaef 100644 --- a/m4/fileblocks.m4 +++ b/m4/fileblocks.m4 @@ -8,6 +8,10 @@ AC_DEFUN([gl_FILEBLOCKS], [ AC_STRUCT_ST_BLOCKS dnl Note: AC_STRUCT_ST_BLOCKS does AC_LIBOBJ([fileblocks]). + dnl The stat-size module depends on this one and also assumes that + dnl HAVE_STRUCT_STAT_ST_BLOCKS is correctly defined. So if you + dnl remove the call above, please make sure that this does not + dnl introduce a bug into lib/stat-size.h. if test $ac_cv_member_struct_stat_st_blocks = no; then gl_PREREQ_FILEBLOCKS fi diff --git a/m4/stat-size.m4 b/m4/stat-size.m4 new file mode 100644 index 000000000..fa4e6b9e9 --- /dev/null +++ b/m4/stat-size.m4 @@ -0,0 +1,14 @@ +#serial 1 + +# Copyright (C) 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_STAT_SIZE], +[ + # Don't call AC_STRUCT_ST_BLOCKS because it causes bugs. Details at + # http://lists.gnu.org/archive/html/bug-gnulib/2011-06/msg00051.html + AC_CHECK_HEADERS_ONCE([sys/param.h]) +]) diff --git a/modules/stat-size b/modules/stat-size new file mode 100644 index 000000000..77279707c --- /dev/null +++ b/modules/stat-size @@ -0,0 +1,24 @@ +Description: +stat-related file size macros + +Files: +lib/stat-size.h +m4/stat-size.m4 + +Depends-on: +fileblocks +sys_stat + +configure.ac: +gl_STAT_SIZE + +Makefile.am: + +Include: +"stat-size.h" + +License: +GPL + +Maintainer: +James Youngman, Jim Meyering