Mail Archives: djgpp-workers/2002/01/29/16:16:26
Hello.
Please find below a revised patch to add statvfs, fstatvfs
to DJGPP. The only change over the previous patch is that
the file serial number fields are filled in with the number
of blocks, as per Eli's suggestion.
OK to commit? (I finally I have a disclaimer for DJGPP
from my company. Yay!)
Thanks, bye, Rich
--- /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 Sun Dec 16 10:31:58 2001
@@ -0,0 +1,120 @@
+/* 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];
+
+ /* The `file serial number' fields can be considered to be
+ * numbers of inodes. Since an inode and block are roughly equivalent,
+ * fill these in with the numbers of blocks. */
+ outbuf->f_files = sbuf.f_blocks;
+ outbuf->f_ffree = sbuf.f_bfree;
+ outbuf->f_favail = sbuf.f_bavail;
+
+ /* 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;
+
+ 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 Tue Jan 29 21:14:28 2002
+++ /develop/djgpp.rw/src/docs/kb/wc204.txi Tue Jan 29 21:10:02 2002
@@ -708,3 +708,9 @@ Corrected problem with negative gmt offs
@cindex startup code, and memory corruption
The startup code was updated, to prevent memory corruption when
the @env{DJGPP} environment variable is not set.
+
+@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 -