1 /* fsusage.c -- return space usage of mounted filesystems
2 Copyright (C) 1991, 1992, 1996 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 2, or (at your option)
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, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 # include <inttypes.h>
25 #include <sys/types.h>
32 # include <sys/param.h>
36 # include <sys/mount.h>
43 #if HAVE_SYS_FS_S5PARAM_H /* Fujitsu UXP/V */
44 # include <sys/fs/s5param.h>
47 #if defined (HAVE_SYS_FILSYS_H) && !defined (_CRAY)
48 # include <sys/filsys.h> /* SVR2 */
56 # include <sys/statfs.h>
59 #if HAVE_DUSTAT_H /* AIX PS/2 */
60 # include <sys/dustat.h>
63 #if HAVE_SYS_STATVFS_H /* SVR4 */
64 # include <sys/statvfs.h>
70 /* Fill in the fields of FSP with information about space usage for
71 the filesystem on which PATH resides.
72 DISK is the device on which PATH is mounted, for space-getting
73 methods that need to know it.
74 Return 0 if successful, -1 if not. When returning -1, ensure that
75 ERRNO is either a system error value, or zero if DISK is NULL
76 on a system that requires a non-NULL value. */
78 get_fs_usage (path, disk, fsp)
83 #ifdef STAT_STATFS3_OSF1
87 if (statfs (path, &fsd, sizeof (struct statfs)) != 0)
90 fsp->fsu_blocksize = fsd.f_fsize;
92 #endif /* STAT_STATFS3_OSF1 */
94 #ifdef STAT_STATFS2_FS_DATA /* Ultrix */
98 if (statfs (path, &fsd) != 1)
101 fsp->fsu_blocksize = 1024;
102 fsp->fsu_blocks = fsd.fd_req.btot;
103 fsp->fsu_bfree = fsd.fd_req.bfree;
104 fsp->fsu_bavail = fsd.fd_req.bfreen;
105 fsp->fsu_files = fsd.fd_req.gtot;
106 fsp->fsu_ffree = fsd.fd_req.gfree;
108 #endif /* STAT_STATFS2_FS_DATA */
110 #ifdef STAT_READ_FILSYS /* SVR2 */
112 # define SUPERBOFF (SUPERB * 512)
124 fd = open (disk, O_RDONLY);
127 lseek (fd, (off_t) SUPERBOFF, 0);
128 if (safe_read (fd, (char *) &fsd, sizeof fsd) != sizeof fsd)
135 fsp->fsu_blocksize = fsd.s_type == Fs2b ? 1024 : 512;
136 fsp->fsu_blocks = fsd.s_fsize;
137 fsp->fsu_bfree = fsd.s_tfree;
138 fsp->fsu_bavail = fsd.s_tfree;
139 fsp->fsu_files = (fsd.s_isize - 2) * INOPB * (fsd.s_type == Fs2b ? 2 : 1);
140 fsp->fsu_ffree = fsd.s_tinode;
142 #endif /* STAT_READ_FILSYS */
144 #ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX */
148 if (statfs (path, &fsd) < 0)
151 fsp->fsu_blocksize = fsd.f_bsize;
153 # ifdef STATFS_TRUNCATES_BLOCK_COUNTS
155 /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
156 struct statfs are truncated to 2GB. These conditions detect that
157 truncation, presumably without botching the 4.1.1 case, in which
158 the values are not truncated. The correct counts are stored in
159 undocumented spare fields. */
160 if (fsd.f_blocks == 0x1fffff && fsd.f_spare[0] > 0)
162 fsd.f_blocks = fsd.f_spare[0];
163 fsd.f_bfree = fsd.f_spare[1];
164 fsd.f_bavail = fsd.f_spare[2];
166 # endif /* STATFS_TRUNCATES_BLOCK_COUNTS */
168 #endif /* STAT_STATFS2_BSIZE */
170 #ifdef STAT_STATFS2_FSIZE /* 4.4BSD */
174 if (statfs (path, &fsd) < 0)
177 fsp->fsu_blocksize = fsd.f_fsize;
179 #endif /* STAT_STATFS2_FSIZE */
181 #ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX */
183 # if !_AIX && !defined _SEQUENT_ && !defined DOLPHIN
184 # define f_bavail f_bfree
189 if (statfs (path, &fsd, sizeof fsd, 0) < 0)
192 /* Empirically, the block counts on most SVR3 and SVR3-derived
193 systems seem to always be in terms of 512-byte blocks,
194 no matter what value f_bsize has. */
195 # if _AIX || defined(_CRAY)
196 fsp->fsu_blocksize = fsd.f_bsize;
198 fsp->fsu_blocksize = 512;
201 #endif /* STAT_STATFS4 */
203 #ifdef STAT_STATVFS /* SVR4 */
207 if (statvfs (path, &fsd) < 0)
210 /* f_frsize isn't guaranteed to be supported. */
211 fsp->fsu_blocksize = fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize;
213 #endif /* STAT_STATVFS */
215 #if !defined(STAT_STATFS2_FS_DATA) && !defined(STAT_READ_FILSYS)
216 /* !Ultrix && !SVR2 */
218 fsp->fsu_blocks = fsd.f_blocks;
219 fsp->fsu_bfree = fsd.f_bfree;
220 fsp->fsu_bavail = fsd.f_bavail;
221 fsp->fsu_files = fsd.f_files;
222 fsp->fsu_ffree = fsd.f_ffree;
224 #endif /* not STAT_STATFS2_FS_DATA && not STAT_READ_FILSYS */
229 #if defined(_AIX) && defined(_I386)
230 /* AIX PS/2 does not supply statfs. */
240 if (stat (path, &stats))
242 if (dustat (stats.st_dev, 0, &fsd, sizeof (fsd)))
245 fsb->f_bsize = fsd.du_bsize;
246 fsb->f_blocks = fsd.du_fsize - fsd.du_isize;
247 fsb->f_bfree = fsd.du_tfree;
248 fsb->f_bavail = fsd.du_tfree;
249 fsb->f_files = (fsd.du_isize - 2) * fsd.du_inopb;
250 fsb->f_ffree = fsd.du_tinode;
251 fsb->f_fsid.val[0] = fsd.du_site;
252 fsb->f_fsid.val[1] = fsd.du_pckno;
256 #endif /* _AIX && _I386 */