delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2008/12/06/13:35:27

X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f
X-Recipient: djgpp-workers AT delorie DOT com
X-Authenticated: #27081556
X-Provags-ID: V01U2FsdGVkX1/O3LFaxj/OqN/3hXljckvqNVhjFzGBFRVR7tzsHa
gczVwOblWI3gGF
Message-ID: <001101c957cd$86db7010$2602a8c0@computername>
From: "Juan Manuel Guerrero" <juan DOT guerrero AT gmx DOT de>
To: <djgpp-workers AT delorie DOT com>
Subject: One bug fix for opendir/readdir commited
Date: Sat, 6 Dec 2008 19:07:38 +0100
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2800.1106
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
X-Y-GMX-Trusted: 0
X-FuHaFi: 0.43
Reply-To: djgpp-workers AT delorie DOT com

OFYI:
I have checked in the patch below to fix an issue in the DIR structure
that I have already reported some months ago in
<http://www.delorie.com/archives/browse.cgi?p=djgpp-workers/2008/05/21/08:23:25>

With this patch the DIR structure no longer will have a trailing "/*.*"
string appended to the canonicalized directory name.  All libc functions
that require such a trailing string will take care to append it to the dir
name when they need it.  This avoids difficulties with code that appends a
path string to the end of the dir string without first checking that no "/*.*"
string is already append to it.

Regards,
Juan M. Guerrero


2008-05-21  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>


 * djgpp/src/libc/posix/dirent/opendir.c (opendir): No longer add a
 trailing "/*.*" string to the canonicalized directory string stored
 in the DIR directory structure.
 (__set_need_fake_dot_dotdot): Add "/*.*" to the directory string before
 passing it to findfirst.

 * djgpp/src/libc/posix/dirent/readdir.c (readdir): Add "/*.*" to the
 directory string before passing it to findfirst.

 * src/docs/kb/wc204.txi: Document changes.








Index: djgpp/src/docs/kb/wc204.txi
===================================================================
RCS file: /cvs/djgpp/djgpp/src/docs/kb/wc204.txi,v
retrieving revision 1.188
diff -U5 -r1.188 wc204.txi
--- djgpp/src/docs/kb/wc204.txi 6 Dec 2008 13:53:42 -0000 1.188
+++ djgpp/src/docs/kb/wc204.txi 6 Dec 2008 14:03:04 -0000
@@ -1163,5 +1163,14 @@
 @findex _fixpath AT r{, and Windows 2000/XP root directories and drive specifier character case}
 @findex __canonicalize_path AT r{, and Windows 2000/XP root directories and drive specifier character case}
 Lower case drive specifier characters will now be recognized as valid drive specifier too.
 Relative paths that start from the root directory will be correctly canonicalized
 because the backslash following the drive specifier is now removed.
