www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/08/14/15:13:39

Message-ID: <399844B1.9A99D08F@softhome.net>
Date: Mon, 14 Aug 2000 21:12:49 +0200
From: Laurynas Biveinis <lauras AT softhome DOT net>
X-Mailer: Mozilla 4.74 [en] (Win98; U)
X-Accept-Language: lt,en
MIME-Version: 1.0
To: DJGPP Workers <djgpp-workers AT delorie DOT com>
Subject: Patch: lstat() adjustments for symlinks
Reply-To: djgpp-workers AT delorie DOT com

It adds new macros S_ISLNK and S_IFLNK, as well as code to set them
in lstat() and testsuite.

Any comments?
Laurynas

Index: djgpp/include/sys/stat.h
===================================================================
RCS file: /cvs/djgpp/djgpp/include/sys/stat.h,v
retrieving revision 1.2
diff -u -r1.2 stat.h
--- stat.h	2000/08/07 15:30:58	1.2
+++ stat.h	2000/08/14 19:09:29
@@ -64,6 +64,8 @@
 
 /* POSIX.1 doesn't mention these at all */
 
+#define S_ISLNK(m)	(((m) & 0xf000) == 0x8000)
+
 #define S_IFMT		0xf000
 
 #define S_IFREG		0x0000
@@ -71,6 +73,7 @@
 #define S_IFCHR		0x2000
 #define S_IFDIR		0x3000
 #define S_IFIFO		0x4000
+#define S_IFLNK         0x8000
 #define S_IFFIFO	S_IFIFO
 
 #define S_IFLABEL	0x5000
Index: djgpp/src/docs/kb/wc204.txi
===================================================================
RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v
retrieving revision 1.18
diff -u -r1.18 wc204.txi
--- wc204.txi	2000/08/14 08:51:29	1.18
+++ wc204.txi	2000/08/14 19:09:31
@@ -84,9 +84,7 @@
 @email{restone@@skypoint.com, Richard E. Stone}.
 
 @findex lchown AT r{, added to the library}
-@findex lstat AT r{, added to the library}
-New functions @code{lchown} and @code{lstat} have been added for 
-UNIX compatibility.
+New function @code{lchown} has been added for UNIX compatibility.
 
 @findex setitimer AT r{, and zero @code{it_interval.tv_usec}}
 Calling the @code{setitimer} function with both
@@ -97,11 +95,17 @@
 
 @findex __solve_symlinks AT r{, and symlink support}
 @findex __solve_symlinks AT r{, added to the library}
+@findex lstat AT r{, added to the library}
+@findex lstat AT r{, and symlink support}
 @findex readlink AT r{, and symlink support}
 @findex readlink AT r{, added to the library}
+@findex S_ISLNK AT r{, and symlink support}
+@findex S_ISLNK AT r{, added to the library}
+@findex S_IFLNK AT r{, and symlink support}
+@findex S_IFLNK AT r{, added to the library}
 UNIX-style symbolic links are fully emulated by library. As a part of this,
-new functions @code{__solve_symlinks} and @code{readlink} have been 
-added to library.
+new functions @code{__solve_symlinks}, @code{lstat} and @code{readlink};
+new macros @code{S_ISLNK} and @code{S_IFLNK} have been added to library.
 
 @findex symlink AT r{, and symlink support}
 As a part of symlink emulation, @code{symlink} no longer emulates symlinks
