exp2l: Work around a NetBSD 10.0/i386 bug.
[gnulib.git] / lib / stat-size.h
blob8ec324bae8a591ea0b8d5ae91934cabe398c3004
1 /* Yield size-related values in struct stat.
2 Copyright (C) 1989, 1991-2024 Free Software Foundation, Inc.
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.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 #ifndef STAT_SIZE_H
18 #define STAT_SIZE_H
20 /* This file uses HAVE_SYS_PARAM_H, HAVE_STRUCT_STAT_ST_BLOCKS. */
21 #if !_GL_CONFIG_H_INCLUDED
22 #error "Please include config.h first."
23 #endif
25 /* sys/param.h may define DEV_BSIZE */
26 #if HAVE_SYS_PARAM_H
27 # include <sys/param.h>
28 #endif
30 /* The device blocksize, or a faked version thereof.
31 But use ST_NBLOCKSIZE instead.
32 Usually defined by sys/param.h (if at all). */
33 #if !defined DEV_BSIZE && defined BSIZE
34 # define DEV_BSIZE BSIZE
35 #endif
36 #if !defined DEV_BSIZE && defined BBSIZE /* SGI sys/param.h */
37 # define DEV_BSIZE BBSIZE
38 #endif
39 #ifndef DEV_BSIZE
40 # define DEV_BSIZE 4096
41 #endif
43 /* Extract or fake data from a struct stat *st.
44 STP_BLKSIZE(st): Preferred performance I/O blocksize, in bytes.
45 STP_NBLOCKS(st): Number of blocks, including indirect blocks.
46 ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
47 #ifndef HAVE_STRUCT_STAT_ST_BLOCKS
48 # define STP_BLKSIZE(st) DEV_BSIZE
49 /* coreutils' fileblocks.c also uses BSIZE. */
50 # if defined _POSIX_SOURCE || !defined BSIZE
51 # define STP_NBLOCKS(st) \
52 ((st)->st_size / ST_NBLOCKSIZE + ((st)->st_size % ST_NBLOCKSIZE != 0))
53 # else
54 /* This definition calls st_blocks, which is in the fileblocks module. */
55 # define STP_NBLOCKS(st) \
56 (S_ISREG ((st)->st_mode) || S_ISDIR ((st)->st_mode) \
57 ? st_blocks ((st)->st_size) : 0)
58 # endif
59 #else
60 /* When running 'rsh hpux11-system cat any-file', cat would
61 determine that the output stream had an st_blksize of 2147421096.
62 Conversely st_blksize can be 2 GiB (or maybe even larger) with XFS
63 on 64-bit hosts. Somewhat arbitrarily, limit the "optimal" block
64 size to SIZE_MAX / 8 + 1. (Dividing SIZE_MAX by only 4 wouldn't
65 suffice, since "cat" sometimes multiplies the result by 4.) If
66 anyone knows of a system for which this limit is too small, please
67 report it as a bug in this code. */
68 # define STP_BLKSIZE(st) ((0 < (st)->st_blksize \
69 && (st)->st_blksize <= (size_t) -1 / 8 + 1) \
70 ? (st)->st_blksize : DEV_BSIZE)
71 # if defined hpux || defined __hpux__ || defined __hpux
72 /* HP-UX counts st_blocks in 1024-byte units.
73 This loses when mixing HP-UX and BSD file systems with NFS. */
74 # define ST_NBLOCKSIZE 1024
75 # endif
76 #endif
78 #ifndef STP_NBLOCKS
79 # define STP_NBLOCKS(st) ((st)->st_blocks)
80 #endif
82 #ifndef ST_NBLOCKSIZE
83 # ifdef S_BLKSIZE
84 # define ST_NBLOCKSIZE S_BLKSIZE
85 # else
86 # define ST_NBLOCKSIZE 512
87 # endif
88 #endif
90 /* Preferred blocksize and number of blocks for a struct stat object. */
91 #define ST_BLKSIZE(statbuf) STP_BLKSIZE (&(statbuf))
92 #define ST_NBLOCKS(statbuf) STP_NBLOCKS (&(statbuf))
94 #endif /* STAT_SIZE_H */