Mail Archives: djgpp-workers/2000/08/01/12:49:16
OK, here is reworked patch:
- New stat.c is diffed against /dev/null
- lstat.c is diffed against old stat.c
- everything else has been left untouched.
--- /dev/null Tue Aug 1 18:04:59 2000
+++ stat.c.new Sun Jul 30 21:22:52 2000
@@ -0,0 +1,80 @@
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+
+/* Main entry point. This is library stat() function.
+ Actual code has been moved to lstat() in lstat.c.
+ */
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <libc/symlink.h>
+
+#ifdef TEST
+#include "xstat.h"
+#endif
+
+int
+stat(const char *path, struct stat *statbuf)
+{
+ return lstat(path, statbuf);
+}
+
+#ifdef TEST
+
+unsigned short _djstat_flags = 0;
+
+void
+main(int argc, char *argv[])
+{
+ struct stat stat_buf;
+ char *endp;
+
+ if (argc < 2)
+ {
+ fprintf (stderr, "Usage: %s <_djstat_flags> <file...>\n", argv[0]);
+ exit(0);
+ }
+
+ if (stat(*argv, &stat_buf) != 0)
+ perror ("stat failed on argv[0]");
+ else
+ fprintf(stderr, "DOS %d.%d (%s)\n", _osmajor, _osminor, _os_flavor);
+ argc--; argv++;
+
+ _djstat_flags = (unsigned short)strtoul(*argv, &endp, 0);
+ argc--; argv++;
+
+ while (argc--)
+ {
+ if (!stat(*argv, &stat_buf))
+ {
+ fprintf(stderr, "%s: %d %6u %o %d %d %ld %lu %s", *argv,
+ stat_buf.st_dev,
+ (unsigned)stat_buf.st_ino,
+ stat_buf.st_mode,
+ stat_buf.st_nlink,
+ stat_buf.st_uid,
+ (long)stat_buf.st_size,
+ (unsigned long)stat_buf.st_mtime,
+ ctime(&stat_buf.st_mtime));
+ _djstat_describe_lossage(stderr);
+ }
+ else
+ {
+ fprintf(stderr, "%s: lossage", *argv);
+ perror(" ");
+ _djstat_describe_lossage(stderr);
+ }
+
+ ++argv;
+ }
+
+ exit (0);
+}
+
+#endif
Index: stat/stat.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/stat.c,v
retrieving revision 1.7
diff -u -r1.7 stat.c
--- stat.c 1999/06/03 17:27:40 1.7
+++ stat.c 2000/08/01 16:03:28
@@ -1,15 +1,17 @@
+/* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
-/* This is file STAT.C */
+/* This is file LSTAT.C */
/*
- * Almost a 100% U**X-compatible stat() substitute.
+ * Almost a 100% U**X-compatible stat()/lstat() substitute.
*
- * Usage:
+ * Note:
*
- * That's easy: put this into libc.a, then just call stat() as usual.
+ * The actual function implemented here is lstat(), not stat(). The
+ * stat() now is just a lstat() wrapper.
*
* Rationale:
*
@@ -851,11 +853,11 @@
return 0;
}
-/* Main entry point. This is library stat() function.
+/* Main entry point. This is library lstat() function.
*/
int
-stat(const char *path, struct stat *statbuf)
+lstat(const char *path, struct stat *statbuf)
{
int e = errno;
int pathlen, ret;
@@ -911,8 +913,8 @@
exit(0);
}
- if (stat(*argv, &stat_buf) != 0)
- perror ("stat failed on argv[0]");
+ if (lstat(*argv, &stat_buf) != 0)
+ perror ("lstat failed on argv[0]");
else
fprintf(stderr, "DOS %d.%d (%s)\n", _osmajor, _osminor, _os_flavor);
argc--; argv++;
@@ -922,7 +924,7 @@
while (argc--)
{
- if (!stat(*argv, &stat_buf))
+ if (!lstat(*argv, &stat_buf))
{
fprintf(stderr, "%s: %d %6u %o %d %d %ld %lu %s", *argv,
stat_buf.st_dev,
@@ -949,4 +951,3 @@
}
#endif
-
Index: src/docs/kb/wc204.txi
===================================================================
RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v
retrieving revision 1.15
diff -u -r1.15 wc204.txi
--- wc204.txi 2000/07/26 17:54:44 1.15
+++ wc204.txi 2000/07/30 19:53:31
@@ -84,7 +84,9 @@
@email{restone@@skypoint.com, Richard E. Stone}.
@findex lchown AT r{, added to the library}
-New function @code{lchown} has been added for UNIX compatibility.
+@findex lstat AT r{, added to the library}
+New functions @code{lchown} and @code{lstat} have been added for
+UNIX compatibility.
@findex setitimer AT r{, and zero @code{it_interval.tv_usec}}
Calling the @code{setitimer} function with both
Index: src/libc/posix/sys/stat/lstat.txh
===================================================================
RCS file: lstat.txh
diff -N lstat.txh
--- /dev/null Tue May 5 16:32:27 1998
+++ lstat.txh Sun Jul 30 15:53:46 2000
@@ -0,0 +1,117 @@
+@node lstat, io
+@subheading Syntax
+
+@example
+#include <sys/stat.h>
+
+int lstat(const char *file, struct stat *sbuf);
+@end example
+
+@subheading Description
+
+This function obtains the status of the file @var{file} and stores
+it in @var{sbuf}, which has this structure:
+
+@smallexample
+struct stat @{
+ time_t st_atime; /* time of last access */
+ time_t st_ctime; /* time of file's creation */
+ dev_t st_dev; /* The drive number (0 = a:) */
+ gid_t st_gid; /* what getgid() returns */
+ ino_t st_ino; /* starting cluster or unique identifier */
+ mode_t st_mode; /* file mode - S_IF* and S_IRUSR/S_IWUSR */
+ time_t st_mtime; /* time that the file was last written */
+ nlink_t st_nlink; /* 2 + number of subdirs, or 1 for files */
+ off_t st_size; /* size of file in bytes */
+ off_t st_blksize; /* the size of transfer buffer */
+ uid_t st_uid; /* what getuid() returns */
+@};
+@end smallexample
+
+The @code{st_atime}, @code{st_ctime} and @code{st_mtime} have different
+values only when long file names are supported (e.g. on Windows 9X);
+otherwise, they all have the same value: the time that the file was last
+written AT footnote{
+Even when long file names @emph{are} supported, the three time values
+returned by @code{stat} might be identical if the file was last written
+by a program which used legacy DOS functions that don't know about long
+file names.}. Most Windows 9X VFAT filesystems only support the date of
+the file's last access (the time is set to zero); therefore, the DJGPP
+implementation of @code{stat} sets the @code{st_atime} member to the
+same value as @code{st_mtime} if the time part of @code{st_atime}
+returned by the filesystem is zero (to prevent the situation where the
+file appears to have been created @emph{after} it was last accessed,
+which doesn't look good).
+
+Some members of @code{struct stat} are very expensive to compute. If
+your application is a heavy user of @code{stat} and is too slow, you can
+disable computation of the members your application doesn't need, as
+described in @ref{_djstat_flags}.
+
+@subheading Return Value
+
+Zero on success, nonzero on failure (and @var{errno} set).
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+struct stat s;
+lstat("data.txt", &s);
+if (S_ISDIR(s.st_mode))
+ printf("is directory\n");
+@end example
+
+@subheading Implementation Notes
+
+Supplying a 100% Unix-compatible @code{lstat} function under DOS is an
+implementation nightmare. The following notes describe some of the
+obscure points specific to @code{lstat}s behavior in DJGPP.
+
+1. The @samp{drive} for character devices (like @code{con}, @code{/dev/null}
+and others is returned as -1. For drives networked by Novell Netware, it
+is returned as -2.
+
+2. The starting cluster number of a file serves as its inode number. For
+files whose starting cluster number is inaccessible (empty files, files on
+Windows 9X, on networked drives, etc.) the @code{st_inode} field will be
+@emph{invented}
+in a way which guarantees that no two different files will get the same
+inode number (thus it is unique). This invented inode will also be
+different from any real cluster number of any local file. However, only
+on plain DOS, and only for local, non-empty files/directories the inode
+is guaranteed to be consistent between @code{stat} and @code{fstat}
+function calls.
+
+3. The WRITE access mode bit is set only for the user (unless the file is
+read-only, hidden or system). EXECUTE bit is set for directories, files
+which can be executed from the DOS prompt (batch files, .com, .dll and .exe
+executables) or run by @code{go32-v2}.
+
+4. Size of directories is reported as the number of its files (sans `.' and
+`..' entries) multiplied by 32 bytes (the size of directory entry). On FAT
+filesystems that support the LFN API (such as Windows 9X), the reported
+size of the directory accounts for additional space used to store the long
+file names.
+
+5. Time stamp for root directories is taken from the volume label entry,
+if that's available; otherwise, it is reported as 1-Jan-1980.
+
+6. The variable @code{_djstat_flags} (@pxref{_djstat_flags}) controls
+what hard-to-get fields of @code{struct stat} are needed by the
+application.
+
+7. @code{stat} should not be used to get an up-to-date info about a file
+which is open and has been written to, because @code{stat} will only
+return correct data after the file is closed. Use @code{fstat}
+(@pxref{fstat}) while the file is open. Alternatively, you can call
+@code{fflush} and @code{fsync} to make the OS flush all the file's data
+to the disk, before calling @code{stat}.
+
+8. The number of links @code{st_nlink} is always 1 for files other than
+directories. For directories, it is the number of subdirectories plus
+2. This is so that programs written for Unix that depend on this to
+optimize recursive traversal of the directory tree, will still work.
Index: src/libc/posix/sys/stat/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/makefile,v
retrieving revision 1.1
diff -u -r1.1 makefile
--- makefile 1995/04/05 05:59:56 1.1
+++ makefile 2000/07/30 19:53:46
@@ -6,6 +6,7 @@
SRC += fixpath.c
SRC += fstat.c
SRC += is_exec.c
+SRC += lstat.c
SRC += mkdir.c
SRC += mkfifo.c
SRC += st_loss.c
Index: src/libc/posix/sys/stat/xstat.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/xstat.c,v
retrieving revision 1.2
diff -u -r1.2 xstat.c
--- xstat.c 2000/06/19 18:00:57 1.2
+++ xstat.c 2000/07/30 19:53:47
@@ -3,7 +3,7 @@
/*
* This is file XSTAT.C
*
- * Internal assist functions which are common to stat() and fstat().
+ * Internal assist functions which are common to stat(), fstat() and lstat().
*
*
* Copyright (c) 1994-96 Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
Index: src/libc/posix/sys/stat/xstat.h
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/xstat.h,v
retrieving revision 1.3
diff -u -r1.3 xstat.h
--- xstat.h 1996/08/12 23:58:18 1.3
+++ xstat.h 2000/07/30 19:53:48
@@ -1,7 +1,7 @@
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/*
- * Header for internal stat()/fstat() assist functions.
+ * Header for internal stat()/fstat()/lstat() assist functions.
*
*/
- Raw text -