Index: djgpp/src/libc/posix/sys/stat/lstat.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/sys/stat/lstat.c,v
retrieving revision 1.1
diff -u -r1.1 lstat.c
--- lstat.c	2000/08/05 16:53:45	1.1
+++ lstat.c	2000/08/14 19:09:57
@@ -628,21 +628,39 @@
 
       else
         {
-          /* This is a regular file. */
-          char *extension  = strrchr(ff_blk.ff_name, '.');
+          int bytes_read;
+          int old_errno;
+          char buf[2];
 
-          /* Set regular file bit.  */
-          statbuf->st_mode |= S_IFREG;
+          /* Check if it is symlink.  */
+          old_errno = errno;
+          bytes_read = readlink(pathname, buf, 1);
+          if (bytes_read != -1)
+          {
+              /* Yes, it is.  */
+              statbuf->st_mode |= S_IFLNK;
+              errno = old_errno;
+          }
+          else
+          {
+              /* This is a regular file. */
+              char *extension  = strrchr(ff_blk.ff_name, '.');
 
-          if ((_djstat_flags & _STAT_EXECBIT) != _STAT_EXECBIT)
-            {
-              /* Set execute bits based on file's extension and
-                 first 2 bytes. */
-              if (extension)
-                extension++;    /* get past the dot */
-              if (_is_executable(pathname, -1, extension))
-                statbuf->st_mode |= EXEC_ACCESS;
-            }
+              errno = old_errno;
+
+              /* Set regular file bit.  */
+              statbuf->st_mode |= S_IFREG;
+
+              if ((_djstat_flags & _STAT_EXECBIT) != _STAT_EXECBIT)
+                {
+                  /* Set execute bits based on file's extension and
+                     first 2 bytes. */
+                  if (extension)
+                    extension++;    /* get past the dot */
+                  if (_is_executable(pathname, -1, extension))
+                    statbuf->st_mode |= EXEC_ACCESS;
+                }
+          }
         }
     }
   else if ((_djstat_fail_bits & _STFAIL_TRUENAME))
Index: djgpp/tests/libc/posix/sys/stat/file1
===================================================================
RCS file: file1
diff -N file1
--- /dev/null	Tue May  5 16:32:27 1998
+++ file1	Mon Aug 14 15:10:06 2000
@@ -0,0 +1 @@
+0123456789
\ No newline at end of file
Index: djgpp/tests/libc/posix/sys/stat/lstat.c
===================================================================
RCS file: lstat.c
diff -N lstat.c
--- /dev/null	Tue May  5 16:32:27 1998
+++ lstat.c	Mon Aug 14 15:10:06 2000
@@ -0,0 +1,62 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+int main(void)
+{
+   char *tmp_file;
+   struct stat file_info;
+   if (!__file_exists("file1"))
+   {
+      fprintf(stderr, "Required data file not found\n");
+      exit(1);
+   }
+   tmp_file = tmpnam(NULL);
+   symlink("file1", tmp_file);
+   if (lstat(tmp_file, &file_info))
+   {
+      fprintf(stderr, "Test 1 failed - unexpected lstat() failure\n");
+      exit(1);
+   }
+   if (file_info.st_size != 510)
+   {
+      fprintf(stderr, "Test 1 failed - lstat() returns wrong link size\n");
+      exit(1);
+   }
+   if (!S_ISLNK(file_info.st_mode))
+   {
+      fprintf(stderr, "Test 1 failed - lstat() does not set link bit for mode\n");
+      exit(1);
+   }
+   if (file_info.st_mode & !S_IFLNK)
+   {
+      fprintf(stderr, "Test 1 failed - lstat() set other mode bits for link\n");
+      exit(1);
+   }
+   printf("Test 1 passed\n");
+   if (lstat("file1", &file_info))
+   {
+      fprintf(stderr, "Test 2 failed - unexpected lstat() failure\n");
+      exit(1);
+   }
+   if (file_info.st_size != 10)
+   {
+      fprintf(stderr, "Test 2 failed - lstat() returns wrong file size\n");
+      exit(1);
+   }
+   if (!S_ISREG(file_info.st_mode))
+   {
+      fprintf(stderr, "Test 2 failed - lstat() does not set regular file bit "
+                      "for mode\n");
+      exit(1);
+   }
+   if (file_info.st_mode & !S_IFREG)
+   {
+      fprintf(stderr, "Test 2 failed - lstat() sets other mode bits for file\n");
+      exit(1);
+   }
+   printf("Test 2 passed\n");
+   remove(tmp_file);
+   return 0;
+}
\ No newline at end of file
Index: djgpp/tests/libc/posix/sys/stat/makefile
===================================================================
RCS file: /cvs/djgpp/djgpp/tests/libc/posix/sys/stat/makefile,v
retrieving revision 1.1
diff -u -r1.1 makefile
--- makefile	1996/01/14 02:00:52	1.1
+++ makefile	2000/08/14 19:10:06
@@ -2,6 +2,7 @@
 
 SRC += fixpath.c
 SRC += leak.c
+SRC += lstat.c
 SRC += mkdir.c
 SRC += stat.c
 SRC += stat1.c

- Raw text -


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