Message-ID: <399844B1.9A99D08F@softhome.net> Date: Mon, 14 Aug 2000 21:12:49 +0200 From: Laurynas Biveinis X-Mailer: Mozilla 4.74 [en] (Win98; U) X-Accept-Language: lt,en MIME-Version: 1.0 To: DJGPP Workers Subject: Patch: lstat() adjustments for symlinks Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit 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 +#include +#include +#include + +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