1 /* Lisp functions for making directory listings.
2 Copyright (C) 1985-1986, 1993-1994, 1999-2012 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23 #include <sys/types.h>
36 #include <stat-time.h>
40 #include "character.h"
46 #include "blockinput.h"
48 static Lisp_Object Qdirectory_files
;
49 static Lisp_Object Qdirectory_files_and_attributes
;
50 static Lisp_Object Qfile_name_completion
;
51 static Lisp_Object Qfile_name_all_completions
;
52 static Lisp_Object Qfile_attributes
;
53 static Lisp_Object Qfile_attributes_lessp
;
55 static ptrdiff_t scmp (const char *, const char *, ptrdiff_t);
57 /* Return the number of bytes in DP's name. */
59 dirent_namelen (struct dirent
*dp
)
61 #ifdef _D_EXACT_NAMLEN
62 return _D_EXACT_NAMLEN (dp
);
64 return strlen (dp
->d_name
);
70 directory_files_internal_w32_unwind (Lisp_Object arg
)
72 Vw32_get_true_file_attributes
= arg
;
78 directory_files_internal_unwind (Lisp_Object dh
)
80 DIR *d
= (DIR *) XSAVE_VALUE (dh
)->pointer
;
87 /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
88 If not ATTRS, return a list of directory filenames;
89 if ATTRS, return a list of directory filenames and their attributes.
90 In the latter case, ID_FORMAT is passed to Ffile_attributes. */
93 directory_files_internal (Lisp_Object directory
, Lisp_Object full
,
94 Lisp_Object match
, Lisp_Object nosort
, bool attrs
,
95 Lisp_Object id_format
)
98 ptrdiff_t directory_nbytes
;
99 Lisp_Object list
, dirfilename
, encoded_directory
;
100 struct re_pattern_buffer
*bufp
= NULL
;
102 ptrdiff_t count
= SPECPDL_INDEX ();
103 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
106 Lisp_Object w32_save
= Qnil
;
109 /* Because of file name handlers, these functions might call
110 Ffuncall, and cause a GC. */
111 list
= encoded_directory
= dirfilename
= Qnil
;
112 GCPRO5 (match
, directory
, list
, dirfilename
, encoded_directory
);
113 dirfilename
= Fdirectory_file_name (directory
);
117 CHECK_STRING (match
);
119 /* MATCH might be a flawed regular expression. Rather than
120 catching and signaling our own errors, we just call
121 compile_pattern to do the work for us. */
122 /* Pass 1 for the MULTIBYTE arg
123 because we do make multibyte strings if the contents warrant. */
125 /* Windows users want case-insensitive wildcards. */
126 bufp
= compile_pattern (match
, 0,
127 BVAR (&buffer_defaults
, case_canon_table
), 0, 1);
128 # else /* !WINDOWSNT */
129 bufp
= compile_pattern (match
, 0, Qnil
, 0, 1);
130 # endif /* !WINDOWSNT */
133 /* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
134 run_pre_post_conversion_on_str which calls Lisp directly and
136 if (STRING_MULTIBYTE (dirfilename
))
137 dirfilename
= ENCODE_FILE (dirfilename
);
138 encoded_directory
= (STRING_MULTIBYTE (directory
)
139 ? ENCODE_FILE (directory
) : directory
);
141 /* Now *bufp is the compiled form of MATCH; don't call anything
142 which might compile a new regexp until we're done with the loop! */
145 d
= opendir (SSDATA (dirfilename
));
148 report_file_error ("Opening directory", Fcons (directory
, Qnil
));
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
,
154 make_save_value (d
, 0));
159 extern int is_slow_fs (const char *);
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
))
168 /* w32.c:stat will notice these bindings and avoid calling
169 GetDriveType for each file. */
170 if (is_slow_fs (SDATA (dirfilename
)))
171 Vw32_get_true_file_attributes
= Qnil
;
173 Vw32_get_true_file_attributes
= Qt
;
178 directory_nbytes
= SBYTES (directory
);
179 re_match_object
= Qt
;
181 /* Decide whether we need to add a directory separator. */
182 if (directory_nbytes
== 0
183 || !IS_ANY_SEP (SREF (directory
, directory_nbytes
- 1)))
186 /* Loop reading blocks until EOF or error. */
191 Lisp_Object name
, finalname
;
192 struct gcpro gcpro1
, gcpro2
;
210 len
= dirent_namelen (dp
);
211 name
= finalname
= make_unibyte_string (dp
->d_name
, len
);
212 GCPRO2 (finalname
, name
);
214 /* Note: DECODE_FILE can GC; it should protect its argument,
216 name
= DECODE_FILE (name
);
219 /* Now that we have unwind_protect in place, we might as well
220 allow matching to be interrupted. */
225 || (0 <= re_search (bufp
, SSDATA (name
), len
, 0, len
, 0)))
234 Lisp_Object fullname
;
235 ptrdiff_t nbytes
= len
+ directory_nbytes
+ needsep
;
238 fullname
= make_uninit_multibyte_string (nbytes
, nbytes
);
239 memcpy (SDATA (fullname
), SDATA (directory
),
243 SSET (fullname
, directory_nbytes
, DIRECTORY_SEP
);
245 memcpy (SDATA (fullname
) + directory_nbytes
+ needsep
,
248 nchars
= chars_in_text (SDATA (fullname
), nbytes
);
250 /* Some bug somewhere. */
254 STRING_SET_CHARS (fullname
, nchars
);
255 if (nchars
== nbytes
)
256 STRING_SET_UNIBYTE (fullname
);
258 finalname
= fullname
;
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
;
270 decoded_fullname
= fileattrs
= Qnil
;
271 GCPRO2 (decoded_fullname
, fileattrs
);
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
);
277 list
= Fcons (Fcons (finalname
, fileattrs
), list
);
281 list
= Fcons (finalname
, list
);
292 Vw32_get_true_file_attributes
= w32_save
;
295 /* Discard the unwind protect. */
296 specpdl_ptr
= specpdl
+ count
;
299 list
= Fsort (Fnreverse (list
),
300 attrs
? Qfile_attributes_lessp
: Qstring_lessp
);
302 RETURN_UNGCPRO (list
);
306 DEFUN ("directory-files", Fdirectory_files
, Sdirectory_files
, 1, 4, 0,
307 doc
: /* Return a list of names of files in DIRECTORY.
308 There are three optional arguments:
309 If FULL is non-nil, return absolute file names. Otherwise return names
310 that are relative to the specified directory.
311 If MATCH is non-nil, mention only file names that match the regexp MATCH.
312 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
313 Otherwise, the list returned is sorted with `string-lessp'.
314 NOSORT is useful if you plan to sort the result yourself. */)
315 (Lisp_Object directory
, Lisp_Object full
, Lisp_Object match
, Lisp_Object nosort
)
318 directory
= Fexpand_file_name (directory
, Qnil
);
320 /* If the file name has special constructs in it,
321 call the corresponding file handler. */
322 handler
= Ffind_file_name_handler (directory
, Qdirectory_files
);
324 return call5 (handler
, Qdirectory_files
, directory
,
325 full
, match
, nosort
);
327 return directory_files_internal (directory
, full
, match
, nosort
, 0, Qnil
);
330 DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes
,
331 Sdirectory_files_and_attributes
, 1, 5, 0,
332 doc
: /* Return a list of names of files and their attributes in DIRECTORY.
333 There are four optional arguments:
334 If FULL is non-nil, return absolute file names. Otherwise return names
335 that are relative to the specified directory.
336 If MATCH is non-nil, mention only file names that match the regexp MATCH.
337 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
338 NOSORT is useful if you plan to sort the result yourself.
339 ID-FORMAT specifies the preferred format of attributes uid and gid, see
340 `file-attributes' for further documentation.
341 On MS-Windows, performance depends on `w32-get-true-file-attributes',
343 (Lisp_Object directory
, Lisp_Object full
, Lisp_Object match
, Lisp_Object nosort
, Lisp_Object id_format
)
346 directory
= Fexpand_file_name (directory
, Qnil
);
348 /* If the file name has special constructs in it,
349 call the corresponding file handler. */
350 handler
= Ffind_file_name_handler (directory
, Qdirectory_files_and_attributes
);
352 return call6 (handler
, Qdirectory_files_and_attributes
,
353 directory
, full
, match
, nosort
, id_format
);
355 return directory_files_internal (directory
, full
, match
, nosort
, 1, id_format
);
359 static Lisp_Object
file_name_completion (Lisp_Object
, Lisp_Object
, bool,
362 DEFUN ("file-name-completion", Ffile_name_completion
, Sfile_name_completion
,
364 doc
: /* Complete file name FILE in directory DIRECTORY.
365 Returns the longest string
366 common to all file names in DIRECTORY that start with FILE.
367 If there is only one and FILE matches it exactly, returns t.
368 Returns nil if DIRECTORY contains no name starting with FILE.
370 If PREDICATE is non-nil, call PREDICATE with each possible
371 completion (in absolute form) and ignore it if PREDICATE returns nil.
373 This function ignores some of the possible completions as
374 determined by the variable `completion-ignored-extensions', which see. */)
375 (Lisp_Object file
, Lisp_Object directory
, Lisp_Object predicate
)
378 directory
= Fexpand_file_name (directory
, Qnil
);
380 /* If the directory name has special constructs in it,
381 call the corresponding file handler. */
382 handler
= Ffind_file_name_handler (directory
, Qfile_name_completion
);
384 return call4 (handler
, Qfile_name_completion
, file
, directory
, predicate
);
386 /* If the file name has special constructs in it,
387 call the corresponding file handler. */
388 handler
= Ffind_file_name_handler (file
, Qfile_name_completion
);
390 return call4 (handler
, Qfile_name_completion
, file
, directory
, predicate
);
392 return file_name_completion (file
, directory
, 0, predicate
);
395 DEFUN ("file-name-all-completions", Ffile_name_all_completions
,
396 Sfile_name_all_completions
, 2, 2, 0,
397 doc
: /* Return a list of all completions of file name FILE in directory DIRECTORY.
398 These are all file names in directory DIRECTORY which begin with FILE. */)
399 (Lisp_Object file
, Lisp_Object directory
)
402 directory
= Fexpand_file_name (directory
, Qnil
);
404 /* If the directory name has special constructs in it,
405 call the corresponding file handler. */
406 handler
= Ffind_file_name_handler (directory
, Qfile_name_all_completions
);
408 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
410 /* If the file name has special constructs in it,
411 call the corresponding file handler. */
412 handler
= Ffind_file_name_handler (file
, Qfile_name_all_completions
);
414 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
416 return file_name_completion (file
, directory
, 1, Qnil
);
419 static int file_name_completion_stat (Lisp_Object dirname
, struct dirent
*dp
,
420 struct stat
*st_addr
);
421 static Lisp_Object Qdefault_directory
;
424 file_name_completion (Lisp_Object file
, Lisp_Object dirname
, bool all_flag
,
425 Lisp_Object predicate
)
428 ptrdiff_t bestmatchsize
= 0;
430 /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded.
431 If ALL_FLAG is 0, BESTMATCH is either nil
432 or the best match so far, not decoded. */
433 Lisp_Object bestmatch
, tem
, elt
, name
;
434 Lisp_Object encoded_file
;
435 Lisp_Object encoded_dir
;
438 /* If not INCLUDEALL, exclude files in completion-ignored-extensions as
439 well as "." and "..". Until shown otherwise, assume we can't exclude
442 ptrdiff_t count
= SPECPDL_INDEX ();
443 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
450 encoded_file
= encoded_dir
= Qnil
;
451 GCPRO5 (file
, dirname
, bestmatch
, encoded_file
, encoded_dir
);
452 specbind (Qdefault_directory
, dirname
);
454 /* Do completion on the encoded file name
455 because the other names in the directory are (we presume)
456 encoded likewise. We decode the completed string at the end. */
457 /* Actually, this is not quite true any more: we do most of the completion
458 work with decoded file names, but we still do some filtering based
459 on the encoded file name. */
460 encoded_file
= STRING_MULTIBYTE (file
) ? ENCODE_FILE (file
) : file
;
462 encoded_dir
= ENCODE_FILE (dirname
);
465 d
= opendir (SSDATA (Fdirectory_file_name (encoded_dir
)));
468 report_file_error ("Opening directory", Fcons (dirname
, Qnil
));
470 record_unwind_protect (directory_files_internal_unwind
,
471 make_save_value (d
, 0));
473 /* Loop reading blocks */
474 /* (att3b compiler bug requires do a null comparison this way) */
495 len
= dirent_namelen (dp
);
498 if (len
< SCHARS (encoded_file
)
499 || 0 <= scmp (dp
->d_name
, SSDATA (encoded_file
),
500 SCHARS (encoded_file
)))
503 if (file_name_completion_stat (encoded_dir
, dp
, &st
) < 0)
506 directoryp
= S_ISDIR (st
.st_mode
) != 0;
508 /* If all_flag is set, always include all.
509 It would not actually be helpful to the user to ignore any possible
510 completions when making a list of them. */
515 #if 0 /* FIXME: The `scmp' call compares an encoded and a decoded string. */
516 /* If this entry matches the current bestmatch, the only
517 thing it can do is increase matchcount, so don't bother
518 investigating it any further. */
519 if (!completion_ignore_case
520 /* The return result depends on whether it's the sole match. */
522 && !includeall
/* This match may allow includeall to 0. */
523 && len
>= bestmatchsize
524 && 0 > scmp (dp
->d_name
, SSDATA (bestmatch
), bestmatchsize
))
530 #ifndef TRIVIAL_DIRECTORY_ENTRY
531 #define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
533 /* "." and ".." are never interesting as completions, and are
534 actually in the way in a directory with only one file. */
535 if (TRIVIAL_DIRECTORY_ENTRY (dp
->d_name
))
537 else if (len
> SCHARS (encoded_file
))
538 /* Ignore directories if they match an element of
539 completion-ignored-extensions which ends in a slash. */
540 for (tem
= Vcompletion_ignored_extensions
;
541 CONSP (tem
); tem
= XCDR (tem
))
549 /* Need to encode ELT, since scmp compares unibyte
551 elt
= ENCODE_FILE (elt
);
552 elt_len
= SCHARS (elt
) - 1; /* -1 for trailing / */
556 if (p1
[elt_len
] != '/')
558 skip
= len
- elt_len
;
562 if (0 <= scmp (dp
->d_name
+ skip
, p1
, elt_len
))
569 /* Compare extensions-to-be-ignored against end of this file name */
570 /* if name is not an exact match against specified string */
571 if (len
> SCHARS (encoded_file
))
572 /* and exit this for loop if a match is found */
573 for (tem
= Vcompletion_ignored_extensions
;
574 CONSP (tem
); tem
= XCDR (tem
))
577 if (!STRINGP (elt
)) continue;
578 /* Need to encode ELT, since scmp compares unibyte
580 elt
= ENCODE_FILE (elt
);
581 skip
= len
- SCHARS (elt
);
582 if (skip
< 0) continue;
584 if (0 <= scmp (dp
->d_name
+ skip
,
592 /* If an ignored-extensions match was found,
593 don't process this name as a completion. */
597 if (!includeall
&& canexclude
)
598 /* We're not including all files and this file can be excluded. */
601 if (includeall
&& !canexclude
)
602 { /* If we have one non-excludable file, we want to exclude the
605 /* Throw away any previous excludable match found. */
611 /* FIXME: If we move this `decode' earlier we can eliminate
612 the repeated ENCODE_FILE on Vcompletion_ignored_extensions. */
613 name
= make_unibyte_string (dp
->d_name
, len
);
614 name
= DECODE_FILE (name
);
619 /* Ignore this element if it fails to match all the regexps. */
620 if (completion_ignore_case
)
622 for (regexps
= Vcompletion_regexp_list
; CONSP (regexps
);
623 regexps
= XCDR (regexps
))
624 if (fast_string_match_ignore_case (XCAR (regexps
), name
) < 0)
629 for (regexps
= Vcompletion_regexp_list
; CONSP (regexps
);
630 regexps
= XCDR (regexps
))
631 if (fast_string_match (XCAR (regexps
), name
) < 0)
639 /* This is a possible completion */
641 /* This completion is a directory; make it end with '/'. */
642 name
= Ffile_name_as_directory (name
);
644 /* Test the predicate, if any. */
645 if (!NILP (predicate
))
651 val
= call1 (predicate
, name
);
658 /* Suitably record this match. */
660 matchcount
+= matchcount
<= 1;
663 bestmatch
= Fcons (name
, bestmatch
);
664 else if (NILP (bestmatch
))
667 bestmatchsize
= SCHARS (name
);
671 Lisp_Object zero
= make_number (0);
672 /* FIXME: This is a copy of the code in Ftry_completion. */
673 ptrdiff_t compare
= min (bestmatchsize
, SCHARS (name
));
675 = Fcompare_strings (bestmatch
, zero
,
676 make_number (compare
),
678 make_number (compare
),
679 completion_ignore_case
? Qt
: Qnil
);
681 = (EQ (cmp
, Qt
) ? compare
682 : XINT (cmp
) < 0 ? - XINT (cmp
) - 1
685 if (completion_ignore_case
)
687 /* If this is an exact match except for case,
688 use it as the best match rather than one that is not
689 an exact match. This way, we get the case pattern
690 of the actual match. */
691 /* This tests that the current file is an exact match
692 but BESTMATCH is not (it is too long). */
693 if ((matchsize
== SCHARS (name
)
694 && matchsize
+ directoryp
< SCHARS (bestmatch
))
696 /* If there is no exact match ignoring case,
697 prefer a match that does not change the case
699 /* If there is more than one exact match aside from
700 case, and one of them is exact including case,
702 /* This == checks that, of current file and BESTMATCH,
703 either both or neither are exact. */
704 (((matchsize
== SCHARS (name
))
706 (matchsize
+ directoryp
== SCHARS (bestmatch
)))
707 && (cmp
= Fcompare_strings (name
, zero
,
708 make_number (SCHARS (file
)),
713 && (cmp
= Fcompare_strings (bestmatch
, zero
,
714 make_number (SCHARS (file
)),
721 bestmatchsize
= matchsize
;
723 /* If the best completion so far is reduced to the string
724 we're trying to complete, then we already know there's no
725 other completion, so there's no point looking any further. */
726 if (matchsize
<= SCHARS (file
)
727 && !includeall
/* A future match may allow includeall to 0. */
728 /* If completion-ignore-case is non-nil, don't
729 short-circuit because we want to find the best
730 possible match *including* case differences. */
731 && (!completion_ignore_case
|| matchsize
== 0)
732 /* The return value depends on whether it's the sole match. */
740 /* This closes the directory. */
741 bestmatch
= unbind_to (count
, bestmatch
);
743 if (all_flag
|| NILP (bestmatch
))
745 /* Return t if the supplied string is an exact match (counting case);
746 it does not require any change to be made. */
747 if (matchcount
== 1 && !NILP (Fequal (bestmatch
, file
)))
749 bestmatch
= Fsubstring (bestmatch
, make_number (0),
750 make_number (bestmatchsize
));
754 /* Compare exactly LEN chars of strings at S1 and S2,
755 ignoring case if appropriate.
756 Return -1 if strings match,
757 else number of chars that match at the beginning. */
760 scmp (const char *s1
, const char *s2
, ptrdiff_t len
)
762 register ptrdiff_t l
= len
;
764 if (completion_ignore_case
)
767 && (downcase ((unsigned char) *s1
++)
768 == downcase ((unsigned char) *s2
++)))
773 while (l
&& *s1
++ == *s2
++)
783 file_name_completion_stat (Lisp_Object dirname
, struct dirent
*dp
,
784 struct stat
*st_addr
)
786 ptrdiff_t len
= dirent_namelen (dp
);
787 ptrdiff_t pos
= SCHARS (dirname
);
790 char *fullname
= SAFE_ALLOCA (len
+ pos
+ 2);
793 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
794 but aren't required here. Avoid computing the following fields:
795 st_inode, st_size and st_nlink for directories, and the execute bits
796 in st_mode for non-directory files with non-standard extensions. */
798 unsigned short save_djstat_flags
= _djstat_flags
;
800 _djstat_flags
= _STAT_INODE
| _STAT_EXEC_MAGIC
| _STAT_DIRSIZE
;
803 memcpy (fullname
, SDATA (dirname
), pos
);
804 if (!IS_DIRECTORY_SEP (fullname
[pos
- 1]))
805 fullname
[pos
++] = DIRECTORY_SEP
;
807 memcpy (fullname
+ pos
, dp
->d_name
, len
);
808 fullname
[pos
+ len
] = 0;
810 /* We want to return success if a link points to a nonexistent file,
811 but we want to return the status for what the link points to,
812 in case it is a directory. */
813 value
= lstat (fullname
, st_addr
);
814 if (value
== 0 && S_ISLNK (st_addr
->st_mode
))
815 stat (fullname
, st_addr
);
817 _djstat_flags
= save_djstat_flags
;
824 stat_uname (struct stat
*st
)
829 struct passwd
*pw
= (struct passwd
*) getpwuid (st
->st_uid
);
839 stat_gname (struct stat
*st
)
844 struct group
*gr
= (struct group
*) getgrgid (st
->st_gid
);
853 DEFUN ("file-attributes", Ffile_attributes
, Sfile_attributes
, 1, 2, 0,
854 doc
: /* Return a list of attributes of file FILENAME.
855 Value is nil if specified file cannot be opened.
857 ID-FORMAT specifies the preferred format of attributes uid and gid (see
858 below) - valid values are 'string and 'integer. The latter is the
859 default, but we plan to change that, so you should specify a non-nil value
860 for ID-FORMAT if you use the returned uid or gid.
862 Elements of the attribute list are:
863 0. t for directory, string (name linked to) for symbolic link, or nil.
864 1. Number of links to file.
865 2. File uid as a string or a number. If a string value cannot be
866 looked up, a numeric value, either an integer or a float, is returned.
867 3. File gid, likewise.
868 4. Last access time, as a list of integers (HIGH LOW USEC PSEC) in the
869 same style as (current-time).
870 (See a note below about access time on FAT-based filesystems.)
871 5. Last modification time, likewise. This is the time of the last
872 change to the file's contents.
873 6. Last status change time, likewise. This is the time of last change
874 to the file's attributes: owner and group, access mode bits, etc.
876 This is a floating point number if the size is too large for an integer.
877 8. File modes, as a string of ten letters or dashes as in ls -l.
878 9. t if file's gid would change if file were deleted and recreated.
879 10. inode number. If it is larger than what an Emacs integer can hold,
880 this is of the form (HIGH . LOW): first the high bits, then the low 16 bits.
881 If even HIGH is too large for an Emacs integer, this is instead of the form
882 (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits,
883 and finally the low 16 bits.
884 11. Filesystem device number. If it is larger than what the Emacs
885 integer can hold, this is a cons cell, similar to the inode number.
887 On most filesystems, the combination of the inode and the device
888 number uniquely identifies the file.
890 On MS-Windows, performance depends on `w32-get-true-file-attributes',
893 On some FAT-based filesystems, only the date of last access is recorded,
894 so last access time will always be midnight of that day. */)
895 (Lisp_Object filename
, Lisp_Object id_format
)
897 Lisp_Object values
[12];
905 /* An array to hold the mode string generated by filemodestring,
906 including its terminating space and null byte. */
907 char modes
[sizeof "-rwxr-xr-x "];
911 char *uname
= NULL
, *gname
= NULL
;
913 filename
= Fexpand_file_name (filename
, Qnil
);
915 /* If the file name has special constructs in it,
916 call the corresponding file handler. */
917 handler
= Ffind_file_name_handler (filename
, Qfile_attributes
);
919 { /* Only pass the extra arg if it is used to help backward compatibility
920 with old file handlers which do not implement the new arg. --Stef */
921 if (NILP (id_format
))
922 return call2 (handler
, Qfile_attributes
, filename
);
924 return call3 (handler
, Qfile_attributes
, filename
, id_format
);
928 encoded
= ENCODE_FILE (filename
);
931 if (lstat (SSDATA (encoded
), &s
) < 0)
934 values
[0] = (S_ISLNK (s
.st_mode
) ? Ffile_symlink_p (filename
)
935 : S_ISDIR (s
.st_mode
) ? Qt
: Qnil
);
936 values
[1] = make_number (s
.st_nlink
);
938 if (!(NILP (id_format
) || EQ (id_format
, Qinteger
)))
941 uname
= stat_uname (&s
);
942 gname
= stat_gname (&s
);
946 values
[2] = DECODE_SYSTEM (build_string (uname
));
948 values
[2] = make_fixnum_or_float (s
.st_uid
);
950 values
[3] = DECODE_SYSTEM (build_string (gname
));
952 values
[3] = make_fixnum_or_float (s
.st_gid
);
954 values
[4] = make_lisp_time (get_stat_atime (&s
));
955 values
[5] = make_lisp_time (get_stat_mtime (&s
));
956 values
[6] = make_lisp_time (get_stat_ctime (&s
));
958 /* If the file size is a 4-byte type, assume that files of sizes in
959 the 2-4 GiB range wrap around to negative values, as this is a
960 common bug on older 32-bit platforms. */
961 if (sizeof (s
.st_size
) == 4)
962 values
[7] = make_fixnum_or_float (s
.st_size
& 0xffffffffu
);
964 values
[7] = make_fixnum_or_float (s
.st_size
);
966 filemodestring (&s
, modes
);
967 values
[8] = make_string (modes
, 10);
968 #ifdef BSD4_2 /* file gid will be dir gid */
969 dirname
= Ffile_name_directory (filename
);
970 if (! NILP (dirname
))
971 encoded
= ENCODE_FILE (dirname
);
972 if (! NILP (dirname
) && stat (SDATA (encoded
), &sdir
) == 0)
973 values
[9] = (sdir
.st_gid
!= s
.st_gid
) ? Qt
: Qnil
;
974 else /* if we can't tell, assume worst */
976 #else /* file gid will be egid */
977 values
[9] = (s
.st_gid
!= getegid ()) ? Qt
: Qnil
;
978 #endif /* not BSD4_2 */
979 values
[10] = INTEGER_TO_CONS (s
.st_ino
);
980 values
[11] = INTEGER_TO_CONS (s
.st_dev
);
982 return Flist (sizeof (values
) / sizeof (values
[0]), values
);
985 DEFUN ("file-attributes-lessp", Ffile_attributes_lessp
, Sfile_attributes_lessp
, 2, 2, 0,
986 doc
: /* Return t if first arg file attributes list is less than second.
987 Comparison is in lexicographic order and case is significant. */)
988 (Lisp_Object f1
, Lisp_Object f2
)
990 return Fstring_lessp (Fcar (f1
), Fcar (f2
));
994 DEFUN ("system-users", Fsystem_users
, Ssystem_users
, 0, 0, 0,
995 doc
: /* Return a list of user names currently registered in the system.
996 If we don't know how to determine that on this platform, just
997 return a list with one element, taken from `user-real-login-name'. */)
1000 Lisp_Object users
= Qnil
;
1001 #if defined HAVE_GETPWENT && defined HAVE_ENDPWENT
1004 while ((pw
= getpwent ()))
1005 users
= Fcons (DECODE_SYSTEM (build_string (pw
->pw_name
)), users
);
1009 if (EQ (users
, Qnil
))
1010 /* At least current user is always known. */
1011 users
= Fcons (Vuser_real_login_name
, Qnil
);
1015 DEFUN ("system-groups", Fsystem_groups
, Ssystem_groups
, 0, 0, 0,
1016 doc
: /* Return a list of user group names currently registered in the system.
1017 The value may be nil if not supported on this platform. */)
1020 Lisp_Object groups
= Qnil
;
1021 #if defined HAVE_GETGRENT && defined HAVE_ENDGRENT
1024 while ((gr
= getgrent ()))
1025 groups
= Fcons (DECODE_SYSTEM (build_string (gr
->gr_name
)), groups
);
1033 syms_of_dired (void)
1035 DEFSYM (Qdirectory_files
, "directory-files");
1036 DEFSYM (Qdirectory_files_and_attributes
, "directory-files-and-attributes");
1037 DEFSYM (Qfile_name_completion
, "file-name-completion");
1038 DEFSYM (Qfile_name_all_completions
, "file-name-all-completions");
1039 DEFSYM (Qfile_attributes
, "file-attributes");
1040 DEFSYM (Qfile_attributes_lessp
, "file-attributes-lessp");
1041 DEFSYM (Qdefault_directory
, "default-directory");
1043 defsubr (&Sdirectory_files
);
1044 defsubr (&Sdirectory_files_and_attributes
);
1045 defsubr (&Sfile_name_completion
);
1046 defsubr (&Sfile_name_all_completions
);
1047 defsubr (&Sfile_attributes
);
1048 defsubr (&Sfile_attributes_lessp
);
1049 defsubr (&Ssystem_users
);
1050 defsubr (&Ssystem_groups
);
1052 DEFVAR_LISP ("completion-ignored-extensions", Vcompletion_ignored_extensions
,
1053 doc
: /* Completion ignores file names ending in any string in this list.
1054 It does not ignore them if all possible completions end in one of
1055 these strings or when displaying a list of completions.
1056 It ignores directory names if they match any string in this list which
1057 ends in a slash. */);
1058 Vcompletion_ignored_extensions
= Qnil
;