diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2012-11-22 23:48:43 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2012-11-22 23:48:43 -0800 |
commit | 95ef7787fb0a5786a2e4f150649aadfa687a15f2 (patch) | |
tree | c109235849121c6909c8dd5075ddf63ed847ee82 /src | |
parent | 6f6b82d66f73e65545865b72f109dbf695934aea (diff) | |
download | emacs-95ef7787fb0a5786a2e4f150649aadfa687a15f2.tar.gz |
Assume POSIX 1003.1-1988 or later for dirent.h.
* admin/CPP-DEFINES (HAVE_CLOSEDIR, HAVE_DIRENT_H): Remove.
* admin/notes/copyright: Adjust to src/ndir.h -> nt/inc/dirent.h renaming.
* configure.ac: Do not check for dirent.h or closdir.
* nt/inc/dirent.h: Rename from ../src/ndir.h, with these changes:
(struct dirent): Rename from struct direct. All uses changed.
* nt/inc/sys/dir.h: Remove.
* src/dired.c: Assume HAVE_DIRENT_H.
(NAMLEN): Remove, replacing with ...
(dirent_namelen): New function. All uses changed. Use the GNU macro
_D_EXACT_NAMELEN if available, as it's faster than strlen.
(DIRENTRY): Remove, replacing all uses with 'struct dirent'.
(DIRENTRY_NONEMPTY): Remove. All callers now assume it's nonzero.
* src/makefile.w32-in (DIR_H): Remove. All uses replaced with
$(NT_INC)/dirent.h.
($(BLD)/w32.$(O)): Do not depend on $(SRC)/ndir.h.
* src/ndir.h: Rename to ../nt/inc/dirent.h.
* src/sysdep.h (closedir) [!HAVE_CLOSEDIR]: Remove.
Do not include <dirent.h>; no longer needed.
* src/w32.c: Include <dirent.h> rather than "ndir.h".
Fixes: debbugs:12958
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 17 | ||||
-rw-r--r-- | src/dired.c | 205 | ||||
-rw-r--r-- | src/makefile.w32-in | 6 | ||||
-rw-r--r-- | src/ndir.h | 41 | ||||
-rw-r--r-- | src/sysdep.c | 22 | ||||
-rw-r--r-- | src/w32.c | 8 |
6 files changed, 113 insertions, 186 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d0f4ad6869d..5566b623cec 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,20 @@ +2012-11-23 Paul Eggert <eggert@cs.ucla.edu> + + Assume POSIX 1003.1-1988 or later for dirent.h (Bug#12958). + * dired.c: Assume HAVE_DIRENT_H. + (NAMLEN): Remove, replacing with ... + (dirent_namelen): New function. All uses changed. Use the GNU macro + _D_EXACT_NAMELEN if available, as it's faster than strlen. + (DIRENTRY): Remove, replacing all uses with 'struct dirent'. + (DIRENTRY_NONEMPTY): Remove. All callers now assume it's nonzero. + * makefile.w32-in (DIR_H): Remove. All uses replaced with + $(NT_INC)/dirent.h. + ($(BLD)/w32.$(O)): Do not depend on $(SRC)/ndir.h. + * ndir.h: Rename to ../nt/inc/dirent.h. + * sysdep.h (closedir) [!HAVE_CLOSEDIR]: Remove. + Do not include <dirent.h>; no longer needed. + * w32.c: Include <dirent.h> rather than "ndir.h". + 2012-11-23 Chong Yidong <cyd@gnu.org> * xftfont.c (xftfont_open): Remove duplicate assignment. diff --git a/src/dired.c b/src/dired.c index 4986f845101..3530b74ecb4 100644 --- a/src/dired.c +++ b/src/dired.c @@ -31,44 +31,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <errno.h> #include <unistd.h> -/* The d_nameln member of a struct dirent includes the '\0' character - on some systems, but not on others. What's worse, you can't tell - at compile-time which one it will be, since it really depends on - the sort of system providing the filesystem you're reading from, - not the system you are running on. Paul Eggert - <eggert@bi.twinsun.com> says this occurs when Emacs is running on a - SunOS 4.1.2 host, reading a directory that is remote-mounted from a - Solaris 2.1 host and is in a native Solaris 2.1 filesystem. - - Since applying strlen to the name always works, we'll just do that. */ -#define NAMLEN(p) strlen (p->d_name) - -#ifdef HAVE_DIRENT_H - #include <dirent.h> -#define DIRENTRY struct dirent - -#else /* not HAVE_DIRENT_H */ - -#include <sys/dir.h> -#include <sys/stat.h> - -#define DIRENTRY struct direct - -extern DIR *opendir (char *); -extern struct direct *readdir (DIR *); - -#endif /* HAVE_DIRENT_H */ - #include <filemode.h> #include <stat-time.h> -#ifdef MSDOS -#define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0) -#else -#define DIRENTRY_NONEMPTY(p) ((p)->d_ino) -#endif - #include "lisp.h" #include "systime.h" #include "character.h" @@ -88,6 +54,17 @@ static Lisp_Object Qfile_attributes_lessp; static ptrdiff_t scmp (const char *, const char *, ptrdiff_t); +/* Return the number of bytes in DP's name. */ +static ptrdiff_t +dirent_namelen (struct dirent *dp) +{ +#ifdef _D_EXACT_NAMLEN + return _D_EXACT_NAMLEN (dp); +#else + return strlen (dp->d_name); +#endif +} + #ifdef WINDOWSNT Lisp_Object directory_files_internal_w32_unwind (Lisp_Object arg) @@ -124,7 +101,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, bool needsep = 0; ptrdiff_t count = SPECPDL_INDEX (); struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; - DIRENTRY *dp; + struct dirent *dp; #ifdef WINDOWSNT Lisp_Object w32_save = Qnil; #endif @@ -209,6 +186,11 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, /* Loop reading blocks until EOF or error. */ for (;;) { + ptrdiff_t len; + bool wanted = 0; + Lisp_Object name, finalname; + struct gcpro gcpro1, gcpro2; + errno = 0; dp = readdir (d); @@ -225,89 +207,81 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, if (dp == NULL) break; - if (DIRENTRY_NONEMPTY (dp)) + len = dirent_namelen (dp); + name = finalname = make_unibyte_string (dp->d_name, len); + GCPRO2 (finalname, name); + + /* Note: DECODE_FILE can GC; it should protect its argument, + though. */ + name = DECODE_FILE (name); + len = SBYTES (name); + + /* Now that we have unwind_protect in place, we might as well + allow matching to be interrupted. */ + immediate_quit = 1; + QUIT; + + if (NILP (match) + || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0))) + wanted = 1; + + immediate_quit = 0; + + if (wanted) { - ptrdiff_t len; - bool wanted = 0; - Lisp_Object name, finalname; - struct gcpro gcpro1, gcpro2; + if (!NILP (full)) + { + Lisp_Object fullname; + ptrdiff_t nbytes = len + directory_nbytes + needsep; + ptrdiff_t nchars; - len = NAMLEN (dp); - name = finalname = make_unibyte_string (dp->d_name, len); - GCPRO2 (finalname, name); + fullname = make_uninit_multibyte_string (nbytes, nbytes); + memcpy (SDATA (fullname), SDATA (directory), + directory_nbytes); - /* Note: DECODE_FILE can GC; it should protect its argument, - though. */ - name = DECODE_FILE (name); - len = SBYTES (name); + if (needsep) + SSET (fullname, directory_nbytes, DIRECTORY_SEP); - /* Now that we have unwind_protect in place, we might as well - allow matching to be interrupted. */ - immediate_quit = 1; - QUIT; + memcpy (SDATA (fullname) + directory_nbytes + needsep, + SDATA (name), len); - if (NILP (match) - || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0))) - wanted = 1; + nchars = chars_in_text (SDATA (fullname), nbytes); - immediate_quit = 0; + /* Some bug somewhere. */ + if (nchars > nbytes) + emacs_abort (); - if (wanted) - { - if (!NILP (full)) - { - Lisp_Object fullname; - ptrdiff_t nbytes = len + directory_nbytes + needsep; - ptrdiff_t nchars; - - fullname = make_uninit_multibyte_string (nbytes, nbytes); - memcpy (SDATA (fullname), SDATA (directory), - directory_nbytes); - - if (needsep) - SSET (fullname, directory_nbytes, DIRECTORY_SEP); - - memcpy (SDATA (fullname) + directory_nbytes + needsep, - SDATA (name), len); - - nchars = chars_in_text (SDATA (fullname), nbytes); - - /* Some bug somewhere. */ - if (nchars > nbytes) - emacs_abort (); - - STRING_SET_CHARS (fullname, nchars); - if (nchars == nbytes) - STRING_SET_UNIBYTE (fullname); - - finalname = fullname; - } - else - finalname = name; - - if (attrs) - { - /* Construct an expanded filename for the directory entry. - Use the decoded names for input to Ffile_attributes. */ - Lisp_Object decoded_fullname, fileattrs; - struct gcpro gcpro1, gcpro2; - - decoded_fullname = fileattrs = Qnil; - GCPRO2 (decoded_fullname, fileattrs); - - /* Both Fexpand_file_name and Ffile_attributes can GC. */ - decoded_fullname = Fexpand_file_name (name, directory); - fileattrs = Ffile_attributes (decoded_fullname, id_format); - - list = Fcons (Fcons (finalname, fileattrs), list); - UNGCPRO; - } - else - list = Fcons (finalname, list); + STRING_SET_CHARS (fullname, nchars); + if (nchars == nbytes) + STRING_SET_UNIBYTE (fullname); + + finalname = fullname; } + else + finalname = name; - UNGCPRO; + if (attrs) + { + /* Construct an expanded filename for the directory entry. + Use the decoded names for input to Ffile_attributes. */ + Lisp_Object decoded_fullname, fileattrs; + struct gcpro gcpro1, gcpro2; + + decoded_fullname = fileattrs = Qnil; + GCPRO2 (decoded_fullname, fileattrs); + + /* Both Fexpand_file_name and Ffile_attributes can GC. */ + decoded_fullname = Fexpand_file_name (name, directory); + fileattrs = Ffile_attributes (decoded_fullname, id_format); + + list = Fcons (Fcons (finalname, fileattrs), list); + UNGCPRO; + } + else + list = Fcons (finalname, list); } + + UNGCPRO; } block_input (); @@ -442,7 +416,8 @@ These are all file names in directory DIRECTORY which begin with FILE. */) return file_name_completion (file, directory, 1, Qnil); } -static int file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr); +static int file_name_completion_stat (Lisp_Object dirname, struct dirent *dp, + struct stat *st_addr); static Lisp_Object Qdefault_directory; static Lisp_Object @@ -499,7 +474,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, /* (att3b compiler bug requires do a null comparison this way) */ while (1) { - DIRENTRY *dp; + struct dirent *dp; ptrdiff_t len; bool canexclude = 0; @@ -517,11 +492,10 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag, if (!dp) break; - len = NAMLEN (dp); + len = dirent_namelen (dp); QUIT; - if (! DIRENTRY_NONEMPTY (dp) - || len < SCHARS (encoded_file) + if (len < SCHARS (encoded_file) || 0 <= scmp (dp->d_name, SSDATA (encoded_file), SCHARS (encoded_file))) continue; @@ -806,9 +780,10 @@ scmp (const char *s1, const char *s2, ptrdiff_t len) } static int -file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr) +file_name_completion_stat (Lisp_Object dirname, struct dirent *dp, + struct stat *st_addr) { - ptrdiff_t len = NAMLEN (dp); + ptrdiff_t len = dirent_namelen (dp); ptrdiff_t pos = SCHARS (dirname); int value; USE_SAFE_ALLOCA; diff --git a/src/makefile.w32-in b/src/makefile.w32-in index 9778e955677..5d0c6e72146 100644 --- a/src/makefile.w32-in +++ b/src/makefile.w32-in @@ -413,8 +413,6 @@ CONF_POST_H = $(SRC)/conf_post.h \ $(MS_W32_H) CONFIG_H = $(SRC)/config.h \ $(CONF_POST_H) -DIR_H = $(NT_INC)/sys/dir.h \ - $(SRC)/ndir.h W32GUI_H = $(SRC)/w32gui.h \ $(SYSTIME_H) DISPEXTERN_H = $(SRC)/dispextern.h \ @@ -714,6 +712,7 @@ $(BLD)/dired.$(O) : \ $(SRC)/blockinput.h \ $(SRC)/commands.h \ $(SRC)/regex.h \ + $(NT_INC)/dirent.h \ $(NT_INC)/pwd.h \ $(NT_INC)/sys/stat.h \ $(NT_INC)/unistd.h \ @@ -722,7 +721,6 @@ $(BLD)/dired.$(O) : \ $(CHARSET_H) \ $(CODING_H) \ $(CONFIG_H) \ - $(DIR_H) \ $(FILEMODE_H) \ $(GRP_H) \ $(LISP_H) \ @@ -1175,11 +1173,11 @@ $(BLD)/minibuf.$(O) : \ $(BLD)/w32.$(O) : \ $(SRC)/w32.c \ - $(SRC)/ndir.h \ $(SRC)/w32.h \ $(SRC)/w32common.h \ $(SRC)/w32heap.h \ $(SRC)/w32select.h \ + $(NT_INC)/dirent.h \ $(NT_INC)/pwd.h \ $(NT_INC)/sys/file.h \ $(NT_INC)/sys/time.h \ diff --git a/src/ndir.h b/src/ndir.h deleted file mode 100644 index cd7cdbe55f5..00000000000 --- a/src/ndir.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - <dir.h> -- definitions for 4.2BSD-compatible directory access - - last edit: 09-Jul-1983 D A Gwyn - - * The code here is forced by the interface, and is not subject to - * copyright, constituting the only possible expression of the - * algorithm in this format. - */ - -#define DIRBLKSIZ 512 /* size of directory block */ -#ifdef WINDOWSNT -#define MAXNAMLEN 255 -#else /* not WINDOWSNT */ -#define MAXNAMLEN 15 /* maximum filename length */ -#endif /* not WINDOWSNT */ - /* NOTE: MAXNAMLEN must be one less than a multiple of 4 */ - -struct direct /* data from readdir() */ - { - long d_ino; /* inode number of entry */ - unsigned short d_reclen; /* length of this record */ - unsigned short d_namlen; /* length of string in d_name */ - char d_name[MAXNAMLEN+1]; /* name of file */ - }; - -typedef struct - { - int dd_fd; /* file descriptor */ - int dd_loc; /* offset in block */ - int dd_size; /* amount of valid data */ - char dd_buf[DIRBLKSIZ]; /* directory block */ - } DIR; /* stream data from opendir() */ - -extern DIR *opendir (char *); -extern struct direct *readdir (DIR *); -extern void seekdir (DIR *, long); -extern void closedir (DIR *); - -#define rewinddir( dirp ) seekdir( dirp, 0L ) - diff --git a/src/sysdep.c b/src/sysdep.c index 3dd19685540..bc4dc91509f 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -2220,28 +2220,6 @@ emacs_readlink (char const *filename, char initial_buf[READLINK_BUFSIZE]) &emacs_norealloc_allocator, careadlinkatcwd); } -/* Directory routines for systems that don't have them. */ - -#ifdef HAVE_DIRENT_H - -#include <dirent.h> - -#if !defined (HAVE_CLOSEDIR) - -int -closedir (DIR *dirp /* stream from opendir */) -{ - int rtnval; - - rtnval = emacs_close (dirp->dd_fd); - xfree (dirp); - - return rtnval; -} -#endif /* not HAVE_CLOSEDIR */ -#endif /* HAVE_DIRENT_H */ - - /* Return a struct timeval that is roughly equivalent to T. Use the least timeval not less than T. Return an extremal value if the result would overflow. */ diff --git a/src/w32.c b/src/w32.c index 038a442f529..c8e16dfaa94 100644 --- a/src/w32.c +++ b/src/w32.c @@ -179,7 +179,7 @@ typedef struct _REPARSE_DATA_BUFFER { #undef sendto #include "w32.h" -#include "ndir.h" +#include <dirent.h> #include "w32common.h" #include "w32heap.h" #include "w32select.h" @@ -2448,7 +2448,7 @@ is_exec (const char * name) and readdir. We can't use the procedures supplied in sysdep.c, so we provide them here. */ -struct direct dir_static; /* simulated directory contents */ +struct dirent dir_static; /* simulated directory contents */ static HANDLE dir_find_handle = INVALID_HANDLE_VALUE; static int dir_is_fat; static char dir_pathname[MAXPATHLEN+1]; @@ -2518,7 +2518,7 @@ closedir (DIR *dirp) xfree ((char *) dirp); } -struct direct * +struct dirent * readdir (DIR *dirp) { int downcase = !NILP (Vw32_downcase_file_names); @@ -2572,7 +2572,7 @@ readdir (DIR *dirp) downcase = 1; /* 8+3 aliases are returned in all caps */ } dir_static.d_namlen = strlen (dir_static.d_name); - dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + + dir_static.d_reclen = sizeof (struct dirent) - MAXNAMLEN + 3 + dir_static.d_namlen - dir_static.d_namlen % 4; /* If the file name in cFileName[] includes `?' characters, it means |