+
+@findex opendir AT r{, fixed malformed path string for symlinks}
+@findex readdir AT r{, fixed malformed path string for symlinks}
+@findex __set_need_fake_dot_dotdot AT r{, fixed malformed path string for symlinks}
+The trailing search pattern @code{/*.*} has been removed from the path string
+stored in the member @code{name} of the @code{DIR} structure created by @code{opendir}
+and used by @code{readdir}, @code{rewinddir} and @code{__set_need_fake_dot_dotdot}.
+Now it only contains the canonicalized path to the directory without a terminating slash.
+Those functions that require the trailing search pattern @code{/*.*} will append it.
Index: djgpp/src/libc/posix/dirent/opendir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/dirent/opendir.c,v
retrieving revision 1.6
diff -U5 -r1.6 opendir.c
--- djgpp/src/libc/posix/dirent/opendir.c 17 Oct 2002 23:00:25 -0000 1.6
+++ djgpp/src/libc/posix/dirent/opendir.c 6 Dec 2008 14:03:06 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 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 */
@@ -18,10 +19,26 @@
 #include <fcntl.h>
 #include <libc/dosio.h>
 #include <dpmi.h>
 #include "dirstruc.h"
 
+#define IS_ROOT_DIR(path)  (((path)[1] == ':') && ((path)[2] == '/') && ((path)[3] == '\0'))
+
+#define APPEND_STAR_DOT_STAR(dst, src)  \
+  do {                                  \
+    int _i;                             \
+                                        \
+    for (_i = 0; (src)[_i]; _i++)       \
+      (dst)[_i] = (src)[_i];            \
+    (dst)[_i++] = '/';                  \
+    (dst)[_i++] = '*';                  \
+    (dst)[_i++] = '.';                  \
+    (dst)[_i++] = '*';                  \
+    (dst)[_i++] = '\0';                 \
+  } while(1)
+
+
 void
 _lfn_find_close(int handle)
 {
   __dpmi_regs r;
 
@@ -38,14 +55,17 @@
 __set_need_fake_dot_dotdot(DIR *dir)
 {
   int oerrno = errno;
 
   dir->need_fake_dot_dotdot = 0;
-  if (strlen(dir->name) == 6) /* "d:/" + "*.*" */
+  if (IS_ROOT_DIR(dir->name))
   {    
     /* see if findfirst finds "." anyway */
-    if (findfirst(dir->name, &dir->ff, FA_ARCH|FA_RDONLY|FA_DIREC)
+    char dir_name[FILENAME_MAX + 1];
+
+    APPEND_STAR_DOT_STAR(dir_name, dir->name);
+    if (findfirst(dir_name, &dir->ff, FA_ARCH|FA_RDONLY|FA_DIREC)
  || strcmp(dir->ff.ff_name, "."))
     {
       dir->need_fake_dot_dotdot = 2;
 
       /* Restore errno in certain cases. findfirst() will fail for empty
@@ -97,11 +117,14 @@
     free(dir->name);
     free(dir);
     return 0;
   }
 
-  /* Strip trailing slashes, so we can append "/ *.*" */
+  /* Strip trailing slashes.
+     The "/ *.*" is no longer part of the directory
+     name but is appended in every libc function
+     that requires it.  */
   length = strlen(dir->name);
   while (1)
   {
     if (length == 0) break;
     length--;
@@ -112,14 +135,10 @@
     {
       length++;
       break;
     }
   }
-  dir->name[length++] = '/';
-  dir->name[length++] = '*';
-  dir->name[length++] = '.';
-  dir->name[length++] = '*';
   dir->name[length++] = 0;
 
   /* If we're doing opendir of the root directory, we need to
      fake out the . and .. entries, as some unix programs (like
      mkisofs) expect them and fail if they don't exist */
Index: djgpp/src/libc/posix/dirent/readdir.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/libc/posix/dirent/readdir.c,v
retrieving revision 1.6
diff -U5 -r1.6 readdir.c
--- djgpp/src/libc/posix/dirent/readdir.c 17 Jun 2008 11:54:55 -0000 1.6
+++ djgpp/src/libc/posix/dirent/readdir.c 6 Dec 2008 14:03:06 -0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 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) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
@@ -12,10 +13,23 @@
 #include <ctype.h>
 #include <io.h>
 #include <libc/symlink.h>
 #include "dirstruc.h"
 
+#define APPEND_STAR_DOT_STAR(dst, src)  \
+  do {                                  \
+    int _i;                             \
+                                        \
+    for (_i = 0; (src)[_i]; _i++)       \
+      (dst)[_i] = (src)[_i];            \
+    (dst)[_i++] = '/';                  \
+    (dst)[_i++] = '*';                  \
+    (dst)[_i++] = '.';                  \
+    (dst)[_i++] = '*';                  \
+    (dst)[_i++] = '\0';                 \
+  } while(1)
+
 struct dirent *
 readdir(DIR *dir)
 {
   int done;
   int oerrno = errno;
@@ -39,24 +53,26 @@
 
   if (dir->num_read)
     done = findnext(&dir->ff);
   else
   {
+    char dir_name[FILENAME_MAX + 1];
     int ff_flags = FA_ARCH|FA_RDONLY|FA_DIREC|FA_SYSTEM;
     if (!(dir->flags & __OPENDIR_NO_HIDDEN))
       ff_flags |= FA_HIDDEN;
     if (dir->flags & __OPENDIR_FIND_LABEL)
       ff_flags |= FA_LABEL;
-    done = findfirst(dir->name, &dir->ff, ff_flags);
+    APPEND_STAR_DOT_STAR(dir_name, dir->name);
+    done = findfirst(dir_name, &dir->ff, ff_flags);
   }
   if (done)
   {
     if (errno == ENMFILE)
       errno = oerrno;
     return 0;
   }
-  dir->num_read ++;
+  dir->num_read++;
   if (!(dir->flags & __OPENDIR_PRESERVE_CASE))
   {
     char *cp;
 
     if (_is_DOS83(dir->ff.ff_name))

- Raw text -


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