aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2012-11-22 23:48:43 -0800
committerPaul Eggert2012-11-22 23:48:43 -0800
commit95ef7787fb0a5786a2e4f150649aadfa687a15f2 (patch)
treec109235849121c6909c8dd5075ddf63ed847ee82 /src
parent6f6b82d66f73e65545865b72f109dbf695934aea (diff)
downloademacs-95ef7787fb0a5786a2e4f150649aadfa687a15f2.tar.gz
emacs-95ef7787fb0a5786a2e4f150649aadfa687a15f2.zip
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/ChangeLog17
-rw-r--r--src/dired.c205
-rw-r--r--src/makefile.w32-in6
-rw-r--r--src/ndir.h41
-rw-r--r--src/sysdep.c22
-rw-r--r--src/w32.c8
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 @@
12012-11-23 Paul Eggert <eggert@cs.ucla.edu>
2
3 Assume POSIX 1003.1-1988 or later for dirent.h (Bug#12958).
4 * dired.c: Assume HAVE_DIRENT_H.
5 (NAMLEN): Remove, replacing with ...
6 (dirent_namelen): New function. All uses changed. Use the GNU macro
7 _D_EXACT_NAMELEN if available, as it's faster than strlen.
8 (DIRENTRY): Remove, replacing all uses with 'struct dirent'.
9 (DIRENTRY_NONEMPTY): Remove. All callers now assume it's nonzero.
10 * makefile.w32-in (DIR_H): Remove. All uses replaced with
11 $(NT_INC)/dirent.h.
12 ($(BLD)/w32.$(O)): Do not depend on $(SRC)/ndir.h.
13 * ndir.h: Rename to ../nt/inc/dirent.h.
14 * sysdep.h (closedir) [!HAVE_CLOSEDIR]: Remove.
15 Do not include <dirent.h>; no longer needed.
16 * w32.c: Include <dirent.h> rather than "ndir.h".
17
12012-11-23 Chong Yidong <cyd@gnu.org> 182012-11-23 Chong Yidong <cyd@gnu.org>
2 19
3 * xftfont.c (xftfont_open): Remove duplicate assignment. 20 * 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/>. */
31#include <errno.h> 31#include <errno.h>
32#include <unistd.h> 32#include <unistd.h>
33 33
34/* The d_nameln member of a struct dirent includes the '\0' character
35 on some systems, but not on others. What's worse, you can't tell
36 at compile-time which one it will be, since it really depends on
37 the sort of system providing the filesystem you're reading from,
38 not the system you are running on. Paul Eggert
39 <eggert@bi.twinsun.com> says this occurs when Emacs is running on a
40 SunOS 4.1.2 host, reading a directory that is remote-mounted from a
41 Solaris 2.1 host and is in a native Solaris 2.1 filesystem.
42
43 Since applying strlen to the name always works, we'll just do that. */
44#define NAMLEN(p) strlen (p->d_name)
45
46#ifdef HAVE_DIRENT_H
47
48#include <dirent.h> 34#include <dirent.h>
49#define DIRENTRY struct dirent
50
51#else /* not HAVE_DIRENT_H */
52
53#include <sys/dir.h>
54#include <sys/stat.h>
55
56#define DIRENTRY struct direct
57
58extern DIR *opendir (char *);
59extern struct direct *readdir (DIR *);
60
61#endif /* HAVE_DIRENT_H */
62
63#include <filemode.h> 35#include <filemode.h>
64#include <stat-time.h> 36#include <stat-time.h>
65 37
66#ifdef MSDOS
67#define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
68#else
69#define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
70#endif
71
72#include "lisp.h" 38#include "lisp.h"
73#include "systime.h" 39#include "systime.h"
74#include "character.h" 40#include "character.h"
@@ -88,6 +54,17 @@ static Lisp_Object Qfile_attributes_lessp;
88 54
89static ptrdiff_t scmp (const char *, const char *, ptrdiff_t); 55static ptrdiff_t scmp (const char *, const char *, ptrdiff_t);
90 56
57/* Return the number of bytes in DP's name. */
58static ptrdiff_t
59dirent_namelen (struct dirent *dp)
60{
61#ifdef _D_EXACT_NAMLEN
62 return _D_EXACT_NAMLEN (dp);
63#else
64 return strlen (dp->d_name);
65#endif
66}
67
91#ifdef WINDOWSNT 68#ifdef WINDOWSNT
92Lisp_Object 69Lisp_Object
93directory_files_internal_w32_unwind (Lisp_Object arg) 70directory_files_internal_w32_unwind (Lisp_Object arg)
@@ -124,7 +101,7 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
124 bool needsep = 0; 101 bool needsep = 0;
125 ptrdiff_t count = SPECPDL_INDEX (); 102 ptrdiff_t count = SPECPDL_INDEX ();
126 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 103 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
127 DIRENTRY *dp; 104 struct dirent *dp;
128#ifdef WINDOWSNT 105#ifdef WINDOWSNT
129 Lisp_Object w32_save = Qnil; 106 Lisp_Object w32_save = Qnil;
130#endif 107#endif
@@ -209,6 +186,11 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
209 /* Loop reading blocks until EOF or error. */ 186 /* Loop reading blocks until EOF or error. */
210 for (;;) 187 for (;;)
211 { 188 {
189 ptrdiff_t len;
190 bool wanted = 0;
191 Lisp_Object name, finalname;
192 struct gcpro gcpro1, gcpro2;
193
212 errno = 0; 194 errno = 0;
213 dp = readdir (d); 195 dp = readdir (d);
214 196
@@ -225,89 +207,81 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full,
225 if (dp == NULL) 207 if (dp == NULL)
226 break; 208 break;
227 209
228 if (DIRENTRY_NONEMPTY (dp)) 210 len = dirent_namelen (dp);
211 name = finalname = make_unibyte_string (dp->d_name, len);
212 GCPRO2 (finalname, name);
213
214 /* Note: DECODE_FILE can GC; it should protect its argument,
215 though. */
216 name = DECODE_FILE (name);
217 len = SBYTES (name);
218
219 /* Now that we have unwind_protect in place, we might as well
220 allow matching to be interrupted. */
221 immediate_quit = 1;
222 QUIT;
223
224 if (NILP (match)
225 || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0)))
226 wanted = 1;
227
228 immediate_quit = 0;
229
230 if (wanted)
229 { 231 {
230 ptrdiff_t len; 232 if (!NILP (full))
231 bool wanted = 0; 233 {
232 Lisp_Object name, finalname; 234 Lisp_Object fullname;
233 struct gcpro gcpro1, gcpro2; 235 ptrdiff_t nbytes = len + directory_nbytes + needsep;
236 ptrdiff_t nchars;
234 237
235 len = NAMLEN (dp); 238 fullname = make_uninit_multibyte_string (nbytes, nbytes);
236 name = finalname = make_unibyte_string (dp->d_name, len); 239 memcpy (SDATA (fullname), SDATA (directory),
237 GCPRO2 (finalname, name); 240 directory_nbytes);
238 241
239 /* Note: DECODE_FILE can GC; it should protect its argument, 242 if (needsep)
240 though. */ 243 SSET (fullname, directory_nbytes, DIRECTORY_SEP);
241 name = DECODE_FILE (name);
242 len = SBYTES (name);
243 244
244 /* Now that we have unwind_protect in place, we might as well 245 memcpy (SDATA (fullname) + directory_nbytes + needsep,
245 allow matching to be interrupted. */ 246 SDATA (name), len);
246 immediate_quit = 1;
247 QUIT;
248 247
249 if (NILP (match) 248 nchars = chars_in_text (SDATA (fullname), nbytes);
250 || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0)))
251 wanted = 1;
252 249
253 immediate_quit = 0; 250 /* Some bug somewhere. */
251 if (nchars > nbytes)
252 emacs_abort ();
254 253
255 if (wanted) 254 STRING_SET_CHARS (fullname, nchars);
256 { 255 if (nchars == nbytes)
257 if (!NILP (full)) 256 STRING_SET_UNIBYTE (fullname);
258 { 257
259 Lisp_Object fullname; 258 finalname = fullname;
260 ptrdiff_t nbytes = len + directory_nbytes + needsep;
261 ptrdiff_t nchars;
262
263 fullname = make_uninit_multibyte_string (nbytes, nbytes);
264 memcpy (SDATA (fullname), SDATA (directory),
265 directory_nbytes);
266
267 if (needsep)
268 SSET (fullname, directory_nbytes, DIRECTORY_SEP);
269
270 memcpy (SDATA (fullname) + directory_nbytes + needsep,
271 SDATA (name), len);
272
273 nchars = chars_in_text (SDATA (fullname), nbytes);
274
275 /* Some bug somewhere. */
276 if (nchars > nbytes)
277 emacs_abort ();
278
279 STRING_SET_CHARS (fullname, nchars);
280 if (nchars == nbytes)
281 STRING_SET_UNIBYTE (fullname);
282
283 finalname = fullname;
284 }
285 else
286 finalname = name;
287
288 if (attrs)
289 {
290 /* Construct an expanded filename for the directory entry.
291 Use the decoded names for input to Ffile_attributes. */
292 Lisp_Object decoded_fullname, fileattrs;
293 struct gcpro gcpro1, gcpro2;
294
295 decoded_fullname = fileattrs = Qnil;
296 GCPRO2 (decoded_fullname, fileattrs);
297
298 /* Both Fexpand_file_name and Ffile_attributes can GC. */
299 decoded_fullname = Fexpand_file_name (name, directory);
300 fileattrs = Ffile_attributes (decoded_fullname, id_format);
301
302 list = Fcons (Fcons (finalname, fileattrs), list);
303 UNGCPRO;
304 }
305 else
306 list = Fcons (finalname, list);
307 } 259 }
260 else
261 finalname = name;
308 262
309 UNGCPRO; 263 if (attrs)
264 {
265 /* Construct an expanded filename for the directory entry.
266 Use the decoded names for input to Ffile_attributes. */
267 Lisp_Object decoded_fullname, fileattrs;
268 struct gcpro gcpro1, gcpro2;
269
270 decoded_fullname = fileattrs = Qnil;
271 GCPRO2 (decoded_fullname, fileattrs);
272
273 /* Both Fexpand_file_name and Ffile_attributes can GC. */
274 decoded_fullname = Fexpand_file_name (name, directory);
275 fileattrs = Ffile_attributes (decoded_fullname, id_format);
276
277 list = Fcons (Fcons (finalname, fileattrs), list);
278 UNGCPRO;
279 }
280 else
281 list = Fcons (finalname, list);
310 } 282 }
283
284 UNGCPRO;
311 } 285 }
312 286
313 block_input (); 287 block_input ();
@@ -442,7 +416,8 @@ These are all file names in directory DIRECTORY which begin with FILE. */)
442 return file_name_completion (file, directory, 1, Qnil); 416 return file_name_completion (file, directory, 1, Qnil);
443} 417}
444 418
445static int file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr); 419static int file_name_completion_stat (Lisp_Object dirname, struct dirent *dp,
420 struct stat *st_addr);
446static Lisp_Object Qdefault_directory; 421static Lisp_Object Qdefault_directory;
447 422
448static Lisp_Object 423static Lisp_Object
@@ -499,7 +474,7 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
499 /* (att3b compiler bug requires do a null comparison this way) */ 474 /* (att3b compiler bug requires do a null comparison this way) */
500 while (1) 475 while (1)
501 { 476 {
502 DIRENTRY *dp; 477 struct dirent *dp;
503 ptrdiff_t len; 478 ptrdiff_t len;
504 bool canexclude = 0; 479 bool canexclude = 0;
505 480
@@ -517,11 +492,10 @@ file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
517 492
518 if (!dp) break; 493 if (!dp) break;
519 494
520 len = NAMLEN (dp); 495 len = dirent_namelen (dp);
521 496
522 QUIT; 497 QUIT;
523 if (! DIRENTRY_NONEMPTY (dp) 498 if (len < SCHARS (encoded_file)
524 || len < SCHARS (encoded_file)
525 || 0 <= scmp (dp->d_name, SSDATA (encoded_file), 499 || 0 <= scmp (dp->d_name, SSDATA (encoded_file),
526 SCHARS (encoded_file))) 500 SCHARS (encoded_file)))
527 continue; 501 continue;
@@ -806,9 +780,10 @@ scmp (const char *s1, const char *s2, ptrdiff_t len)
806} 780}
807 781
808static int 782static int
809file_name_completion_stat (Lisp_Object dirname, DIRENTRY *dp, struct stat *st_addr) 783file_name_completion_stat (Lisp_Object dirname, struct dirent *dp,
784 struct stat *st_addr)
810{ 785{
811 ptrdiff_t len = NAMLEN (dp); 786 ptrdiff_t len = dirent_namelen (dp);
812 ptrdiff_t pos = SCHARS (dirname); 787 ptrdiff_t pos = SCHARS (dirname);
813 int value; 788 int value;
814 USE_SAFE_ALLOCA; 789 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 \
413 $(MS_W32_H) 413 $(MS_W32_H)
414CONFIG_H = $(SRC)/config.h \ 414CONFIG_H = $(SRC)/config.h \
415 $(CONF_POST_H) 415 $(CONF_POST_H)
416DIR_H = $(NT_INC)/sys/dir.h \
417 $(SRC)/ndir.h
418W32GUI_H = $(SRC)/w32gui.h \ 416W32GUI_H = $(SRC)/w32gui.h \
419 $(SYSTIME_H) 417 $(SYSTIME_H)
420DISPEXTERN_H = $(SRC)/dispextern.h \ 418DISPEXTERN_H = $(SRC)/dispextern.h \
@@ -714,6 +712,7 @@ $(BLD)/dired.$(O) : \
714 $(SRC)/blockinput.h \ 712 $(SRC)/blockinput.h \
715 $(SRC)/commands.h \ 713 $(SRC)/commands.h \
716 $(SRC)/regex.h \ 714 $(SRC)/regex.h \
715 $(NT_INC)/dirent.h \
717 $(NT_INC)/pwd.h \ 716 $(NT_INC)/pwd.h \
718 $(NT_INC)/sys/stat.h \ 717 $(NT_INC)/sys/stat.h \
719 $(NT_INC)/unistd.h \ 718 $(NT_INC)/unistd.h \
@@ -722,7 +721,6 @@ $(BLD)/dired.$(O) : \
722 $(CHARSET_H) \ 721 $(CHARSET_H) \
723 $(CODING_H) \ 722 $(CODING_H) \
724 $(CONFIG_H) \ 723 $(CONFIG_H) \
725 $(DIR_H) \
726 $(FILEMODE_H) \ 724 $(FILEMODE_H) \
727 $(GRP_H) \ 725 $(GRP_H) \
728 $(LISP_H) \ 726 $(LISP_H) \
@@ -1175,11 +1173,11 @@ $(BLD)/minibuf.$(O) : \
1175 1173
1176$(BLD)/w32.$(O) : \ 1174$(BLD)/w32.$(O) : \
1177 $(SRC)/w32.c \ 1175 $(SRC)/w32.c \
1178 $(SRC)/ndir.h \
1179 $(SRC)/w32.h \ 1176 $(SRC)/w32.h \
1180 $(SRC)/w32common.h \ 1177 $(SRC)/w32common.h \
1181 $(SRC)/w32heap.h \ 1178 $(SRC)/w32heap.h \
1182 $(SRC)/w32select.h \ 1179 $(SRC)/w32select.h \
1180 $(NT_INC)/dirent.h \
1183 $(NT_INC)/pwd.h \ 1181 $(NT_INC)/pwd.h \
1184 $(NT_INC)/sys/file.h \ 1182 $(NT_INC)/sys/file.h \
1185 $(NT_INC)/sys/time.h \ 1183 $(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 @@
1/*
2 <dir.h> -- definitions for 4.2BSD-compatible directory access
3
4 last edit: 09-Jul-1983 D A Gwyn
5
6 * The code here is forced by the interface, and is not subject to
7 * copyright, constituting the only possible expression of the
8 * algorithm in this format.
9 */
10
11#define DIRBLKSIZ 512 /* size of directory block */
12#ifdef WINDOWSNT
13#define MAXNAMLEN 255
14#else /* not WINDOWSNT */
15#define MAXNAMLEN 15 /* maximum filename length */
16#endif /* not WINDOWSNT */
17 /* NOTE: MAXNAMLEN must be one less than a multiple of 4 */
18
19struct direct /* data from readdir() */
20 {
21 long d_ino; /* inode number of entry */
22 unsigned short d_reclen; /* length of this record */
23 unsigned short d_namlen; /* length of string in d_name */
24 char d_name[MAXNAMLEN+1]; /* name of file */
25 };
26
27typedef struct
28 {
29 int dd_fd; /* file descriptor */
30 int dd_loc; /* offset in block */
31 int dd_size; /* amount of valid data */
32 char dd_buf[DIRBLKSIZ]; /* directory block */
33 } DIR; /* stream data from opendir() */
34
35extern DIR *opendir (char *);
36extern struct direct *readdir (DIR *);
37extern void seekdir (DIR *, long);
38extern void closedir (DIR *);
39
40#define rewinddir( dirp ) seekdir( dirp, 0L )
41
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])
2220 &emacs_norealloc_allocator, careadlinkatcwd); 2220 &emacs_norealloc_allocator, careadlinkatcwd);
2221} 2221}
2222 2222
2223/* Directory routines for systems that don't have them. */
2224
2225#ifdef HAVE_DIRENT_H
2226
2227#include <dirent.h>
2228
2229#if !defined (HAVE_CLOSEDIR)
2230
2231int
2232closedir (DIR *dirp /* stream from opendir */)
2233{
2234 int rtnval;
2235
2236 rtnval = emacs_close (dirp->dd_fd);
2237 xfree (dirp);
2238
2239 return rtnval;
2240}
2241#endif /* not HAVE_CLOSEDIR */
2242#endif /* HAVE_DIRENT_H */
2243
2244
2245/* Return a struct timeval that is roughly equivalent to T. 2223/* Return a struct timeval that is roughly equivalent to T.
2246 Use the least timeval not less than T. 2224 Use the least timeval not less than T.
2247 Return an extremal value if the result would overflow. */ 2225 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 {
179#undef sendto 179#undef sendto
180 180
181#include "w32.h" 181#include "w32.h"
182#include "ndir.h" 182#include <dirent.h>
183#include "w32common.h" 183#include "w32common.h"
184#include "w32heap.h" 184#include "w32heap.h"
185#include "w32select.h" 185#include "w32select.h"
@@ -2448,7 +2448,7 @@ is_exec (const char * name)
2448 and readdir. We can't use the procedures supplied in sysdep.c, 2448 and readdir. We can't use the procedures supplied in sysdep.c,
2449 so we provide them here. */ 2449 so we provide them here. */
2450 2450
2451struct direct dir_static; /* simulated directory contents */ 2451struct dirent dir_static; /* simulated directory contents */
2452static HANDLE dir_find_handle = INVALID_HANDLE_VALUE; 2452static HANDLE dir_find_handle = INVALID_HANDLE_VALUE;
2453static int dir_is_fat; 2453static int dir_is_fat;
2454static char dir_pathname[MAXPATHLEN+1]; 2454static char dir_pathname[MAXPATHLEN+1];
@@ -2518,7 +2518,7 @@ closedir (DIR *dirp)
2518 xfree ((char *) dirp); 2518 xfree ((char *) dirp);
2519} 2519}
2520 2520
2521struct direct * 2521struct dirent *
2522readdir (DIR *dirp) 2522readdir (DIR *dirp)
2523{ 2523{
2524 int downcase = !NILP (Vw32_downcase_file_names); 2524 int downcase = !NILP (Vw32_downcase_file_names);
@@ -2572,7 +2572,7 @@ readdir (DIR *dirp)
2572 downcase = 1; /* 8+3 aliases are returned in all caps */ 2572 downcase = 1; /* 8+3 aliases are returned in all caps */
2573 } 2573 }
2574 dir_static.d_namlen = strlen (dir_static.d_name); 2574 dir_static.d_namlen = strlen (dir_static.d_name);
2575 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3 + 2575 dir_static.d_reclen = sizeof (struct dirent) - MAXNAMLEN + 3 +
2576 dir_static.d_namlen - dir_static.d_namlen % 4; 2576 dir_static.d_namlen - dir_static.d_namlen % 4;
2577 2577
2578 /* If the file name in cFileName[] includes `?' characters, it means 2578 /* If the file name in cFileName[] includes `?' characters, it means