diff options
Diffstat (limited to 'gnu/libexec/uucp/libunix/fsusg.c')
-rw-r--r-- | gnu/libexec/uucp/libunix/fsusg.c | 128 |
1 files changed, 103 insertions, 25 deletions
diff --git a/gnu/libexec/uucp/libunix/fsusg.c b/gnu/libexec/uucp/libunix/fsusg.c index e2b40a8ad5a5..116ab88fc187 100644 --- a/gnu/libexec/uucp/libunix/fsusg.c +++ b/gnu/libexec/uucp/libunix/fsusg.c @@ -1,5 +1,5 @@ /* fsusage.c -- return space usage of mounted filesystems - Copyright (C) 1991, 1992 Free Software Foundation, Inc. + Copyright (C) 1991, 1992, 1993 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 @@ -19,11 +19,10 @@ for use with Taylor UUCP. */ #include "uucp.h" +#include "uudefs.h" #include "sysdep.h" #include "fsusg.h" -int statfs (); - #if STAT_STATFS2_BSIZE #ifndef _IBMR2 /* 4.3BSD, SunOS 4, HP-UX, AIX PS/2. */ #include <sys/vfs.h> @@ -52,16 +51,19 @@ int statfs (); #endif #endif -#ifdef _AIX -#ifdef _I386 /* AIX PS/2. */ +#if STAT_DUSTAT /* AIX PS/2. */ #include <sys/stat.h> #include <sys/dustat.h> #endif -#endif #if STAT_STATVFS /* SVR4. */ #include <sys/statvfs.h> -int statvfs (); +#endif + +#if STAT_DISK_SPACE /* QNX. */ +#include <sys/disk.h> +#include <fcntl.h> +#include <errno.h> #endif #define STAT_NONE 0 @@ -71,7 +73,9 @@ int statvfs (); #if ! STAT_STATFS2_FSIZE #if ! STAT_STATFS2_FS_DATA #if ! STAT_STATFS4 +#if ! STAT_DUSTAT #if ! STAT_USTAT +#if ! STAT_DISK_SPACE #undef STAT_NONE #define STAT_NONE 1 #endif @@ -80,9 +84,13 @@ int statvfs (); #endif #endif #endif +#endif +#endif #if ! STAT_NONE +static long adjust_blocks P((long blocks, int fromsize, int tosize)); + /* Return the number of TOSIZE-byte blocks used by BLOCKS FROMSIZE-byte blocks, rounding up. */ @@ -121,7 +129,7 @@ get_fs_usage (path, disk, fsp) if (statfs (path, &fsd) != 1) return -1; -#define convert_blocks(b) adjust_blocks ((b), 1024, 512) +#define convert_blocks(b) adjust_blocks ((long) (b), 1024, 512) fsp->fsu_blocks = convert_blocks (fsd.fd_req.btot); fsp->fsu_bfree = convert_blocks (fsd.fd_req.bfree); fsp->fsu_bavail = convert_blocks (fsd.fd_req.bfreen); @@ -129,7 +137,7 @@ get_fs_usage (path, disk, fsp) fsp->fsu_ffree = fsd.fd_req.gfree; #endif -#if STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX. */ +#if STAT_STATFS2_BSIZE || STAT_DUSTAT /* 4.3BSD, SunOS 4, HP-UX, AIX. */ struct statfs fsd; if (statfs (path, &fsd) < 0) @@ -169,23 +177,94 @@ get_fs_usage (path, disk, fsp) adjust_blocks ((b), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512) #endif +#if STAT_DISK_SPACE /* QNX. */ + int o; + int iret; + long cfree_blocks, ctotal_blocks; + char *zpath; + char *zslash; + + zpath = zbufcpy (path); + while ((o = open (zpath, O_RDONLY, 0)) == -1 + && errno == ENOENT) + { + /* The named file doesn't exist, so we can't open it. Try the + directory containing it. */ + if ((strcmp ("/", zpath) == 0) + || (strcmp (zpath, ".") == 0) + || (strcmp (zpath, "") == 0) + /* QNX peculiarity: "//2" means root on node 2 */ + || ((strncmp (zpath, "//", 2) == 0) + && (strchr (zpath + 2, '/') == NULL))) + { + /* We can't shorten this! */ + break; + } + + /* Shorten the pathname by one component and try again. */ + zslash = strrchr (zpath, '/'); + if (zslash == NULL) + { + /* Try the current directory. We can open directories. */ + zpath[0] = '.'; + zpath[1] = '\0'; + } + else if (zslash == zpath) + { + /* Try the root directory. */ + zpath[0] = '/'; + zpath[1] = '\0'; + } + else + { + /* Chop off last path component. */ + zslash[0] = '\0'; + } + } + if (o == -1) + { + ulog (LOG_ERROR, "get_fs_usage: open (%s) failed: %s", zpath, + strerror (errno)); + ubuffree (zpath); + return -1; + } + ubuffree (zpath); + + iret = disk_space (o, &cfree_blocks, &ctotal_blocks); + (void) close (o); + if (iret == -1) + { + ulog (LOG_ERROR, "get_fs_usage: disk_space failed: %s", + strerror (errno)); + return -1; + } + + fsp->fsu_blocks = ctotal_blocks; + fsp->fsu_bfree = cfree_blocks; + fsp->fsu_bavail = cfree_blocks; + + /* QNX has no limit on the number of inodes. Most inodes are stored + directly in the directory entry. */ + fsp->fsu_files = -1; + fsp->fsu_ffree = -1; +#endif /* STAT_DISK_SPACE */ + #if STAT_USTAT - { - struct stat sstat; - struct ustat s; + struct stat sstat; + struct ustat s; - if (stat (path, &sstat) < 0 - || ustat (sstat.st_dev, &s) < 0) - return -1; - fsp->fsu_blocks = -1; - fsp->fsu_bfree = f_tfree; - fsp->fsu_bavail = f_tfree; - fsp->fsu_files = -1; - fsp->fsu_ffree = -1; - } + if (stat (path, &sstat) < 0 + || ustat (sstat.st_dev, &s) < 0) + return -1; + fsp->fsu_blocks = -1; + fsp->fsu_bfree = s.f_tfree; + fsp->fsu_bavail = s.f_tfree; + fsp->fsu_files = -1; + fsp->fsu_ffree = -1; #endif #if ! STAT_STATFS2_FS_DATA /* ! Ultrix */ +#if ! STAT_DISK_SPACE #if ! STAT_USTAT #if ! STAT_NONE fsp->fsu_blocks = convert_blocks (fsd.f_blocks); @@ -196,12 +275,12 @@ get_fs_usage (path, disk, fsp) #endif #endif #endif +#endif return 0; } -#ifdef _AIX -#ifdef _I386 +#if STAT_DUSTAT /* AIX PS/2 does not supply statfs. */ int @@ -227,5 +306,4 @@ statfs (path, fsb) fsb->f_fsid.val[1] = fsd.du_pckno; return 0; } -#endif -#endif /* _AIX && _I386 */ +#endif /* STAT_DUSTAT */ |