Mail Archives: djgpp-workers/2001/12/14/18:48:11
Hello.
Please find below a diff that adds statvfs() to libc. This is implemented
according to draft D6 by the Austin Group (a draft of what will become the
next version of POSIX).
As suggested by Eli, fstatvfs() and statvfs() are basically just wrappers
for statfs(). They also call _is_cdrom() and pathconf() to fill in a
couple of other fields.
I chose to zero the fields referring to the number of file serial numbers
on a disk. I guess we could put some fake values here. The specification
says that not all the fields in the structure have to have meaningful
values, so we can leave them as zero.
DJ, would you need a disclaimer before I could commit this? My company is
being /incredibly/ slow about signing the disclaimer, despite it being
approved and me reminding them every two to three weeks.
Thanks, bye, Rich =]
--
Richard Dawe
http://www.phekda.freeserve.co.uk/richdawe/
--- /develop/djgpp/include/libc/stubs.h Sat Dec 1 20:06:58 2001
+++ /develop/djgpp.rw/include/libc/stubs.h Fri Dec 14 20:33:52 2001
@@ -21,6 +21,7 @@ extern "C" {
#define dup __dup
#define dup2 __dup2
#define fnmatch __fnmatch
+#define fstatvfs __fstatvfs
#define getcwd __getcwd
#define glob __glob
#define isatty __isatty
@@ -29,6 +30,7 @@ extern "C" {
#define open __open
#define putenv __putenv
#define read __read
+#define statvfs __statvfs
#define tzset __tzset
#define write __write
--- /develop/djgpp/include/sys/statvfs.h Thu Jan 1 00:00:00 1970
+++ /develop/djgpp.rw/include/sys/statvfs.h Fri Dec 14 20:39:48 2001
@@ -0,0 +1,40 @@
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+#ifndef __dj_include_sys_statvfs_h_
+#define __dj_include_sys_statvfs_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __dj_ENFORCE_ANSI_FREESTANDING
+
+#ifndef __STRICT_ANSI__
+
+struct statvfs {
+ unsigned long f_bsize;
+ unsigned long f_frsize;
+ fsblkcnt_t f_blocks;
+ fsblkcnt_t f_bfree;
+ fsblkcnt_t f_bavail;
+ fsfilcnt_t f_files;
+ fsfilcnt_t f_ffree;
+ fsfilcnt_t f_favail;
+ unsigned long f_fsid;
+ unsigned long f_flag;
+ unsigned long f_namemax;
+};
+
+#define ST_RDONLY 0x0001
+#define ST_NOSUID 0x0002
+
+int fstatvfs (int _fd, struct statvfs *_buf);
+int statvfs (const char *_path, struct statvfs *_buf);
+
+#endif /* !__STRICT_ANSI__ */
+#endif /* !__dj_ENFORCE_ANSI_FREESTANDING */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__dj_include_sys_statvfs_h_ */
--- /develop/djgpp/src/libc/posix/sys/statvfs/makefile Thu Jan 1
00:00:00 1970
+++ /develop/djgpp.rw/src/libc/posix/sys/statvfs/makefile Fri Dec 14
20:47:26 2001
@@ -0,0 +1,7 @@
+# Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details
+TOP=../../..
+
+SRC += fstatvfs.c
+SRC += statvfs.c
+
+include $(TOP)/../makefile.inc
--- /develop/djgpp/src/libc/posix/sys/statvfs/fstatvfs.c Thu Jan 1
00:00:00 1970
+++ /develop/djgpp.rw/src/libc/posix/sys/statvfs/fstatvfs.c Fri Dec 14
23:09:42 2001
@@ -0,0 +1,100 @@
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+
+#include <libc/stubs.h>
+#include <libc/fd_props.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/statvfs.h>
+
+int
+fstatvfs (int fd, struct statvfs *outbuf)
+{
+ const char *path = NULL;
+
+ if (__has_fd_properties(fd))
+ path = __get_fd_name(fd);
+
+ if (!path)
+ {
+ /* We can't find the path for `fd'. */
+ errno = ENOENT;
+ return -1;
+ }
+
+ return statvfs(path, outbuf);
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+ const char NOSUID[] = "nosuid";
+ const char RDONLY[] = "rdonly";
+ struct statvfs svbuf;
+ char buf[64];
+ int fd, i;
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "Syntax: %s <path> [<path> ...]\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ fd = open(argv[i], O_RDONLY);
+ if (fd < 0)
+ {
+ perror(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if (fstatvfs(fd, &svbuf) < 0)
+ {
+ perror(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ close(fd);
+
+ *buf = '\0';
+ if (svbuf.f_flag & ST_NOSUID)
+ strcat(buf, NOSUID);
+ if (svbuf.f_flag & ST_RDONLY)
+ {
+ if (svbuf.f_flag & ST_NOSUID)
+ strcat(buf, ",");
+ strcat(buf, RDONLY);
+ }
+
+ printf("%s:\n"
+ "\tBlock size: %lu\n"
+ "\tFundamental block size: %lu\n"
+ "\tBlocks on filesystem: %lu\n"
+ "\tFree blocks on filesystem: %lu\n"
+ "\tFree blocks on filesystem for unprivileged users: %lu\n"
+ "\tFile serial numbers: %lu\n"
+ "\tFree file serial numbers: %lu\n"
+ "\tFree file serial numbers for unprivileged users: %lu\n"
+ "\tFile system ID: %lu\n"
+ "\tFile system flags: %s\n"
+ "\tMaximum file name length:
%lu\n\n",
+ argv[i],
+ svbuf.f_bsize, svbuf.f_frsize,
+ svbuf.f_blocks, svbuf.f_bfree, svbuf.f_bavail,
+ svbuf.f_files, svbuf.f_ffree, svbuf.f_favail,
+ svbuf.f_fsid, buf, svbuf.f_namemax);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+#endif /* TEST */
--- /develop/djgpp/src/libc/posix/sys/statvfs/statvfs.c Thu Jan 1
00:00:00 1970
+++ /develop/djgpp.rw/src/libc/posix/sys/statvfs/statvfs.c Fri Dec 14
23:09:34 2001
@@ -0,0 +1,117 @@
+/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
+
+#include <libc/stubs.h>
+#include <sys/types.h>
+#include <sys/vfs.h>
+#include <sys/statvfs.h>
+#include <dos.h>
+#include <unistd.h>
+
+int
+statvfs (const char *path, struct statvfs *outbuf)
+{
+ struct statfs sbuf;
+ long len;
+
+ if (statfs(path, &sbuf) != 0)
+ {
+ /* Pass through the error from statfs(). */
+ return -1;
+ }
+
+ /* Fill outbuf from sbuf. */
+ outbuf->f_bsize = sbuf.f_bsize;
+ outbuf->f_blocks = sbuf.f_blocks;
+ outbuf->f_bfree = sbuf.f_bfree;
+ outbuf->f_bavail = sbuf.f_bavail;
+ outbuf->f_fsid = sbuf.f_fsid[0];
+
+ /* We pretend that the fundamental block size `f_frsize' for all
devices
+ * is 512 bytes. This seems reasonable since many (if not most) devices
+ * have 512 byte sectors. */
+ outbuf->f_frsize = 512;
+
+ /* Set the flags. */
+ outbuf->f_flag = ST_NOSUID;
+ if (_is_cdrom_drive(outbuf->f_fsid))
+ outbuf->f_flag |= ST_RDONLY;
+
+ /* Find the maximum file name length. */
+ len = pathconf(path, _PC_NAME_MAX);
+ if (len < 0)
+ {
+ /* Pass through the error from pathconf(). */
+ return -1;
+ }
+
+ outbuf->f_namemax = len;
+
+ /* Since it's unspecified by the standard whether all the fields
+ * are meaningful, zero unsupported fields. */
+ outbuf->f_files = outbuf->f_ffree = outbuf->f_favail = 0;
+
+ return 0;
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+ const char NOSUID[] = "nosuid";
+ const char RDONLY[] = "rdonly";
+ struct statvfs svbuf;
+ char buf[64];
+ int i;
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "Syntax: %s <path> [<path> ...]\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ if (statvfs(argv[i], &svbuf) < 0)
+ {
+ perror(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ *buf = '\0';
+ if (svbuf.f_flag & ST_NOSUID)
+ strcat(buf, NOSUID);
+ if (svbuf.f_flag & ST_RDONLY)
+ {
+ if (svbuf.f_flag & ST_NOSUID)
+ strcat(buf, ",");
+ strcat(buf, RDONLY);
+ }
+
+ printf("%s:\n"
+ "\tBlock size: %lu\n"
+ "\tFundamental block size: %lu\n"
+ "\tBlocks on filesystem: %lu\n"
+ "\tFree blocks on filesystem: %lu\n"
+ "\tFree blocks on filesystem for unprivileged users: %lu\n"
+ "\tFile serial numbers: %lu\n"
+ "\tFree file serial numbers: %lu\n"
+ "\tFree file serial numbers for unprivileged users: %lu\n"
+ "\tFile system ID: %lu\n"
+ "\tFile system flags: %s\n"
+ "\tMaximum file name length:
%lu\n\n",
+ argv[i],
+ svbuf.f_bsize, svbuf.f_frsize,
+ svbuf.f_blocks, svbuf.f_bfree, svbuf.f_bavail,
+ svbuf.f_files, svbuf.f_ffree, svbuf.f_favail,
+ svbuf.f_fsid, buf, svbuf.f_namemax);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+#endif /* TEST */
--- /develop/djgpp/src/libc/posix/sys/statvfs/fstatvfs.txh Thu Jan 1
00:00:00 1970
+++ /develop/djgpp.rw/src/libc/posix/sys/statvfs/fstatvfs.txh Fri Dec 14
23:35:14 2001
@@ -0,0 +1,45 @@
+@node fstatvfs, file system
+@subheading Syntax
+
+@example
+#include <sys/types.h>
+#include <sys/statvfs.h>
+
+int fstatvfs (int fd, struct statvfs *sbuf);
+@end example
+
+@subheading Description
+
+This function returns information about the "filesystem" (FS)
+containing the file referred to by the file descriptor @var{fd}
+and stores it in @var{sbuf}, which has the structure below:
+
+@example
+struct statvfs @{
+ unsigned long f_bsize; /* FS block size */
+ unsigned long f_frsize; /* fundamental block size */
+ fsblkcnt_t f_blocks; /* # of blocks on filesystem */
+ fsblkcnt_t f_bfree; /* # of free blocks on FS */
+ fsblkcnt_t f_bavail; /* # of free blocks on FS for
+ * unprivileged users */
+ fsfilcnt_t f_files; /* # of file serial numbers */
+ fsfilcnt_t f_ffree; /* # of free file serial numbers */
+ fsfilcnt_t f_favail; /* # of free file serial numbers
+ * for unprivileged users */
+ unsigned long f_fsid; /* FS identifier */
+ unsigned long f_flag; /* FS flags: bitwise OR of ST_NOSUID,
+ * ST_RDONLY */
+ unsigned long f_namemax; /* Maximum file name length on FS */
+@};
+@end example
+
+Note that if INT 21h is hooked by a TSR, the total size is limited
+to approximately 2GB.
+
+@subheading Return Value
+
+Zero on success, nonzero on failure (and @var{errno} set).
+
+@subheading Portability
+
+@portability !ansi, posix
--- /develop/djgpp/src/libc/posix/sys/statvfs/statvfs.txh Thu Jan 1
00:00:00 1970
+++ /develop/djgpp.rw/src/libc/posix/sys/statvfs/statvfs.txh Fri Dec 14
23:35:22 2001
@@ -0,0 +1,45 @@
+@node statvfs, file system
+@subheading Syntax
+
+@example
+#include <sys/types.h>
+#include <sys/statvfs.h>
+
+int statvfs (const char *path, struct statvfs *sbuf);
+@end example
+
+@subheading Description
+
+This function returns information about the "filesystem" (FS)
+containing @var{path} and stores it in @var{sbuf}, which has
+the structure below:
+
+@example
+struct statvfs @{
+ unsigned long f_bsize; /* FS block size */
+ unsigned long f_frsize; /* fundamental block size */
+ fsblkcnt_t f_blocks; /* # of blocks on filesystem */
+ fsblkcnt_t f_bfree; /* # of free blocks on FS */
+ fsblkcnt_t f_bavail; /* # of free blocks on FS for
+ * unprivileged users */
+ fsfilcnt_t f_files; /* # of file serial numbers */
+ fsfilcnt_t f_ffree; /* # of free file serial numbers */
+ fsfilcnt_t f_favail; /* # of free file serial numbers
+ * for unprivileged users */
+ unsigned long f_fsid; /* FS identifier */
+ unsigned long f_flag; /* FS flags: bitwise OR of ST_NOSUID,
+ * ST_RDONLY */
+ unsigned long f_namemax; /* Maximum file name length on FS */
+@};
+@end example
+
+Note that if INT 21h is hooked by a TSR, the total size is limited
+to approximately 2GB.
+
+@subheading Return Value
+
+Zero on success, nonzero on failure (and @var{errno} set).
+
+@subheading Portability
+
+@portability !ansi, posix
--- /develop/djgpp/src/libc/compat/sys/vfs/statfs.txh Sat Mar 17
14:10:50 2001
+++ /develop/djgpp.rw/src/libc/compat/sys/vfs/statfs.txh Fri Dec 14
23:27:14 2001
@@ -23,7 +23,7 @@ struct statfs
long f_bavail; /* available clusters */
long f_files; /* clusters on drive */
long f_ffree; /* available clusters */
- fsid_t f_fsid; /* [0]=drive_number, [1]=MOUNT_UFS
+ fsid_t f_fsid; /* array: [0]=drive_number, [1]=MOUNT_UFS */
long f_magic; /* FS_MAGIC */
@};
@end example
@@ -31,6 +31,9 @@ struct statfs
Note that if INT 21h is hooked by a TSR, the total size is limited
to approximately 2GB.
+Note that there is a POSIX-compliant function @code{statvfs}
+(@pxref{statvfs}), which returns similar information.
+
@subheading Return Value
Zero on success, nonzero on failure.
--- /develop/djgpp/src/docs/kb/wc204.txi Fri Dec 14 23:40:42 2001
+++ /develop/djgpp.rw/src/docs/kb/wc204.txi Fri Dec 14 22:59:26 2001
@@ -700,3 +700,9 @@ versions can be built. Profiling option
for certain files in the C libraries' sources. The build system for
@file{emu387.dxe}, the math co-processor emulation library, was also
modified, so that it can be built against a profiled version of libc.
+
+@findex fstatvfs
+@findex statvfs
+The functions @code{fstatvfs} and @code{statvfs} have been added.
+@code{statvfs} does much the same as @code{statfs}, but it is
+POSIX-compliant.
- Raw text -