diff options
Diffstat (limited to 'lib/fsusage.c')
-rw-r--r-- | lib/fsusage.c | 57 |
1 files changed, 34 insertions, 23 deletions
diff --git a/lib/fsusage.c b/lib/fsusage.c index 7339c80..d926029 100644 --- a/lib/fsusage.c +++ b/lib/fsusage.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* fsusage.c -- return space usage of mounted filesystems | 1 | /* fsusage.c -- return space usage of mounted filesystems |
2 | Copyright (C) 1991, 1992, 1996, 1998, 1999 Free Software Foundation, Inc. | 2 | |
3 | Copyright (C) 1991, 1992, 1996, 1998, 1999, 2002, 2003 Free | ||
4 | Software Foundation, Inc. | ||
3 | 5 | ||
4 | This program is free software; you can redistribute it and/or modify | 6 | 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 | 7 | it under the terms of the GNU General Public License as published by |
@@ -15,23 +17,26 @@ | |||
15 | along with this program; if not, write to the Free Software Foundation, | 17 | along with this program; if not, write to the Free Software Foundation, |
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | 18 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
17 | 19 | ||
18 | #include "config.h" | 20 | #if HAVE_CONFIG_H |
21 | # include <config.h> | ||
22 | #endif | ||
19 | 23 | ||
20 | #if HAVE_INTTYPES_H | 24 | #if HAVE_INTTYPES_H |
21 | # include <inttypes.h> | 25 | # include <inttypes.h> |
26 | #else | ||
27 | # if HAVE_STDINT_H | ||
28 | # include <stdint.h> | ||
29 | # endif | ||
22 | #endif | 30 | #endif |
31 | #ifndef UINTMAX_MAX | ||
32 | # define UINTMAX_MAX ((uintmax_t) -1) | ||
33 | #endif | ||
34 | |||
23 | #include <sys/types.h> | 35 | #include <sys/types.h> |
24 | #include <sys/stat.h> | 36 | #include <sys/stat.h> |
25 | #include "fsusage.h" | 37 | #include "fsusage.h" |
26 | 38 | ||
27 | #if HAVE_LIMITS_H | 39 | #include <limits.h> |
28 | # include <limits.h> | ||
29 | #endif | ||
30 | #ifndef CHAR_BIT | ||
31 | # define CHAR_BIT 8 | ||
32 | #endif | ||
33 | |||
34 | int statfs (); | ||
35 | 40 | ||
36 | #if HAVE_SYS_PARAM_H | 41 | #if HAVE_SYS_PARAM_H |
37 | # include <sys/param.h> | 42 | # include <sys/param.h> |
@@ -49,7 +54,7 @@ int statfs (); | |||
49 | # include <sys/fs/s5param.h> | 54 | # include <sys/fs/s5param.h> |
50 | #endif | 55 | #endif |
51 | 56 | ||
52 | #if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY) | 57 | #if defined HAVE_SYS_FILSYS_H && !defined _CRAY |
53 | # include <sys/filsys.h> /* SVR2 */ | 58 | # include <sys/filsys.h> /* SVR2 */ |
54 | #endif | 59 | #endif |
55 | 60 | ||
@@ -70,11 +75,18 @@ int statfs (); | |||
70 | int statvfs (); | 75 | int statvfs (); |
71 | #endif | 76 | #endif |
72 | 77 | ||
78 | #include "full-read.h" | ||
79 | |||
73 | /* Many space usage primitives use all 1 bits to denote a value that is | 80 | /* Many space usage primitives use all 1 bits to denote a value that is |
74 | not applicable or unknown. Propagate this information by returning | 81 | not applicable or unknown. Propagate this information by returning |
75 | a uintmax_t value that is all 1 bits if the argument is all 1 bits, | 82 | a uintmax_t value that is all 1 bits if X is all 1 bits, even if X |
76 | even if the argument is unsigned and smaller than uintmax_t. */ | 83 | is unsigned and narrower than uintmax_t. */ |
77 | #define PROPAGATE_ALL_ONES(x) ((x) == -1 ? (uintmax_t) -1 : (uintmax_t) (x)) | 84 | #define PROPAGATE_ALL_ONES(x) \ |
85 | ((sizeof (x) < sizeof (uintmax_t) \ | ||
86 | && (~ (x) == (sizeof (x) < sizeof (int) \ | ||
87 | ? - (1 << (sizeof (x) * CHAR_BIT)) \ | ||
88 | : 0))) \ | ||
89 | ? UINTMAX_MAX : (x)) | ||
78 | 90 | ||
79 | /* Extract the top bit of X as an uintmax_t value. */ | 91 | /* Extract the top bit of X as an uintmax_t value. */ |
80 | #define EXTRACT_TOP_BIT(x) ((x) \ | 92 | #define EXTRACT_TOP_BIT(x) ((x) \ |
@@ -89,8 +101,6 @@ int statvfs (); | |||
89 | otherwise, use PROPAGATE_ALL_ONES. */ | 101 | otherwise, use PROPAGATE_ALL_ONES. */ |
90 | #define PROPAGATE_TOP_BIT(x) ((x) | ~ (EXTRACT_TOP_BIT (x) - 1)) | 102 | #define PROPAGATE_TOP_BIT(x) ((x) | ~ (EXTRACT_TOP_BIT (x) - 1)) |
91 | 103 | ||
92 | int safe_read (); | ||
93 | |||
94 | /* Fill in the fields of FSP with information about space usage for | 104 | /* Fill in the fields of FSP with information about space usage for |
95 | the filesystem on which PATH resides. | 105 | the filesystem on which PATH resides. |
96 | DISK is the device on which PATH is mounted, for space-getting | 106 | DISK is the device on which PATH is mounted, for space-getting |
@@ -147,7 +157,7 @@ get_fs_usage (const char *path, const char *disk, struct fs_usage *fsp) | |||
147 | if (fd < 0) | 157 | if (fd < 0) |
148 | return -1; | 158 | return -1; |
149 | lseek (fd, (off_t) SUPERBOFF, 0); | 159 | lseek (fd, (off_t) SUPERBOFF, 0); |
150 | if (safe_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd) | 160 | if (full_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd) |
151 | { | 161 | { |
152 | close (fd); | 162 | close (fd); |
153 | return -1; | 163 | return -1; |
@@ -160,7 +170,7 @@ get_fs_usage (const char *path, const char *disk, struct fs_usage *fsp) | |||
160 | fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.s_tfree); | 170 | fsp->fsu_bavail = PROPAGATE_TOP_BIT (fsd.s_tfree); |
161 | fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.s_tfree) != 0; | 171 | fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (fsd.s_tfree) != 0; |
162 | fsp->fsu_files = (fsd.s_isize == -1 | 172 | fsp->fsu_files = (fsd.s_isize == -1 |
163 | ? (uintmax_t) -1 | 173 | ? UINTMAX_MAX |
164 | : (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1)); | 174 | : (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1)); |
165 | fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.s_tinode); | 175 | fsp->fsu_ffree = PROPAGATE_ALL_ONES (fsd.s_tinode); |
166 | 176 | ||
@@ -217,7 +227,7 @@ get_fs_usage (const char *path, const char *disk, struct fs_usage *fsp) | |||
217 | /* Empirically, the block counts on most SVR3 and SVR3-derived | 227 | /* Empirically, the block counts on most SVR3 and SVR3-derived |
218 | systems seem to always be in terms of 512-byte blocks, | 228 | systems seem to always be in terms of 512-byte blocks, |
219 | no matter what value f_bsize has. */ | 229 | no matter what value f_bsize has. */ |
220 | # if _AIX || defined(_CRAY) | 230 | # if _AIX || defined _CRAY |
221 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize); | 231 | fsp->fsu_blocksize = PROPAGATE_ALL_ONES (fsd.f_bsize); |
222 | # else | 232 | # else |
223 | fsp->fsu_blocksize = 512; | 233 | fsp->fsu_blocksize = 512; |
@@ -233,12 +243,13 @@ get_fs_usage (const char *path, const char *disk, struct fs_usage *fsp) | |||
233 | return -1; | 243 | return -1; |
234 | 244 | ||
235 | /* f_frsize isn't guaranteed to be supported. */ | 245 | /* f_frsize isn't guaranteed to be supported. */ |
236 | fsp->fsu_blocksize = | 246 | fsp->fsu_blocksize = (fsd.f_frsize |
237 | PROPAGATE_ALL_ONES (fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize); | 247 | ? PROPAGATE_ALL_ONES (fsd.f_frsize) |
248 | : PROPAGATE_ALL_ONES (fsd.f_bsize)); | ||
238 | 249 | ||
239 | #endif /* STAT_STATVFS */ | 250 | #endif /* STAT_STATVFS */ |
240 | 251 | ||
241 | #if !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ_FILSYS) | 252 | #if !defined STAT_STATFS2_FS_DATA && !defined STAT_READ_FILSYS |
242 | /* !Ultrix && !SVR2 */ | 253 | /* !Ultrix && !SVR2 */ |
243 | 254 | ||
244 | fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks); | 255 | fsp->fsu_blocks = PROPAGATE_ALL_ONES (fsd.f_blocks); |
@@ -253,7 +264,7 @@ get_fs_usage (const char *path, const char *disk, struct fs_usage *fsp) | |||
253 | return 0; | 264 | return 0; |
254 | } | 265 | } |
255 | 266 | ||
256 | #if defined(_AIX) && defined(_I386) | 267 | #if defined _AIX && defined _I386 |
257 | /* AIX PS/2 does not supply statfs. */ | 268 | /* AIX PS/2 does not supply statfs. */ |
258 | 269 | ||
259 | int | 270 | int |