comparison src/dired.c @ 88155:d7ddb3e565de

sync with trunk
author Henrik Enberg <henrik.enberg@telia.com>
date Mon, 16 Jan 2006 00:03:54 +0000
parents 23a1cea22d13
children
comparison
equal deleted inserted replaced
88154:8ce476d3ba36 88155:d7ddb3e565de
1 /* Lisp functions for making directory listings. 1 /* Lisp functions for making directory listings.
2 Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001 2 Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001, 2002, 2003,
3 Free Software Foundation, Inc. 3 2004, 2005 Free Software Foundation, Inc.
4 4
5 This file is part of GNU Emacs. 5 This file is part of GNU Emacs.
6 6
7 GNU Emacs is free software; you can redistribute it and/or modify 7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to 18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02111-1307, USA. */ 20 Boston, MA 02110-1301, USA. */
21 21
22 22
23 #include <config.h> 23 #include <config.h>
24 24
25 #include <stdio.h> 25 #include <stdio.h>
26 #include <sys/types.h> 26 #include <sys/types.h>
27 #include <sys/stat.h> 27 #include <sys/stat.h>
28 28
29 #include "systime.h" 29 #ifdef HAVE_PWD_H
30 #include <pwd.h>
31 #endif
32 #ifndef VMS
33 #include <grp.h>
34 #endif
35
30 #include <errno.h> 36 #include <errno.h>
31 37
32 #ifdef VMS 38 #ifdef VMS
33 #include <string.h> 39 #include <string.h>
34 #include <rms.h> 40 #include <rms.h>
84 #else 90 #else
85 #define DIRENTRY_NONEMPTY(p) ((p)->d_ino) 91 #define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
86 #endif 92 #endif
87 93
88 #include "lisp.h" 94 #include "lisp.h"
95 #include "systime.h"
89 #include "buffer.h" 96 #include "buffer.h"
90 #include "commands.h" 97 #include "commands.h"
91 #include "charset.h" 98 #include "charset.h"
92 #include "coding.h" 99 #include "coding.h"
93 #include "regex.h" 100 #include "regex.h"
105 #define lstat stat 112 #define lstat stat
106 #endif 113 #endif
107 114
108 extern int completion_ignore_case; 115 extern int completion_ignore_case;
109 extern Lisp_Object Vcompletion_regexp_list; 116 extern Lisp_Object Vcompletion_regexp_list;
110 extern Lisp_Object Vfile_name_coding_system, Vdefault_file_name_coding_system;
111 117
112 Lisp_Object Vcompletion_ignored_extensions; 118 Lisp_Object Vcompletion_ignored_extensions;
113 Lisp_Object Qcompletion_ignore_case; 119 Lisp_Object Qcompletion_ignore_case;
114 Lisp_Object Qdirectory_files; 120 Lisp_Object Qdirectory_files;
115 Lisp_Object Qdirectory_files_and_attributes; 121 Lisp_Object Qdirectory_files_and_attributes;
123 129
124 Lisp_Object 130 Lisp_Object
125 directory_files_internal_unwind (dh) 131 directory_files_internal_unwind (dh)
126 Lisp_Object dh; 132 Lisp_Object dh;
127 { 133 {
128 DIR *d = (DIR *) ((XINT (XCAR (dh)) << 16) + XINT (XCDR (dh))); 134 DIR *d = (DIR *) XSAVE_VALUE (dh)->pointer;
129 closedir (d); 135 closedir (d);
130 return Qnil; 136 return Qnil;
131 } 137 }
132 138
133 /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes. 139 /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
134 When ATTRS is zero, return a list of directory filenames; when 140 When ATTRS is zero, return a list of directory filenames; when
135 non-zero, return a list of directory filenames and their attributes. */ 141 non-zero, return a list of directory filenames and their attributes.
142 In the latter case, ID_FORMAT is passed to Ffile_attributes. */
136 143
137 Lisp_Object 144 Lisp_Object
138 directory_files_internal (directory, full, match, nosort, attrs) 145 directory_files_internal (directory, full, match, nosort, attrs, id_format)
139 Lisp_Object directory, full, match, nosort; 146 Lisp_Object directory, full, match, nosort;
140 int attrs; 147 int attrs;
148 Lisp_Object id_format;
141 { 149 {
142 DIR *d; 150 DIR *d;
143 int directory_nbytes; 151 int directory_nbytes;
144 Lisp_Object list, dirfilename, encoded_directory; 152 Lisp_Object list, dirfilename, encoded_directory;
145 struct re_pattern_buffer *bufp = NULL; 153 struct re_pattern_buffer *bufp = NULL;
146 int needsep = 0; 154 int needsep = 0;
147 int count = SPECPDL_INDEX (); 155 int count = SPECPDL_INDEX ();
148 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 156 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
149 DIRENTRY *dp; 157 DIRENTRY *dp;
150 int retry_p;
151 158
152 /* Because of file name handlers, these functions might call 159 /* Because of file name handlers, these functions might call
153 Ffuncall, and cause a GC. */ 160 Ffuncall, and cause a GC. */
154 list = encoded_directory = dirfilename = Qnil; 161 list = encoded_directory = dirfilename = Qnil;
155 GCPRO5 (match, directory, list, dirfilename, encoded_directory); 162 GCPRO5 (match, directory, list, dirfilename, encoded_directory);
156 directory = Fexpand_file_name (directory, Qnil);
157 dirfilename = Fdirectory_file_name (directory); 163 dirfilename = Fdirectory_file_name (directory);
158 164
159 if (!NILP (match)) 165 if (!NILP (match))
160 { 166 {
161 CHECK_STRING (match); 167 CHECK_STRING (match);
180 encoded_directory = ENCODE_FILE (directory); 186 encoded_directory = ENCODE_FILE (directory);
181 187
182 /* Now *bufp is the compiled form of MATCH; don't call anything 188 /* Now *bufp is the compiled form of MATCH; don't call anything
183 which might compile a new regexp until we're done with the loop! */ 189 which might compile a new regexp until we're done with the loop! */
184 190
185 /* Do this opendir after anything which might signal an error; if
186 an error is signaled while the directory stream is open, we
187 have to make sure it gets closed, and setting up an
188 unwind_protect to do so would be a pain. */
189 retry:
190
191 d = opendir (SDATA (dirfilename)); 191 d = opendir (SDATA (dirfilename));
192 if (d == NULL) 192 if (d == NULL)
193 report_file_error ("Opening directory", Fcons (directory, Qnil)); 193 report_file_error ("Opening directory", Fcons (directory, Qnil));
194 194
195 /* Unfortunately, we can now invoke expand-file-name and 195 /* Unfortunately, we can now invoke expand-file-name and
196 file-attributes on filenames, both of which can throw, so we must 196 file-attributes on filenames, both of which can throw, so we must
197 do a proper unwind-protect. */ 197 do a proper unwind-protect. */
198 record_unwind_protect (directory_files_internal_unwind, 198 record_unwind_protect (directory_files_internal_unwind,
199 Fcons (make_number (((unsigned long) d) >> 16), 199 make_save_value (d, 0));
200 make_number (((unsigned long) d) & 0xffff)));
201 200
202 directory_nbytes = SBYTES (directory); 201 directory_nbytes = SBYTES (directory);
203 re_match_object = Qt; 202 re_match_object = Qt;
204 203
205 /* Decide whether we need to add a directory separator. */ 204 /* Decide whether we need to add a directory separator. */
213 for (;;) 212 for (;;)
214 { 213 {
215 errno = 0; 214 errno = 0;
216 dp = readdir (d); 215 dp = readdir (d);
217 216
217 if (dp == NULL && (0
218 #ifdef EAGAIN 218 #ifdef EAGAIN
219 if (dp == NULL && errno == EAGAIN) 219 || errno == EAGAIN
220 continue; 220 #endif
221 #endif 221 #ifdef EINTR
222 || errno == EINTR
223 #endif
224 ))
225 { QUIT; continue; }
222 226
223 if (dp == NULL) 227 if (dp == NULL)
224 break; 228 break;
225 229
226 if (DIRENTRY_NONEMPTY (dp)) 230 if (DIRENTRY_NONEMPTY (dp))
294 decoded_fullname = fileattrs = Qnil; 298 decoded_fullname = fileattrs = Qnil;
295 GCPRO2 (decoded_fullname, fileattrs); 299 GCPRO2 (decoded_fullname, fileattrs);
296 300
297 /* Both Fexpand_file_name and Ffile_attributes can GC. */ 301 /* Both Fexpand_file_name and Ffile_attributes can GC. */
298 decoded_fullname = Fexpand_file_name (name, directory); 302 decoded_fullname = Fexpand_file_name (name, directory);
299 fileattrs = Ffile_attributes (decoded_fullname); 303 fileattrs = Ffile_attributes (decoded_fullname, id_format);
300 304
301 list = Fcons (Fcons (finalname, fileattrs), list); 305 list = Fcons (Fcons (finalname, fileattrs), list);
302 UNGCPRO; 306 UNGCPRO;
303 } 307 }
304 else 308 else
307 311
308 UNGCPRO; 312 UNGCPRO;
309 } 313 }
310 } 314 }
311 315
312 retry_p = 0;
313 #ifdef EINTR
314 retry_p |= errno == EINTR;
315 #endif
316
317 closedir (d); 316 closedir (d);
318 317
319 /* Discard the unwind protect. */ 318 /* Discard the unwind protect. */
320 specpdl_ptr = specpdl + count; 319 specpdl_ptr = specpdl + count;
321
322 if (retry_p)
323 {
324 list = Qnil;
325 goto retry;
326 }
327 320
328 if (NILP (nosort)) 321 if (NILP (nosort))
329 list = Fsort (Fnreverse (list), 322 list = Fsort (Fnreverse (list),
330 attrs ? Qfile_attributes_lessp : Qstring_lessp); 323 attrs ? Qfile_attributes_lessp : Qstring_lessp);
331 324
343 NOSORT is useful if you plan to sort the result yourself. */) 336 NOSORT is useful if you plan to sort the result yourself. */)
344 (directory, full, match, nosort) 337 (directory, full, match, nosort)
345 Lisp_Object directory, full, match, nosort; 338 Lisp_Object directory, full, match, nosort;
346 { 339 {
347 Lisp_Object handler; 340 Lisp_Object handler;
341 directory = Fexpand_file_name (directory, Qnil);
348 342
349 /* If the file name has special constructs in it, 343 /* If the file name has special constructs in it,
350 call the corresponding file handler. */ 344 call the corresponding file handler. */
351 handler = Ffind_file_name_handler (directory, Qdirectory_files); 345 handler = Ffind_file_name_handler (directory, Qdirectory_files);
352 if (!NILP (handler)) 346 if (!NILP (handler))
353 { 347 return call5 (handler, Qdirectory_files, directory,
354 Lisp_Object args[6]; 348 full, match, nosort);
355 349
356 args[0] = handler; 350 return directory_files_internal (directory, full, match, nosort, 0, Qnil);
357 args[1] = Qdirectory_files;
358 args[2] = directory;
359 args[3] = full;
360 args[4] = match;
361 args[5] = nosort;
362 return Ffuncall (6, args);
363 }
364
365 return directory_files_internal (directory, full, match, nosort, 0);
366 } 351 }
367 352
368 DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes, 353 DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes,
369 Sdirectory_files_and_attributes, 1, 4, 0, 354 Sdirectory_files_and_attributes, 1, 5, 0,
370 doc: /* Return a list of names of files and their attributes in DIRECTORY. 355 doc: /* Return a list of names of files and their attributes in DIRECTORY.
371 There are three optional arguments: 356 There are four optional arguments:
372 If FULL is non-nil, return absolute file names. Otherwise return names 357 If FULL is non-nil, return absolute file names. Otherwise return names
373 that are relative to the specified directory. 358 that are relative to the specified directory.
374 If MATCH is non-nil, mention only file names that match the regexp MATCH. 359 If MATCH is non-nil, mention only file names that match the regexp MATCH.
375 If NOSORT is non-nil, the list is not sorted--its order is unpredictable. 360 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
376 NOSORT is useful if you plan to sort the result yourself. */) 361 NOSORT is useful if you plan to sort the result yourself.
377 (directory, full, match, nosort) 362 ID-FORMAT specifies the preferred format of attributes uid and gid, see
378 Lisp_Object directory, full, match, nosort; 363 `file-attributes' for further documentation. */)
364 (directory, full, match, nosort, id_format)
365 Lisp_Object directory, full, match, nosort, id_format;
379 { 366 {
380 Lisp_Object handler; 367 Lisp_Object handler;
368 directory = Fexpand_file_name (directory, Qnil);
381 369
382 /* If the file name has special constructs in it, 370 /* If the file name has special constructs in it,
383 call the corresponding file handler. */ 371 call the corresponding file handler. */
384 handler = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes); 372 handler = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes);
385 if (!NILP (handler)) 373 if (!NILP (handler))
386 { 374 return call6 (handler, Qdirectory_files_and_attributes,
387 Lisp_Object args[6]; 375 directory, full, match, nosort, id_format);
388 376
389 args[0] = handler; 377 return directory_files_internal (directory, full, match, nosort, 1, id_format);
390 args[1] = Qdirectory_files_and_attributes;
391 args[2] = directory;
392 args[3] = full;
393 args[4] = match;
394 args[5] = nosort;
395 return Ffuncall (6, args);
396 }
397
398 return directory_files_internal (directory, full, match, nosort, 1);
399 } 378 }
400 379
401 380
402 Lisp_Object file_name_completion (); 381 Lisp_Object file_name_completion ();
403 382
405 2, 2, 0, 384 2, 2, 0,
406 doc: /* Complete file name FILE in directory DIRECTORY. 385 doc: /* Complete file name FILE in directory DIRECTORY.
407 Returns the longest string 386 Returns the longest string
408 common to all file names in DIRECTORY that start with FILE. 387 common to all file names in DIRECTORY that start with FILE.
409 If there is only one and FILE matches it exactly, returns t. 388 If there is only one and FILE matches it exactly, returns t.
410 Returns nil if DIR contains no name starting with FILE. 389 Returns nil if DIRECTORY contains no name starting with FILE.
411 390
412 This function ignores some of the possible completions as 391 This function ignores some of the possible completions as
413 determined by the variable `completion-ignored-extensions', which see. */) 392 determined by the variable `completion-ignored-extensions', which see. */)
414 (file, directory) 393 (file, directory)
415 Lisp_Object file, directory; 394 Lisp_Object file, directory;
524 d = opendir (SDATA (Fdirectory_file_name (encoded_dir))); 503 d = opendir (SDATA (Fdirectory_file_name (encoded_dir)));
525 if (!d) 504 if (!d)
526 report_file_error ("Opening directory", Fcons (dirname, Qnil)); 505 report_file_error ("Opening directory", Fcons (dirname, Qnil));
527 506
528 record_unwind_protect (directory_files_internal_unwind, 507 record_unwind_protect (directory_files_internal_unwind,
529 Fcons (make_number (((unsigned long) d) >> 16), 508 make_save_value (d, 0));
530 make_number (((unsigned long) d) & 0xffff)));
531 509
532 /* Loop reading blocks */ 510 /* Loop reading blocks */
533 /* (att3b compiler bug requires do a null comparison this way) */ 511 /* (att3b compiler bug requires do a null comparison this way) */
534 while (1) 512 while (1)
535 { 513 {
537 int len; 515 int len;
538 516
539 #ifdef VMS 517 #ifdef VMS
540 dp = (*readfunc) (d); 518 dp = (*readfunc) (d);
541 #else 519 #else
520 errno = 0;
542 dp = readdir (d); 521 dp = readdir (d);
543 #endif 522 if (dp == NULL && (0
523 # ifdef EAGAIN
524 || errno == EAGAIN
525 # endif
526 # ifdef EINTR
527 || errno == EINTR
528 # endif
529 ))
530 { QUIT; continue; }
531 #endif
532
544 if (!dp) break; 533 if (!dp) break;
545 534
546 len = NAMLEN (dp); 535 len = NAMLEN (dp);
547 536
548 QUIT; 537 QUIT;
869 { 858 {
870 return Fcons (make_number (time >> 16), 859 return Fcons (make_number (time >> 16),
871 Fcons (make_number (time & 0177777), Qnil)); 860 Fcons (make_number (time & 0177777), Qnil));
872 } 861 }
873 862
874 DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 1, 0, 863 DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 2, 0,
875 doc: /* Return a list of attributes of file FILENAME. 864 doc: /* Return a list of attributes of file FILENAME.
876 Value is nil if specified file cannot be opened. 865 Value is nil if specified file cannot be opened.
877 Otherwise, list elements are: 866
867 ID-FORMAT specifies the preferred format of attributes uid and gid (see
868 below) - valid values are 'string and 'integer. The latter is the default,
869 but we plan to change that, so you should specify a non-nil value for
870 ID-FORMAT if you use the returned uid or gid.
871
872 Elements of the attribute list are:
878 0. t for directory, string (name linked to) for symbolic link, or nil. 873 0. t for directory, string (name linked to) for symbolic link, or nil.
879 1. Number of links to file. 874 1. Number of links to file.
880 2. File uid. 875 2. File uid as a string or an integer. If a string value cannot be
881 3. File gid. 876 looked up, the integer value is returned.
877 3. File gid, likewise.
882 4. Last access time, as a list of two integers. 878 4. Last access time, as a list of two integers.
883 First integer has high-order 16 bits of time, second has low 16 bits. 879 First integer has high-order 16 bits of time, second has low 16 bits.
884 5. Last modification time, likewise. 880 5. Last modification time, likewise.
885 6. Last status change time, likewise. 881 6. Last status change time, likewise.
886 7. Size in bytes. 882 7. Size in bytes.
889 9. t iff file's gid would change if file were deleted and recreated. 885 9. t iff file's gid would change if file were deleted and recreated.
890 10. inode number. If inode number is larger than the Emacs integer, 886 10. inode number. If inode number is larger than the Emacs integer,
891 this is a cons cell containing two integers: first the high part, 887 this is a cons cell containing two integers: first the high part,
892 then the low 16 bits. 888 then the low 16 bits.
893 11. Device number. If it is larger than the Emacs integer, this is 889 11. Device number. If it is larger than the Emacs integer, this is
894 a cons cell, similar to the inode number. 890 a cons cell, similar to the inode number. */)
895 891 (filename, id_format)
896 If file does not exist, returns nil. */) 892 Lisp_Object filename, id_format;
897 (filename)
898 Lisp_Object filename;
899 { 893 {
900 Lisp_Object values[12]; 894 Lisp_Object values[12];
901 Lisp_Object encoded; 895 Lisp_Object encoded;
902 struct stat s; 896 struct stat s;
897 struct passwd *pw;
898 struct group *gr;
903 #if defined (BSD4_2) || defined (BSD4_3) 899 #if defined (BSD4_2) || defined (BSD4_3)
904 Lisp_Object dirname; 900 Lisp_Object dirname;
905 struct stat sdir; 901 struct stat sdir;
906 #endif 902 #endif
907 char modes[10]; 903 char modes[10];
908 Lisp_Object handler; 904 Lisp_Object handler;
905 struct gcpro gcpro1;
909 906
910 filename = Fexpand_file_name (filename, Qnil); 907 filename = Fexpand_file_name (filename, Qnil);
911 908
912 /* If the file name has special constructs in it, 909 /* If the file name has special constructs in it,
913 call the corresponding file handler. */ 910 call the corresponding file handler. */
914 handler = Ffind_file_name_handler (filename, Qfile_attributes); 911 handler = Ffind_file_name_handler (filename, Qfile_attributes);
915 if (!NILP (handler)) 912 if (!NILP (handler))
916 return call2 (handler, Qfile_attributes, filename); 913 { /* Only pass the extra arg if it is used to help backward compatibility
917 914 with old file handlers which do not implement the new arg. --Stef */
915 if (NILP (id_format))
916 return call2 (handler, Qfile_attributes, filename);
917 else
918 return call3 (handler, Qfile_attributes, filename, id_format);
919 }
920
921 GCPRO1 (filename);
918 encoded = ENCODE_FILE (filename); 922 encoded = ENCODE_FILE (filename);
923 UNGCPRO;
919 924
920 if (lstat (SDATA (encoded), &s) < 0) 925 if (lstat (SDATA (encoded), &s) < 0)
921 return Qnil; 926 return Qnil;
922 927
923 switch (s.st_mode & S_IFMT) 928 switch (s.st_mode & S_IFMT)
930 case S_IFLNK: 935 case S_IFLNK:
931 values[0] = Ffile_symlink_p (filename); break; 936 values[0] = Ffile_symlink_p (filename); break;
932 #endif 937 #endif
933 } 938 }
934 values[1] = make_number (s.st_nlink); 939 values[1] = make_number (s.st_nlink);
935 values[2] = make_number (s.st_uid); 940 if (NILP (id_format) || EQ (id_format, Qinteger))
936 values[3] = make_number (s.st_gid); 941 {
942 values[2] = make_number (s.st_uid);
943 values[3] = make_number (s.st_gid);
944 }
945 else
946 {
947 pw = (struct passwd *) getpwuid (s.st_uid);
948 values[2] = (pw ? build_string (pw->pw_name) : make_number (s.st_uid));
949 gr = (struct group *) getgrgid (s.st_gid);
950 values[3] = (gr ? build_string (gr->gr_name) : make_number (s.st_gid));
951 }
937 values[4] = make_time (s.st_atime); 952 values[4] = make_time (s.st_atime);
938 values[5] = make_time (s.st_mtime); 953 values[5] = make_time (s.st_mtime);
939 values[6] = make_time (s.st_ctime); 954 values[6] = make_time (s.st_ctime);
940 values[7] = make_number (s.st_size); 955 values[7] = make_number (s.st_size);
941 /* If the size is out of range for an integer, return a float. */ 956 /* If the size is out of range for an integer, return a float. */
1026 ends in a slash. 1041 ends in a slash.
1027 This variable does not affect lists of possible completions, 1042 This variable does not affect lists of possible completions,
1028 but does affect the commands that actually do completions. */); 1043 but does affect the commands that actually do completions. */);
1029 Vcompletion_ignored_extensions = Qnil; 1044 Vcompletion_ignored_extensions = Qnil;
1030 } 1045 }
1046
1047 /* arch-tag: 1ac8deca-4d8f-4d41-ade9-089154d98c03
1048 (do not change this comment) */