maint: update all copyright year number ranges
[gnulib.git] / lib / stat-size.h
1 /* macros useful in interpreting size-related values in struct stat.
2    Copyright (C) 1989, 1991-2012 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16 /*
17    Macros defined by this file (s is an rvalue of type struct stat):
18
19    DEV_BSIZE:       The device blocksize.  But use ST_NBLOCKSIZE instead.
20    ST_BLKSIZE(s):   Preferred (in the sense of best performance) I/O blocksize
21                     for the file, in bytes.
22    ST_NBLOCKS(s):   Number of blocks in the file, including indirect blocks.
23    ST_NBLOCKSIZE:   Size of blocks used when calculating ST_NBLOCKS.
24  */
25 #ifndef STAT_SIZE_H
26 #define STAT_SIZE_H
27
28 /* sys/param.h may define DEV_BSIZE */
29 #if HAVE_SYS_PARAM_H
30 # include <sys/param.h>
31 #endif
32
33
34 /* Much of the remainder of this file is not indented consistently
35    with the above, in order to make it easier to see that the text
36    is almost identical to part of the system.h header in coreutils.
37 */
38 /* Get or fake the disk device blocksize.
39    Usually defined by sys/param.h (if at all).  */
40 #if !defined DEV_BSIZE && defined BSIZE
41 # define DEV_BSIZE BSIZE
42 #endif
43 #if !defined DEV_BSIZE && defined BBSIZE /* SGI sys/param.h */
44 # define DEV_BSIZE BBSIZE
45 #endif
46 #ifndef DEV_BSIZE
47 # define DEV_BSIZE 4096
48 #endif
49
50
51
52 /* Extract or fake data from a `struct stat'.
53    ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
54    ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
55    ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS.  */
56 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
57 # define ST_BLKSIZE(statbuf) DEV_BSIZE
58   /* coreutils' fileblocks.c also uses BSIZE.  */
59 # if defined _POSIX_SOURCE || !defined BSIZE
60 #  define ST_NBLOCKS(statbuf) \
61   ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0))
62 # else
63    /* This definition calls st_blocks, which is in the fileblocks module. */
64 #  define ST_NBLOCKS(statbuf) \
65   (S_ISREG ((statbuf).st_mode) || S_ISDIR ((statbuf).st_mode) ? \
66    st_blocks ((statbuf).st_size) : 0)
67 # endif
68 #else
69 /* Some systems, like Sequents, return st_blksize of 0 on pipes.
70    Also, when running `rsh hpux11-system cat any-file', cat would
71    determine that the output stream had an st_blksize of 2147421096.
72    Conversely st_blksize can be 2 GiB (or maybe even larger) with XFS
73    on 64-bit hosts.  Somewhat arbitrarily, limit the `optimal' block
74    size to SIZE_MAX / 8 + 1.  (Dividing SIZE_MAX by only 4 wouldn't
75    suffice, since "cat" sometimes multiplies the result by 4.)  If
76    anyone knows of a system for which this limit is too small, please
77    report it as a bug in this code.  */
78 # define ST_BLKSIZE(statbuf) ((0 < (statbuf).st_blksize \
79                                && (statbuf).st_blksize <= ((size_t)-1) / 8 + 1) \
80                               ? (statbuf).st_blksize : DEV_BSIZE)
81 # if defined hpux || defined __hpux__ || defined __hpux
82   /* HP-UX counts st_blocks in 1024-byte units.
83      This loses when mixing HP-UX and BSD file systems with NFS.  */
84 #  define ST_NBLOCKSIZE 1024
85 # else /* !hpux */
86 #  if defined _AIX && defined _I386
87     /* AIX PS/2 counts st_blocks in 4K units.  */
88 #   define ST_NBLOCKSIZE (4 * 1024)
89 #  else
90 #   if defined _CRAY
91 #    define ST_NBLOCKS(statbuf) \
92   (S_ISREG ((statbuf).st_mode) || S_ISDIR ((statbuf).st_mode) \
93    ? (statbuf).st_blocks * ST_BLKSIZE (statbuf) / ST_NBLOCKSIZE : 0)
94 #   endif
95 #  endif
96 # endif
97 #endif
98
99 #ifndef ST_NBLOCKS
100 # define ST_NBLOCKS(statbuf) ((statbuf).st_blocks)
101 #endif
102
103 #ifndef ST_NBLOCKSIZE
104 # ifdef S_BLKSIZE
105 #  define ST_NBLOCKSIZE S_BLKSIZE
106 # else
107 #  define ST_NBLOCKSIZE 512
108 # endif
109 #endif
110
111 #endif /* STAT_SIZE_H */