Fix permissions bugs with setgid directories etc.
[bpt/emacs.git] / src / dired.c
CommitLineData
14d55bce 1/* Lisp functions for making directory listings.
acaf905b 2 Copyright (C) 1985-1986, 1993-1994, 1999-2012 Free Software Foundation, Inc.
14d55bce
RS
3
4This file is part of GNU Emacs.
5
9ec0b715 6GNU Emacs is free software: you can redistribute it and/or modify
14d55bce 7it under the terms of the GNU General Public License as published by
9ec0b715
GM
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
14d55bce
RS
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
9ec0b715 17along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
14d55bce
RS
18
19
3964b9a7
RS
20#include <config.h>
21
14d55bce
RS
22#include <stdio.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25
5b9c0a1d 26#ifdef HAVE_PWD_H
6b61353c 27#include <pwd.h>
5b9c0a1d 28#endif
6b61353c 29#include <grp.h>
6b61353c 30
7cc9f69f 31#include <errno.h>
dfcf069d 32#include <unistd.h>
dfcf069d 33
14d55bce 34#include <dirent.h>
d209feed 35#include <filemode.h>
d35af63c 36#include <stat-time.h>
d209feed 37
14d55bce 38#include "lisp.h"
fa8459a3 39#include "systime.h"
e5560ff7 40#include "character.h"
14d55bce
RS
41#include "buffer.h"
42#include "commands.h"
bd33479f
KH
43#include "charset.h"
44#include "coding.h"
14d55bce 45#include "regex.h"
8c8a7c58 46#include "blockinput.h"
14d55bce 47
955cbe7b
PE
48static Lisp_Object Qdirectory_files;
49static Lisp_Object Qdirectory_files_and_attributes;
50static Lisp_Object Qfile_name_completion;
51static Lisp_Object Qfile_name_all_completions;
52static Lisp_Object Qfile_attributes;
53static Lisp_Object Qfile_attributes_lessp;
b3f04ced 54
d311d28c 55static ptrdiff_t scmp (const char *, const char *, ptrdiff_t);
14d55bce 56\f
95ef7787
PE
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
65156807
EZ
68#ifdef WINDOWSNT
69Lisp_Object
70directory_files_internal_w32_unwind (Lisp_Object arg)
71{
72 Vw32_get_true_file_attributes = arg;
73 return Qnil;
74}
75#endif
2488aba5 76
4a6bea26 77static Lisp_Object
971de7fb 78directory_files_internal_unwind (Lisp_Object dh)
2488aba5 79{
9d291bdf 80 DIR *d = (DIR *) XSAVE_VALUE (dh)->pointer;
4d7e6e51 81 block_input ();
2488aba5 82 closedir (d);
4d7e6e51 83 unblock_input ();
2488aba5
AI
84 return Qnil;
85}
86
177c0ea7 87/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
de1339b0
PE
88 If not ATTRS, return a list of directory filenames;
89 if ATTRS, return a list of directory filenames and their attributes.
6b61353c 90 In the latter case, ID_FORMAT is passed to Ffile_attributes. */
f69f9da1 91
4424b255 92Lisp_Object
de1339b0
PE
93directory_files_internal (Lisp_Object directory, Lisp_Object full,
94 Lisp_Object match, Lisp_Object nosort, bool attrs,
95 Lisp_Object id_format)
14d55bce
RS
96{
97 DIR *d;
d311d28c 98 ptrdiff_t directory_nbytes;
388ac098 99 Lisp_Object list, dirfilename, encoded_directory;
6bbd7a29 100 struct re_pattern_buffer *bufp = NULL;
de1339b0 101 bool needsep = 0;
d311d28c 102 ptrdiff_t count = SPECPDL_INDEX ();
388ac098 103 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
95ef7787 104 struct dirent *dp;
65156807
EZ
105#ifdef WINDOWSNT
106 Lisp_Object w32_save = Qnil;
107#endif
32f4334d 108
96d64004 109 /* Because of file name handlers, these functions might call
6155fae1 110 Ffuncall, and cause a GC. */
388ac098
GM
111 list = encoded_directory = dirfilename = Qnil;
112 GCPRO5 (match, directory, list, dirfilename, encoded_directory);
96d64004 113 dirfilename = Fdirectory_file_name (directory);
6155fae1 114
265a9e55 115 if (!NILP (match))
14d55bce 116 {
b7826503 117 CHECK_STRING (match);
ebb9e16f
JB
118
119 /* MATCH might be a flawed regular expression. Rather than
8e6208c5 120 catching and signaling our own errors, we just call
ebb9e16f 121 compile_pattern to do the work for us. */
c872c6b2
RS
122 /* Pass 1 for the MULTIBYTE arg
123 because we do make multibyte strings if the contents warrant. */
1a9fbabe
EZ
124# ifdef WINDOWSNT
125 /* Windows users want case-insensitive wildcards. */
126 bufp = compile_pattern (match, 0,
4b4deea2 127 BVAR (&buffer_defaults, case_canon_table), 0, 1);
1a9fbabe 128# else /* !WINDOWSNT */
3e937712 129 bufp = compile_pattern (match, 0, Qnil, 0, 1);
1a9fbabe 130# endif /* !WINDOWSNT */
14d55bce
RS
131 }
132
b3edfc9b 133 /* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
388ac098
GM
134 run_pre_post_conversion_on_str which calls Lisp directly and
135 indirectly. */
6c8b4f07
SM
136 if (STRING_MULTIBYTE (dirfilename))
137 dirfilename = ENCODE_FILE (dirfilename);
138 encoded_directory = (STRING_MULTIBYTE (directory)
139 ? ENCODE_FILE (directory) : directory);
24c2a54f 140
e50c66d3 141 /* Now *bufp is the compiled form of MATCH; don't call anything
6155fae1
JB
142 which might compile a new regexp until we're done with the loop! */
143
4d7e6e51 144 block_input ();
42a5b22f 145 d = opendir (SSDATA (dirfilename));
4d7e6e51 146 unblock_input ();
388ac098 147 if (d == NULL)
23bd240f 148 report_file_error ("Opening directory", Fcons (directory, Qnil));
14d55bce 149
2488aba5
AI
150 /* Unfortunately, we can now invoke expand-file-name and
151 file-attributes on filenames, both of which can throw, so we must
152 do a proper unwind-protect. */
153 record_unwind_protect (directory_files_internal_unwind,
9d291bdf 154 make_save_value (d, 0));
2488aba5 155
65156807
EZ
156#ifdef WINDOWSNT
157 if (attrs)
158 {
65156807
EZ
159 extern int is_slow_fs (const char *);
160
161 /* Do this only once to avoid doing it (in w32.c:stat) for each
162 file in the directory, when we call Ffile_attributes below. */
163 record_unwind_protect (directory_files_internal_w32_unwind,
164 Vw32_get_true_file_attributes);
165 w32_save = Vw32_get_true_file_attributes;
166 if (EQ (Vw32_get_true_file_attributes, Qlocal))
167 {
65156807
EZ
168 /* w32.c:stat will notice these bindings and avoid calling
169 GetDriveType for each file. */
b6046155 170 if (is_slow_fs (SDATA (dirfilename)))
65156807
EZ
171 Vw32_get_true_file_attributes = Qnil;
172 else
173 Vw32_get_true_file_attributes = Qt;
174 }
175 }
176#endif
177
d5db4077 178 directory_nbytes = SBYTES (directory);
c81a9bdc 179 re_match_object = Qt;
14d55bce 180
96d64004 181 /* Decide whether we need to add a directory separator. */
388ac098 182 if (directory_nbytes == 0
d5db4077 183 || !IS_ANY_SEP (SREF (directory, directory_nbytes - 1)))
96d64004 184 needsep = 1;
96d64004 185
8e42f043 186 /* Loop reading blocks until EOF or error. */
f69f9da1 187 for (;;)
14d55bce 188 {
95ef7787
PE
189 ptrdiff_t len;
190 bool wanted = 0;
191 Lisp_Object name, finalname;
192 struct gcpro gcpro1, gcpro2;
193
f69f9da1
GM
194 errno = 0;
195 dp = readdir (d);
22626a85
PE
196 if (!dp)
197 {
198 if (errno == EAGAIN || errno == EINTR)
199 {
200 QUIT;
201 continue;
202 }
203 break;
204 }
f69f9da1 205
95ef7787
PE
206 len = dirent_namelen (dp);
207 name = finalname = make_unibyte_string (dp->d_name, len);
208 GCPRO2 (finalname, name);
209
210 /* Note: DECODE_FILE can GC; it should protect its argument,
211 though. */
212 name = DECODE_FILE (name);
213 len = SBYTES (name);
214
215 /* Now that we have unwind_protect in place, we might as well
216 allow matching to be interrupted. */
217 immediate_quit = 1;
218 QUIT;
219
220 if (NILP (match)
221 || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0)))
222 wanted = 1;
223
224 immediate_quit = 0;
225
226 if (wanted)
14d55bce 227 {
95ef7787
PE
228 if (!NILP (full))
229 {
230 Lisp_Object fullname;
231 ptrdiff_t nbytes = len + directory_nbytes + needsep;
232 ptrdiff_t nchars;
e23f810c 233
95ef7787
PE
234 fullname = make_uninit_multibyte_string (nbytes, nbytes);
235 memcpy (SDATA (fullname), SDATA (directory),
236 directory_nbytes);
177c0ea7 237
95ef7787
PE
238 if (needsep)
239 SSET (fullname, directory_nbytes, DIRECTORY_SEP);
e23f810c 240
95ef7787
PE
241 memcpy (SDATA (fullname) + directory_nbytes + needsep,
242 SDATA (name), len);
2488aba5 243
95ef7787 244 nchars = chars_in_text (SDATA (fullname), nbytes);
2488aba5 245
95ef7787
PE
246 /* Some bug somewhere. */
247 if (nchars > nbytes)
248 emacs_abort ();
2488aba5 249
95ef7787
PE
250 STRING_SET_CHARS (fullname, nchars);
251 if (nchars == nbytes)
252 STRING_SET_UNIBYTE (fullname);
253
254 finalname = fullname;
14d55bce 255 }
95ef7787
PE
256 else
257 finalname = name;
388ac098 258
95ef7787
PE
259 if (attrs)
260 {
261 /* Construct an expanded filename for the directory entry.
262 Use the decoded names for input to Ffile_attributes. */
263 Lisp_Object decoded_fullname, fileattrs;
264 struct gcpro gcpro1, gcpro2;
265
266 decoded_fullname = fileattrs = Qnil;
267 GCPRO2 (decoded_fullname, fileattrs);
268
269 /* Both Fexpand_file_name and Ffile_attributes can GC. */
270 decoded_fullname = Fexpand_file_name (name, directory);
271 fileattrs = Ffile_attributes (decoded_fullname, id_format);
272
273 list = Fcons (Fcons (finalname, fileattrs), list);
274 UNGCPRO;
275 }
276 else
277 list = Fcons (finalname, list);
14d55bce 278 }
95ef7787
PE
279
280 UNGCPRO;
14d55bce 281 }
2488aba5 282
4d7e6e51 283 block_input ();
14d55bce 284 closedir (d);
4d7e6e51 285 unblock_input ();
65156807
EZ
286#ifdef WINDOWSNT
287 if (attrs)
288 Vw32_get_true_file_attributes = w32_save;
289#endif
2488aba5
AI
290
291 /* Discard the unwind protect. */
292 specpdl_ptr = specpdl + count;
293
388ac098
GM
294 if (NILP (nosort))
295 list = Fsort (Fnreverse (list),
296 attrs ? Qfile_attributes_lessp : Qstring_lessp);
177c0ea7 297
388ac098 298 RETURN_UNGCPRO (list);
14d55bce 299}
4424b255
GV
300
301
302DEFUN ("directory-files", Fdirectory_files, Sdirectory_files, 1, 4, 0,
335c5470
PJ
303 doc: /* Return a list of names of files in DIRECTORY.
304There are three optional arguments:
305If FULL is non-nil, return absolute file names. Otherwise return names
306 that are relative to the specified directory.
307If MATCH is non-nil, mention only file names that match the regexp MATCH.
308If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
a489517b
JB
309 Otherwise, the list returned is sorted with `string-lessp'.
310 NOSORT is useful if you plan to sort the result yourself. */)
5842a27b 311 (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort)
4424b255
GV
312{
313 Lisp_Object handler;
4ece81a6 314 directory = Fexpand_file_name (directory, Qnil);
4424b255
GV
315
316 /* If the file name has special constructs in it,
317 call the corresponding file handler. */
318 handler = Ffind_file_name_handler (directory, Qdirectory_files);
319 if (!NILP (handler))
6b61353c
KH
320 return call5 (handler, Qdirectory_files, directory,
321 full, match, nosort);
4424b255 322
6b61353c 323 return directory_files_internal (directory, full, match, nosort, 0, Qnil);
4424b255
GV
324}
325
335c5470 326DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes,
6b61353c 327 Sdirectory_files_and_attributes, 1, 5, 0,
335c5470 328 doc: /* Return a list of names of files and their attributes in DIRECTORY.
6b61353c 329There are four optional arguments:
335c5470
PJ
330If FULL is non-nil, return absolute file names. Otherwise return names
331 that are relative to the specified directory.
332If MATCH is non-nil, mention only file names that match the regexp MATCH.
333If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
6b61353c
KH
334 NOSORT is useful if you plan to sort the result yourself.
335ID-FORMAT specifies the preferred format of attributes uid and gid, see
6c5665e9
EZ
336`file-attributes' for further documentation.
337On MS-Windows, performance depends on `w32-get-true-file-attributes',
338which see. */)
5842a27b 339 (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort, Lisp_Object id_format)
4424b255
GV
340{
341 Lisp_Object handler;
4ece81a6 342 directory = Fexpand_file_name (directory, Qnil);
4424b255
GV
343
344 /* If the file name has special constructs in it,
345 call the corresponding file handler. */
346 handler = Ffind_file_name_handler (directory, Qdirectory_files_and_attributes);
347 if (!NILP (handler))
6b61353c
KH
348 return call6 (handler, Qdirectory_files_and_attributes,
349 directory, full, match, nosort, id_format);
4424b255 350
6b61353c 351 return directory_files_internal (directory, full, match, nosort, 1, id_format);
4424b255
GV
352}
353
14d55bce 354\f
de1339b0
PE
355static Lisp_Object file_name_completion (Lisp_Object, Lisp_Object, bool,
356 Lisp_Object);
14d55bce
RS
357
358DEFUN ("file-name-completion", Ffile_name_completion, Sfile_name_completion,
abfb1932 359 2, 3, 0,
335c5470
PJ
360 doc: /* Complete file name FILE in directory DIRECTORY.
361Returns the longest string
362common to all file names in DIRECTORY that start with FILE.
363If there is only one and FILE matches it exactly, returns t.
2f60660a 364Returns nil if DIRECTORY contains no name starting with FILE.
335c5470 365
b6ce54d6
RS
366If PREDICATE is non-nil, call PREDICATE with each possible
367completion (in absolute form) and ignore it if PREDICATE returns nil.
368
335c5470
PJ
369This function ignores some of the possible completions as
370determined by the variable `completion-ignored-extensions', which see. */)
5842a27b 371 (Lisp_Object file, Lisp_Object directory, Lisp_Object predicate)
14d55bce 372{
32f4334d 373 Lisp_Object handler;
32c1fffd 374 directory = Fexpand_file_name (directory, Qnil);
32f4334d 375
8436e231 376 /* If the directory name has special constructs in it,
32f4334d 377 call the corresponding file handler. */
23bd240f 378 handler = Ffind_file_name_handler (directory, Qfile_name_completion);
32f4334d 379 if (!NILP (handler))
abfb1932 380 return call4 (handler, Qfile_name_completion, file, directory, predicate);
32f4334d 381
8436e231
RS
382 /* If the file name has special constructs in it,
383 call the corresponding file handler. */
384 handler = Ffind_file_name_handler (file, Qfile_name_completion);
385 if (!NILP (handler))
abfb1932 386 return call4 (handler, Qfile_name_completion, file, directory, predicate);
8436e231 387
de1339b0 388 return file_name_completion (file, directory, 0, predicate);
14d55bce
RS
389}
390
391DEFUN ("file-name-all-completions", Ffile_name_all_completions,
335c5470
PJ
392 Sfile_name_all_completions, 2, 2, 0,
393 doc: /* Return a list of all completions of file name FILE in directory DIRECTORY.
394These are all file names in directory DIRECTORY which begin with FILE. */)
5842a27b 395 (Lisp_Object file, Lisp_Object directory)
14d55bce 396{
32f4334d 397 Lisp_Object handler;
32c1fffd 398 directory = Fexpand_file_name (directory, Qnil);
32f4334d 399
8436e231 400 /* If the directory name has special constructs in it,
32f4334d 401 call the corresponding file handler. */
23bd240f 402 handler = Ffind_file_name_handler (directory, Qfile_name_all_completions);
32f4334d 403 if (!NILP (handler))
23bd240f 404 return call3 (handler, Qfile_name_all_completions, file, directory);
32f4334d 405
8436e231
RS
406 /* If the file name has special constructs in it,
407 call the corresponding file handler. */
408 handler = Ffind_file_name_handler (file, Qfile_name_all_completions);
409 if (!NILP (handler))
23bd240f 410 return call3 (handler, Qfile_name_all_completions, file, directory);
8436e231 411
de1339b0 412 return file_name_completion (file, directory, 1, Qnil);
14d55bce
RS
413}
414
95ef7787
PE
415static int file_name_completion_stat (Lisp_Object dirname, struct dirent *dp,
416 struct stat *st_addr);
955cbe7b 417static Lisp_Object Qdefault_directory;
dfcf069d 418
16390cd2 419static Lisp_Object
de1339b0
PE
420file_name_completion (Lisp_Object file, Lisp_Object dirname, bool all_flag,
421 Lisp_Object predicate)
14d55bce
RS
422{
423 DIR *d;
d311d28c 424 ptrdiff_t bestmatchsize = 0;
14d55bce 425 int matchcount = 0;
abfb1932
RS
426 /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded.
427 If ALL_FLAG is 0, BESTMATCH is either nil
428 or the best match so far, not decoded. */
14d55bce 429 Lisp_Object bestmatch, tem, elt, name;
24c2a54f
RS
430 Lisp_Object encoded_file;
431 Lisp_Object encoded_dir;
14d55bce 432 struct stat st;
59ea14cd 433 bool directoryp;
de1339b0 434 /* If not INCLUDEALL, exclude files in completion-ignored-extensions as
3271a8f5
SM
435 well as "." and "..". Until shown otherwise, assume we can't exclude
436 anything. */
de1339b0 437 bool includeall = 1;
d311d28c 438 ptrdiff_t count = SPECPDL_INDEX ();
24c2a54f 439 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3fcc88cc 440
6bbd7a29
GM
441 elt = Qnil;
442
b7826503 443 CHECK_STRING (file);
14d55bce 444
14d55bce 445 bestmatch = Qnil;
24c2a54f
RS
446 encoded_file = encoded_dir = Qnil;
447 GCPRO5 (file, dirname, bestmatch, encoded_file, encoded_dir);
01bb4018 448 specbind (Qdefault_directory, dirname);
14d55bce 449
24c2a54f
RS
450 /* Do completion on the encoded file name
451 because the other names in the directory are (we presume)
452 encoded likewise. We decode the completed string at the end. */
2a54a229
SM
453 /* Actually, this is not quite true any more: we do most of the completion
454 work with decoded file names, but we still do some filtering based
455 on the encoded file name. */
6c8b4f07 456 encoded_file = STRING_MULTIBYTE (file) ? ENCODE_FILE (file) : file;
24c2a54f
RS
457
458 encoded_dir = ENCODE_FILE (dirname);
459
4d7e6e51 460 block_input ();
42a5b22f 461 d = opendir (SSDATA (Fdirectory_file_name (encoded_dir)));
4d7e6e51 462 unblock_input ();
3271a8f5
SM
463 if (!d)
464 report_file_error ("Opening directory", Fcons (dirname, Qnil));
14d55bce 465
3271a8f5
SM
466 record_unwind_protect (directory_files_internal_unwind,
467 make_save_value (d, 0));
14d55bce 468
3271a8f5
SM
469 /* Loop reading blocks */
470 /* (att3b compiler bug requires do a null comparison this way) */
471 while (1)
14d55bce 472 {
95ef7787 473 struct dirent *dp;
d311d28c 474 ptrdiff_t len;
de1339b0 475 bool canexclude = 0;
14d55bce 476
3271a8f5
SM
477 errno = 0;
478 dp = readdir (d);
22626a85
PE
479 if (!dp)
480 {
481 if (errno == EAGAIN || errno == EINTR)
482 {
483 QUIT;
484 continue;
485 }
486 break;
487 }
14d55bce 488
95ef7787 489 len = dirent_namelen (dp);
14d55bce 490
3271a8f5 491 QUIT;
95ef7787 492 if (len < SCHARS (encoded_file)
4f043d0f 493 || 0 <= scmp (dp->d_name, SSDATA (encoded_file),
3271a8f5
SM
494 SCHARS (encoded_file)))
495 continue;
14d55bce 496
3271a8f5
SM
497 if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
498 continue;
14d55bce 499
59ea14cd 500 directoryp = S_ISDIR (st.st_mode) != 0;
3271a8f5
SM
501 tem = Qnil;
502 /* If all_flag is set, always include all.
503 It would not actually be helpful to the user to ignore any possible
504 completions when making a list of them. */
505 if (!all_flag)
506 {
d311d28c 507 ptrdiff_t skip;
2cd298e2 508
7519c40d 509#if 0 /* FIXME: The `scmp' call compares an encoded and a decoded string. */
2cd298e2
SM
510 /* If this entry matches the current bestmatch, the only
511 thing it can do is increase matchcount, so don't bother
512 investigating it any further. */
513 if (!completion_ignore_case
514 /* The return result depends on whether it's the sole match. */
515 && matchcount > 1
516 && !includeall /* This match may allow includeall to 0. */
517 && len >= bestmatchsize
4f043d0f 518 && 0 > scmp (dp->d_name, SSDATA (bestmatch), bestmatchsize))
2cd298e2 519 continue;
7519c40d 520#endif
2cd298e2 521
3271a8f5 522 if (directoryp)
ad456ad4
RS
523 {
524#ifndef TRIVIAL_DIRECTORY_ENTRY
525#define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
526#endif
abfb1932
RS
527 /* "." and ".." are never interesting as completions, and are
528 actually in the way in a directory with only one file. */
3271a8f5
SM
529 if (TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
530 canexclude = 1;
531 else if (len > SCHARS (encoded_file))
d013f29b
EZ
532 /* Ignore directories if they match an element of
533 completion-ignored-extensions which ends in a slash. */
534 for (tem = Vcompletion_ignored_extensions;
535 CONSP (tem); tem = XCDR (tem))
536 {
d311d28c 537 ptrdiff_t elt_len;
4f043d0f 538 char *p1;
d013f29b
EZ
539
540 elt = XCAR (tem);
541 if (!STRINGP (elt))
542 continue;
a74aaa9d
EZ
543 /* Need to encode ELT, since scmp compares unibyte
544 strings only. */
545 elt = ENCODE_FILE (elt);
d5db4077 546 elt_len = SCHARS (elt) - 1; /* -1 for trailing / */
7a8d465a 547 if (elt_len <= 0)
d013f29b 548 continue;
4f043d0f 549 p1 = SSDATA (elt);
d013f29b
EZ
550 if (p1[elt_len] != '/')
551 continue;
552 skip = len - elt_len;
553 if (skip < 0)
554 continue;
555
556 if (0 <= scmp (dp->d_name + skip, p1, elt_len))
557 continue;
558 break;
559 }
ad456ad4
RS
560 }
561 else
3271a8f5 562 {
14d55bce
RS
563 /* Compare extensions-to-be-ignored against end of this file name */
564 /* if name is not an exact match against specified string */
3271a8f5 565 if (len > SCHARS (encoded_file))
14d55bce
RS
566 /* and exit this for loop if a match is found */
567 for (tem = Vcompletion_ignored_extensions;
70949dac 568 CONSP (tem); tem = XCDR (tem))
14d55bce 569 {
70949dac 570 elt = XCAR (tem);
88cf1852 571 if (!STRINGP (elt)) continue;
a74aaa9d
EZ
572 /* Need to encode ELT, since scmp compares unibyte
573 strings only. */
574 elt = ENCODE_FILE (elt);
d5db4077 575 skip = len - SCHARS (elt);
14d55bce
RS
576 if (skip < 0) continue;
577
578 if (0 <= scmp (dp->d_name + skip,
4f043d0f 579 SSDATA (elt),
d5db4077 580 SCHARS (elt)))
14d55bce
RS
581 continue;
582 break;
583 }
584 }
585
f676868d
KH
586 /* If an ignored-extensions match was found,
587 don't process this name as a completion. */
3271a8f5
SM
588 if (CONSP (tem))
589 canexclude = 1;
f676868d 590
3271a8f5
SM
591 if (!includeall && canexclude)
592 /* We're not including all files and this file can be excluded. */
593 continue;
9c691c00 594
3271a8f5
SM
595 if (includeall && !canexclude)
596 { /* If we have one non-excludable file, we want to exclude the
4c36be58 597 excludable files. */
3271a8f5
SM
598 includeall = 0;
599 /* Throw away any previous excludable match found. */
600 bestmatch = Qnil;
601 bestmatchsize = 0;
602 matchcount = 0;
f676868d 603 }
3271a8f5
SM
604 }
605 /* FIXME: If we move this `decode' earlier we can eliminate
606 the repeated ENCODE_FILE on Vcompletion_ignored_extensions. */
607 name = make_unibyte_string (dp->d_name, len);
608 name = DECODE_FILE (name);
609
610 {
611 Lisp_Object regexps;
3271a8f5
SM
612
613 /* Ignore this element if it fails to match all the regexps. */
cc524e3b
CY
614 if (completion_ignore_case)
615 {
616 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
617 regexps = XCDR (regexps))
618 if (fast_string_match_ignore_case (XCAR (regexps), name) < 0)
619 break;
620 }
621 else
622 {
623 for (regexps = Vcompletion_regexp_list; CONSP (regexps);
624 regexps = XCDR (regexps))
625 if (fast_string_match (XCAR (regexps), name) < 0)
626 break;
627 }
628
3271a8f5
SM
629 if (CONSP (regexps))
630 continue;
631 }
632
633 /* This is a possible completion */
634 if (directoryp)
635 /* This completion is a directory; make it end with '/'. */
636 name = Ffile_name_as_directory (name);
637
638 /* Test the predicate, if any. */
639 if (!NILP (predicate))
640 {
641 Lisp_Object val;
dbf31225 642 struct gcpro gcpro1;
14d55bce 643
dbf31225 644 GCPRO1 (name);
3271a8f5 645 val = call1 (predicate, name);
dbf31225 646 UNGCPRO;
c4c52bb7 647
3271a8f5
SM
648 if (NILP (val))
649 continue;
650 }
abfb1932 651
3271a8f5 652 /* Suitably record this match. */
14d55bce 653
d311d28c 654 matchcount += matchcount <= 1;
f676868d 655
3271a8f5
SM
656 if (all_flag)
657 bestmatch = Fcons (name, bestmatch);
658 else if (NILP (bestmatch))
659 {
660 bestmatch = name;
661 bestmatchsize = SCHARS (name);
662 }
663 else
664 {
665 Lisp_Object zero = make_number (0);
666 /* FIXME: This is a copy of the code in Ftry_completion. */
d311d28c 667 ptrdiff_t compare = min (bestmatchsize, SCHARS (name));
38b2c076 668 Lisp_Object cmp
3271a8f5
SM
669 = Fcompare_strings (bestmatch, zero,
670 make_number (compare),
671 name, zero,
672 make_number (compare),
673 completion_ignore_case ? Qt : Qnil);
d311d28c 674 ptrdiff_t matchsize
38b2c076
PE
675 = (EQ (cmp, Qt) ? compare
676 : XINT (cmp) < 0 ? - XINT (cmp) - 1
677 : XINT (cmp) - 1);
3271a8f5
SM
678
679 if (completion_ignore_case)
f676868d 680 {
3271a8f5
SM
681 /* If this is an exact match except for case,
682 use it as the best match rather than one that is not
683 an exact match. This way, we get the case pattern
684 of the actual match. */
685 /* This tests that the current file is an exact match
686 but BESTMATCH is not (it is too long). */
687 if ((matchsize == SCHARS (name)
59ea14cd 688 && matchsize + directoryp < SCHARS (bestmatch))
3271a8f5
SM
689 ||
690 /* If there is no exact match ignoring case,
691 prefer a match that does not change the case
692 of the input. */
693 /* If there is more than one exact match aside from
694 case, and one of them is exact including case,
695 prefer that one. */
696 /* This == checks that, of current file and BESTMATCH,
697 either both or neither are exact. */
698 (((matchsize == SCHARS (name))
699 ==
59ea14cd 700 (matchsize + directoryp == SCHARS (bestmatch)))
38b2c076 701 && (cmp = Fcompare_strings (name, zero,
3271a8f5
SM
702 make_number (SCHARS (file)),
703 file, zero,
704 Qnil,
705 Qnil),
38b2c076
PE
706 EQ (Qt, cmp))
707 && (cmp = Fcompare_strings (bestmatch, zero,
3271a8f5
SM
708 make_number (SCHARS (file)),
709 file, zero,
710 Qnil,
711 Qnil),
38b2c076 712 ! EQ (Qt, cmp))))
3271a8f5 713 bestmatch = name;
14d55bce 714 }
3271a8f5 715 bestmatchsize = matchsize;
2cd298e2
SM
716
717 /* If the best completion so far is reduced to the string
718 we're trying to complete, then we already know there's no
719 other completion, so there's no point looking any further. */
720 if (matchsize <= SCHARS (file)
721 && !includeall /* A future match may allow includeall to 0. */
722 /* If completion-ignore-case is non-nil, don't
723 short-circuit because we want to find the best
724 possible match *including* case differences. */
725 && (!completion_ignore_case || matchsize == 0)
726 /* The return value depends on whether it's the sole match. */
727 && matchcount > 1)
728 break;
729
14d55bce 730 }
14d55bce
RS
731 }
732
3fcc88cc 733 UNGCPRO;
3271a8f5 734 /* This closes the directory. */
c3a3229c 735 bestmatch = unbind_to (count, bestmatch);
14d55bce 736
265a9e55 737 if (all_flag || NILP (bestmatch))
2a54a229 738 return bestmatch;
928b5acc
SM
739 /* Return t if the supplied string is an exact match (counting case);
740 it does not require any change to be made. */
741 if (matchcount == 1 && !NILP (Fequal (bestmatch, file)))
14d55bce 742 return Qt;
24c2a54f
RS
743 bestmatch = Fsubstring (bestmatch, make_number (0),
744 make_number (bestmatchsize));
24c2a54f 745 return bestmatch;
14d55bce
RS
746}
747
b3f04ced
RS
748/* Compare exactly LEN chars of strings at S1 and S2,
749 ignoring case if appropriate.
750 Return -1 if strings match,
751 else number of chars that match at the beginning. */
752
d311d28c
PE
753static ptrdiff_t
754scmp (const char *s1, const char *s2, ptrdiff_t len)
b3f04ced 755{
d311d28c 756 register ptrdiff_t l = len;
b3f04ced
RS
757
758 if (completion_ignore_case)
759 {
4f043d0f 760 while (l
5da9919f
PE
761 && (downcase ((unsigned char) *s1++)
762 == downcase ((unsigned char) *s2++)))
b3f04ced
RS
763 l--;
764 }
765 else
766 {
767 while (l && *s1++ == *s2++)
768 l--;
769 }
770 if (l == 0)
771 return -1;
772 else
773 return len - l;
774}
775
dfcf069d 776static int
95ef7787
PE
777file_name_completion_stat (Lisp_Object dirname, struct dirent *dp,
778 struct stat *st_addr)
14d55bce 779{
95ef7787 780 ptrdiff_t len = dirent_namelen (dp);
d311d28c 781 ptrdiff_t pos = SCHARS (dirname);
7e3cf34f 782 int value;
d311d28c 783 USE_SAFE_ALLOCA;
98c6f1e3 784 char *fullname = SAFE_ALLOCA (len + pos + 2);
14d55bce 785
04924ee3 786#ifdef MSDOS
04924ee3
RS
787 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
788 but aren't required here. Avoid computing the following fields:
789 st_inode, st_size and st_nlink for directories, and the execute bits
790 in st_mode for non-directory files with non-standard extensions. */
791
792 unsigned short save_djstat_flags = _djstat_flags;
793
794 _djstat_flags = _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
04924ee3
RS
795#endif /* MSDOS */
796
72af86bd 797 memcpy (fullname, SDATA (dirname), pos);
0b39d75d
RS
798 if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
799 fullname[pos++] = DIRECTORY_SEP;
14d55bce 800
72af86bd 801 memcpy (fullname + pos, dp->d_name, len);
14d55bce
RS
802 fullname[pos + len] = 0;
803
7e3cf34f
RS
804 /* We want to return success if a link points to a nonexistent file,
805 but we want to return the status for what the link points to,
806 in case it is a directory. */
807 value = lstat (fullname, st_addr);
f68c809d
PE
808 if (value == 0 && S_ISLNK (st_addr->st_mode))
809 stat (fullname, st_addr);
04924ee3 810#ifdef MSDOS
04924ee3 811 _djstat_flags = save_djstat_flags;
04924ee3 812#endif /* MSDOS */
d311d28c 813 SAFE_FREE ();
04924ee3 814 return value;
14d55bce
RS
815}
816\f
8aaaec6b
EZ
817static char *
818stat_uname (struct stat *st)
819{
820#ifdef WINDOWSNT
821 return st->st_uname;
822#else
350e0088 823 struct passwd *pw = getpwuid (st->st_uid);
8aaaec6b
EZ
824
825 if (pw)
826 return pw->pw_name;
827 else
828 return NULL;
829#endif
830}
831
832static char *
833stat_gname (struct stat *st)
834{
835#ifdef WINDOWSNT
836 return st->st_gname;
837#else
350e0088 838 struct group *gr = getgrgid (st->st_gid);
8aaaec6b
EZ
839
840 if (gr)
841 return gr->gr_name;
842 else
843 return NULL;
844#endif
845}
846
6b61353c 847DEFUN ("file-attributes", Ffile_attributes, Sfile_attributes, 1, 2, 0,
335c5470
PJ
848 doc: /* Return a list of attributes of file FILENAME.
849Value is nil if specified file cannot be opened.
6b61353c
KH
850
851ID-FORMAT specifies the preferred format of attributes uid and gid (see
e42cd1a7
JB
852below) - valid values are 'string and 'integer. The latter is the
853default, but we plan to change that, so you should specify a non-nil value
854for ID-FORMAT if you use the returned uid or gid.
6b61353c
KH
855
856Elements of the attribute list are:
335c5470
PJ
857 0. t for directory, string (name linked to) for symbolic link, or nil.
858 1. Number of links to file.
78e7d1fe
EZ
859 2. File uid as a string or a number. If a string value cannot be
860 looked up, a numeric value, either an integer or a float, is returned.
6b61353c 861 3. File gid, likewise.
d35af63c
PE
862 4. Last access time, as a list of integers (HIGH LOW USEC PSEC) in the
863 same style as (current-time).
e02131a2
EZ
864 (See a note below about access time on FAT-based filesystems.)
865 5. Last modification time, likewise. This is the time of the last
866 change to the file's contents.
867 6. Last status change time, likewise. This is the time of last change
868 to the file's attributes: owner and group, access mode bits, etc.
335c5470
PJ
869 7. Size in bytes.
870 This is a floating point number if the size is too large for an integer.
871 8. File modes, as a string of ten letters or dashes as in ls -l.
97976f9f 872 9. An unspecified value, present only for backward compatibility.
be44ca6c
PE
87310. inode number. If it is larger than what an Emacs integer can hold,
874 this is of the form (HIGH . LOW): first the high bits, then the low 16 bits.
875 If even HIGH is too large for an Emacs integer, this is instead of the form
876 (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits,
e02131a2
EZ
877 and finally the low 16 bits.
87811. Filesystem device number. If it is larger than what the Emacs
879 integer can hold, this is a cons cell, similar to the inode number.
880
881On most filesystems, the combination of the inode and the device
882number uniquely identifies the file.
6c5665e9
EZ
883
884On MS-Windows, performance depends on `w32-get-true-file-attributes',
21f73755
EZ
885which see.
886
887On some FAT-based filesystems, only the date of last access is recorded,
888so last access time will always be midnight of that day. */)
5842a27b 889 (Lisp_Object filename, Lisp_Object id_format)
14d55bce
RS
890{
891 Lisp_Object values[12];
24c2a54f 892 Lisp_Object encoded;
14d55bce 893 struct stat s;
5c207910 894 int lstat_result;
4ad89555
PE
895
896 /* An array to hold the mode string generated by filemodestring,
897 including its terminating space and null byte. */
898 char modes[sizeof "-rwxr-xr-x "];
899
32f4334d 900 Lisp_Object handler;
7435aef8 901 struct gcpro gcpro1;
51105b13 902 char *uname = NULL, *gname = NULL;
14d55bce
RS
903
904 filename = Fexpand_file_name (filename, Qnil);
32f4334d
RS
905
906 /* If the file name has special constructs in it,
907 call the corresponding file handler. */
a617e913 908 handler = Ffind_file_name_handler (filename, Qfile_attributes);
32f4334d 909 if (!NILP (handler))
6b61353c
KH
910 { /* Only pass the extra arg if it is used to help backward compatibility
911 with old file handlers which do not implement the new arg. --Stef */
912 if (NILP (id_format))
913 return call2 (handler, Qfile_attributes, filename);
914 else
915 return call3 (handler, Qfile_attributes, filename, id_format);
916 }
32f4334d 917
7435aef8 918 GCPRO1 (filename);
24c2a54f 919 encoded = ENCODE_FILE (filename);
7435aef8 920 UNGCPRO;
24c2a54f 921
5c207910
EZ
922#ifdef WINDOWSNT
923 /* We usually don't request accurate owner and group info, because
924 it can be very expensive on Windows to get that, and most callers
925 of 'lstat' don't need that. But here we do want that information
926 to be accurate. */
927 w32_stat_get_owner_group = 1;
928#endif
929
930 lstat_result = lstat (SSDATA (encoded), &s);
931
932#ifdef WINDOWSNT
933 w32_stat_get_owner_group = 0;
934#endif
935
936 if (lstat_result < 0)
14d55bce
RS
937 return Qnil;
938
8d40723d
PE
939 values[0] = (S_ISLNK (s.st_mode) ? Ffile_symlink_p (filename)
940 : S_ISDIR (s.st_mode) ? Qt : Qnil);
14d55bce 941 values[1] = make_number (s.st_nlink);
51105b13
EZ
942
943 if (!(NILP (id_format) || EQ (id_format, Qinteger)))
6b61353c 944 {
4d7e6e51 945 block_input ();
8aaaec6b 946 uname = stat_uname (&s);
8aaaec6b 947 gname = stat_gname (&s);
4d7e6e51 948 unblock_input ();
6b61353c 949 }
51105b13 950 if (uname)
80904120 951 values[2] = DECODE_SYSTEM (build_string (uname));
51105b13 952 else
58a12889 953 values[2] = make_fixnum_or_float (s.st_uid);
51105b13 954 if (gname)
80904120 955 values[3] = DECODE_SYSTEM (build_string (gname));
51105b13 956 else
58a12889 957 values[3] = make_fixnum_or_float (s.st_gid);
51105b13 958
d35af63c
PE
959 values[4] = make_lisp_time (get_stat_atime (&s));
960 values[5] = make_lisp_time (get_stat_mtime (&s));
961 values[6] = make_lisp_time (get_stat_ctime (&s));
83c77d31
PE
962
963 /* If the file size is a 4-byte type, assume that files of sizes in
964 the 2-4 GiB range wrap around to negative values, as this is a
965 common bug on older 32-bit platforms. */
966 if (sizeof (s.st_size) == 4)
967 values[7] = make_fixnum_or_float (s.st_size & 0xffffffffu);
968 else
969 values[7] = make_fixnum_or_float (s.st_size);
4bc12672 970
14d55bce
RS
971 filemodestring (&s, modes);
972 values[8] = make_string (modes, 10);
97976f9f 973 values[9] = Qt;
be44ca6c
PE
974 values[10] = INTEGER_TO_CONS (s.st_ino);
975 values[11] = INTEGER_TO_CONS (s.st_dev);
68c45bf0 976
5e617bc2 977 return Flist (sizeof (values) / sizeof (values[0]), values);
14d55bce 978}
4424b255
GV
979
980DEFUN ("file-attributes-lessp", Ffile_attributes_lessp, Sfile_attributes_lessp, 2, 2, 0,
335c5470
PJ
981 doc: /* Return t if first arg file attributes list is less than second.
982Comparison is in lexicographic order and case is significant. */)
5842a27b 983 (Lisp_Object f1, Lisp_Object f2)
4424b255
GV
984{
985 return Fstring_lessp (Fcar (f1), Fcar (f2));
986}
14d55bce 987\f
316411f0
DA
988
989DEFUN ("system-users", Fsystem_users, Ssystem_users, 0, 0, 0,
990 doc: /* Return a list of user names currently registered in the system.
e5a36063
GM
991If we don't know how to determine that on this platform, just
992return a list with one element, taken from `user-real-login-name'. */)
316411f0
DA
993 (void)
994{
995 Lisp_Object users = Qnil;
aba027e8 996#if defined HAVE_GETPWENT && defined HAVE_ENDPWENT
316411f0
DA
997 struct passwd *pw;
998
999 while ((pw = getpwent ()))
1000 users = Fcons (DECODE_SYSTEM (build_string (pw->pw_name)), users);
1001
1002 endpwent ();
1003#endif
1004 if (EQ (users, Qnil))
1005 /* At least current user is always known. */
1006 users = Fcons (Vuser_real_login_name, Qnil);
1007 return users;
1008}
1009
1010DEFUN ("system-groups", Fsystem_groups, Ssystem_groups, 0, 0, 0,
1011 doc: /* Return a list of user group names currently registered in the system.
1012The value may be nil if not supported on this platform. */)
1013 (void)
1014{
1015 Lisp_Object groups = Qnil;
aba027e8 1016#if defined HAVE_GETGRENT && defined HAVE_ENDGRENT
316411f0 1017 struct group *gr;
316411f0
DA
1018
1019 while ((gr = getgrent ()))
1020 groups = Fcons (DECODE_SYSTEM (build_string (gr->gr_name)), groups);
1021
1022 endgrent ();
1023#endif
1024 return groups;
1025}
1026
dfcf069d 1027void
971de7fb 1028syms_of_dired (void)
14d55bce 1029{
cd3520a4
JB
1030 DEFSYM (Qdirectory_files, "directory-files");
1031 DEFSYM (Qdirectory_files_and_attributes, "directory-files-and-attributes");
1032 DEFSYM (Qfile_name_completion, "file-name-completion");
1033 DEFSYM (Qfile_name_all_completions, "file-name-all-completions");
1034 DEFSYM (Qfile_attributes, "file-attributes");
1035 DEFSYM (Qfile_attributes_lessp, "file-attributes-lessp");
1036 DEFSYM (Qdefault_directory, "default-directory");
a2d3836c 1037
14d55bce 1038 defsubr (&Sdirectory_files);
4424b255 1039 defsubr (&Sdirectory_files_and_attributes);
14d55bce 1040 defsubr (&Sfile_name_completion);
14d55bce
RS
1041 defsubr (&Sfile_name_all_completions);
1042 defsubr (&Sfile_attributes);
4424b255 1043 defsubr (&Sfile_attributes_lessp);
316411f0
DA
1044 defsubr (&Ssystem_users);
1045 defsubr (&Ssystem_groups);
14d55bce 1046
29208e82 1047 DEFVAR_LISP ("completion-ignored-extensions", Vcompletion_ignored_extensions,
407a52c4
LT
1048 doc: /* Completion ignores file names ending in any string in this list.
1049It does not ignore them if all possible completions end in one of
1050these strings or when displaying a list of completions.
1051It ignores directory names if they match any string in this list which
1052ends in a slash. */);
14d55bce
RS
1053 Vcompletion_ignored_extensions = Qnil;
1054}