www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/08/01/12:49:16

Message-ID: <3986F623.18444B8D@softhome.net>
Date: Tue, 01 Aug 2000 18:09:07 +0200
From: Laurynas Biveinis <lauras AT softhome DOT net>
X-Mailer: Mozilla 4.73 [en] (Win98; U)
X-Accept-Language: lt,en
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: Re: New function: lstat()
References: <Pine DOT SUN DOT 3 DOT 91 DOT 1000731085405 DOT 2256D-100000 AT is>
Reply-To: djgpp-workers AT delorie DOT com

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019