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
;
198 if (errno
== EAGAIN
|| errno
== EINTR
)
206 len
= dirent_namelen (dp
);
207 name
= finalname
= make_unibyte_string (dp
->d_name
, len
);
208 GCPRO2 (finalname
, name
);
210 /* Note: DECODE_FILE can GC; it should protect its argument,
212 name
= DECODE_FILE (name
);
215 /* Now that we have unwind_protect in place, we might as well
216 allow matching to be interrupted. */
221 || (0 <= re_search (bufp
, SSDATA (name
), len
, 0, len
, 0)))
230 Lisp_Object fullname
;
231 ptrdiff_t nbytes
= len
+ directory_nbytes
+ needsep
;
234 fullname
= make_uninit_multibyte_string (nbytes
, nbytes
);
235 memcpy (SDATA (fullname
), SDATA (directory
),
239 SSET (fullname
, directory_nbytes
, DIRECTORY_SEP
);
241 memcpy (SDATA (fullname
) + directory_nbytes
+ needsep
,
244 nchars
= chars_in_text (SDATA (fullname
), nbytes
);
246 /* Some bug somewhere. */
250 STRING_SET_CHARS (fullname
, nchars
);
251 if (nchars
== nbytes
)
252 STRING_SET_UNIBYTE (fullname
);
254 finalname
= fullname
;
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
;
266 decoded_fullname
= fileattrs
= Qnil
;
267 GCPRO2 (decoded_fullname
, fileattrs
);
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
);
273 list
= Fcons (Fcons (finalname
, fileattrs
), list
);
277 list
= Fcons (finalname
, list
);
288 Vw32_get_true_file_attributes
= w32_save
;
291 /* Discard the unwind protect. */
292 specpdl_ptr
= specpdl
+ count
;
295 list
= Fsort (Fnreverse (list
),
296 attrs
? Qfile_attributes_lessp
: Qstring_lessp
);
298 RETURN_UNGCPRO (list
);
302 DEFUN ("directory-files", Fdirectory_files
, Sdirectory_files
, 1, 4, 0,
303 doc
: /* Return a list of names of files in DIRECTORY.
304 There are three optional arguments:
305 If FULL is non-nil, return absolute file names. Otherwise return names
306 that are relative to the specified directory.
307 If MATCH is non-nil, mention only file names that match the regexp MATCH.
308 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
309 Otherwise, the list returned is sorted with `string-lessp'.
310 NOSORT is useful if you plan to sort the result yourself. */)
311 (Lisp_Object directory
, Lisp_Object full
, Lisp_Object match
, Lisp_Object nosort
)
314 directory
= Fexpand_file_name (directory
, Qnil
);
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
);
320 return call5 (handler
, Qdirectory_files
, directory
,
321 full
, match
, nosort
);
323 return directory_files_internal (directory
, full
, match
, nosort
, 0, Qnil
);
326 DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes
,
327 Sdirectory_files_and_attributes
, 1, 5, 0,
328 doc
: /* Return a list of names of files and their attributes in DIRECTORY.
329 There are four optional arguments:
330 If FULL is non-nil, return absolute file names. Otherwise return names
331 that are relative to the specified directory.
332 If MATCH is non-nil, mention only file names that match the regexp MATCH.
333 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
334 NOSORT is useful if you plan to sort the result yourself.
335 ID-FORMAT specifies the preferred format of attributes uid and gid, see
336 `file-attributes' for further documentation.
337 On MS-Windows, performance depends on `w32-get-true-file-attributes',
339 (Lisp_Object directory
, Lisp_Object full
, Lisp_Object match
, Lisp_Object nosort
, Lisp_Object id_format
)
342 directory
= Fexpand_file_name (directory
, Qnil
);
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
);
348 return call6 (handler
, Qdirectory_files_and_attributes
,
349 directory
, full
, match
, nosort
, id_format
);
351 return directory_files_internal (directory
, full
, match
, nosort
, 1, id_format
);
355 static Lisp_Object
file_name_completion (Lisp_Object
, Lisp_Object
, bool,
358 DEFUN ("file-name-completion", Ffile_name_completion
, Sfile_name_completion
,
360 doc
: /* Complete file name FILE in directory DIRECTORY.
361 Returns the longest string
362 common to all file names in DIRECTORY that start with FILE.
363 If there is only one and FILE matches it exactly, returns t.
364 Returns nil if DIRECTORY contains no name starting with FILE.
366 If PREDICATE is non-nil, call PREDICATE with each possible
367 completion (in absolute form) and ignore it if PREDICATE returns nil.
369 This function ignores some of the possible completions as
370 determined by the variable `completion-ignored-extensions', which see. */)
371 (Lisp_Object file
, Lisp_Object directory
, Lisp_Object predicate
)
374 directory
= Fexpand_file_name (directory
, Qnil
);
376 /* If the directory name has special constructs in it,
377 call the corresponding file handler. */
378 handler
= Ffind_file_name_handler (directory
, Qfile_name_completion
);
380 return call4 (handler
, Qfile_name_completion
, file
, directory
, predicate
);
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
);
386 return call4 (handler
, Qfile_name_completion
, file
, directory
, predicate
);
388 return file_name_completion (file
, directory
, 0, predicate
);
391 DEFUN ("file-name-all-completions", Ffile_name_all_completions
,
392 Sfile_name_all_completions
, 2, 2, 0,
393 doc
: /* Return a list of all completions of file name FILE in directory DIRECTORY.
394 These are all file names in directory DIRECTORY which begin with FILE. */)
395 (Lisp_Object file
, Lisp_Object directory
)
398 directory
= Fexpand_file_name (directory
, Qnil
);
400 /* If the directory name has special constructs in it,
401 call the corresponding file handler. */
402 handler
= Ffind_file_name_handler (directory
, Qfile_name_all_completions
);
404 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
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
);
410 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
412 return file_name_completion (file
, directory
, 1, Qnil
);
415 static int file_name_completion_stat (Lisp_Object dirname
, struct dirent
*dp
,
416 struct stat
*st_addr
);
417 static Lisp_Object Qdefault_directory
;
420 file_name_completion (Lisp_Object file
, Lisp_Object dirname
, bool all_flag
,
421 Lisp_Object predicate
)
424 ptrdiff_t bestmatchsize
= 0;
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. */
429 Lisp_Object bestmatch
, tem
, elt
, name
;
430 Lisp_Object encoded_file
;
431 Lisp_Object encoded_dir
;
434 /* If not INCLUDEALL, exclude files in completion-ignored-extensions as
435 well as "." and "..". Until shown otherwise, assume we can't exclude
438 ptrdiff_t count
= SPECPDL_INDEX ();
439 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
446 encoded_file
= encoded_dir
= Qnil
;
447 GCPRO5 (file
, dirname
, bestmatch
, encoded_file
, encoded_dir
);
448 specbind (Qdefault_directory
, dirname
);
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. */
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. */
456 encoded_file
= STRING_MULTIBYTE (file
) ? ENCODE_FILE (file
) : file
;
458 encoded_dir
= ENCODE_FILE (dirname
);
461 d
= opendir (SSDATA (Fdirectory_file_name (encoded_dir
)));
464 report_file_error ("Opening directory", Fcons (dirname
, Qnil
));
466 record_unwind_protect (directory_files_internal_unwind
,
467 make_save_value (d
, 0));
469 /* Loop reading blocks */
470 /* (att3b compiler bug requires do a null comparison this way) */
481 if (errno
== EAGAIN
|| errno
== EINTR
)
489 len
= dirent_namelen (dp
);
492 if (len
< SCHARS (encoded_file
)
493 || 0 <= scmp (dp
->d_name
, SSDATA (encoded_file
),
494 SCHARS (encoded_file
)))
497 if (file_name_completion_stat (encoded_dir
, dp
, &st
) < 0)
500 directoryp
= S_ISDIR (st
.st_mode
) != 0;
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. */
509 #if 0 /* FIXME: The `scmp' call compares an encoded and a decoded string. */
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. */
516 && !includeall
/* This match may allow includeall to 0. */
517 && len
>= bestmatchsize
518 && 0 > scmp (dp
->d_name
, SSDATA (bestmatch
), bestmatchsize
))
524 #ifndef TRIVIAL_DIRECTORY_ENTRY
525 #define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
527 /* "." and ".." are never interesting as completions, and are
528 actually in the way in a directory with only one file. */
529 if (TRIVIAL_DIRECTORY_ENTRY (dp
->d_name
))
531 else if (len
> SCHARS (encoded_file
))
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
))
543 /* Need to encode ELT, since scmp compares unibyte
545 elt
= ENCODE_FILE (elt
);
546 elt_len
= SCHARS (elt
) - 1; /* -1 for trailing / */
550 if (p1
[elt_len
] != '/')
552 skip
= len
- elt_len
;
556 if (0 <= scmp (dp
->d_name
+ skip
, p1
, elt_len
))
563 /* Compare extensions-to-be-ignored against end of this file name */
564 /* if name is not an exact match against specified string */
565 if (len
> SCHARS (encoded_file
))
566 /* and exit this for loop if a match is found */
567 for (tem
= Vcompletion_ignored_extensions
;
568 CONSP (tem
); tem
= XCDR (tem
))
571 if (!STRINGP (elt
)) continue;
572 /* Need to encode ELT, since scmp compares unibyte
574 elt
= ENCODE_FILE (elt
);
575 skip
= len
- SCHARS (elt
);
576 if (skip
< 0) continue;
578 if (0 <= scmp (dp
->d_name
+ skip
,
586 /* If an ignored-extensions match was found,
587 don't process this name as a completion. */
591 if (!includeall
&& canexclude
)
592 /* We're not including all files and this file can be excluded. */
595 if (includeall
&& !canexclude
)
596 { /* If we have one non-excludable file, we want to exclude the
599 /* Throw away any previous excludable match found. */
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
);
613 /* Ignore this element if it fails to match all the regexps. */
614 if (completion_ignore_case
)
616 for (regexps
= Vcompletion_regexp_list
; CONSP (regexps
);
617 regexps
= XCDR (regexps
))
618 if (fast_string_match_ignore_case (XCAR (regexps
), name
) < 0)
623 for (regexps
= Vcompletion_regexp_list
; CONSP (regexps
);
624 regexps
= XCDR (regexps
))
625 if (fast_string_match (XCAR (regexps
), name
) < 0)
633 /* This is a possible completion */
635 /* This completion is a directory; make it end with '/'. */
636 name
= Ffile_name_as_directory (name
);
638 /* Test the predicate, if any. */
639 if (!NILP (predicate
))
645 val
= call1 (predicate
, name
);
652 /* Suitably record this match. */
654 matchcount
+= matchcount
<= 1;
657 bestmatch
= Fcons (name
, bestmatch
);
658 else if (NILP (bestmatch
))
661 bestmatchsize
= SCHARS (name
);
665 Lisp_Object zero
= make_number (0);
666 /* FIXME: This is a copy of the code in Ftry_completion. */
667 ptrdiff_t compare
= min (bestmatchsize
, SCHARS (name
));
669 = Fcompare_strings (bestmatch
, zero
,
670 make_number (compare
),
672 make_number (compare
),
673 completion_ignore_case
? Qt
: Qnil
);
675 = (EQ (cmp
, Qt
) ? compare
676 : XINT (cmp
) < 0 ? - XINT (cmp
) - 1
679 if (completion_ignore_case
)
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
)
688 && matchsize
+ directoryp
< SCHARS (bestmatch
))
690 /* If there is no exact match ignoring case,
691 prefer a match that does not change the case
693 /* If there is more than one exact match aside from
694 case, and one of them is exact including case,
696 /* This == checks that, of current file and BESTMATCH,
697 either both or neither are exact. */
698 (((matchsize
== SCHARS (name
))
700 (matchsize
+ directoryp
== SCHARS (bestmatch
)))
701 && (cmp
= Fcompare_strings (name
, zero
,
702 make_number (SCHARS (file
)),
707 && (cmp
= Fcompare_strings (bestmatch
, zero
,
708 make_number (SCHARS (file
)),
715 bestmatchsize
= matchsize
;
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. */
734 /* This closes the directory. */
735 bestmatch
= unbind_to (count
, bestmatch
);
737 if (all_flag
|| NILP (bestmatch
))
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
)))
743 bestmatch
= Fsubstring (bestmatch
, make_number (0),
744 make_number (bestmatchsize
));
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. */
754 scmp (const char *s1
, const char *s2
, ptrdiff_t len
)
756 register ptrdiff_t l
= len
;
758 if (completion_ignore_case
)
761 && (downcase ((unsigned char) *s1
++)
762 == downcase ((unsigned char) *s2
++)))
767 while (l
&& *s1
++ == *s2
++)
777 file_name_completion_stat (Lisp_Object dirname
, struct dirent
*dp
,
778 struct stat
*st_addr
)
780 ptrdiff_t len
= dirent_namelen (dp
);
781 ptrdiff_t pos
= SCHARS (dirname
);
784 char *fullname
= SAFE_ALLOCA (len
+ pos
+ 2);
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. */
792 unsigned short save_djstat_flags
= _djstat_flags
;
794 _djstat_flags
= _STAT_INODE
| _STAT_EXEC_MAGIC
| _STAT_DIRSIZE
;
797 memcpy (fullname
, SDATA (dirname
), pos
);
798 if (!IS_DIRECTORY_SEP (fullname
[pos
- 1]))
799 fullname
[pos
++] = DIRECTORY_SEP
;
801 memcpy (fullname
+ pos
, dp
->d_name
, len
);
802 fullname
[pos
+ len
] = 0;
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
);
808 if (value
== 0 && S_ISLNK (st_addr
->st_mode
))
809 stat (fullname
, st_addr
);
811 _djstat_flags
= save_djstat_flags
;
818 stat_uname (struct stat
*st
)
823 struct passwd
*pw
= getpwuid (st
->st_uid
);
833 stat_gname (struct stat
*st
)
838 struct group
*gr
= getgrgid (st
->st_gid
);
847 DEFUN ("file-attributes", Ffile_attributes
, Sfile_attributes
, 1, 2, 0,
848 doc
: /* Return a list of attributes of file FILENAME.
849 Value is nil if specified file cannot be opened.
851 ID-FORMAT specifies the preferred format of attributes uid and gid (see
852 below) - valid values are 'string and 'integer. The latter is the
853 default, but we plan to change that, so you should specify a non-nil value
854 for ID-FORMAT if you use the returned uid or gid.
856 Elements of the attribute list are:
857 0. t for directory, string (name linked to) for symbolic link, or nil.
858 1. Number of links to file.
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.
861 3. File gid, likewise.
862 4. Last access time, as a list of integers (HIGH LOW USEC PSEC) in the
863 same style as (current-time).
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.
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.
872 9. t if file's gid would change if file were deleted and recreated.
873 10. 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,
877 and finally the low 16 bits.
878 11. 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.
881 On most filesystems, the combination of the inode and the device
882 number uniquely identifies the file.
884 On MS-Windows, performance depends on `w32-get-true-file-attributes',
887 On some FAT-based filesystems, only the date of last access is recorded,
888 so last access time will always be midnight of that day. */)
889 (Lisp_Object filename
, Lisp_Object id_format
)
891 Lisp_Object values
[12];
899 /* An array to hold the mode string generated by filemodestring,
900 including its terminating space and null byte. */
901 char modes
[sizeof "-rwxr-xr-x "];
905 char *uname
= NULL
, *gname
= NULL
;
907 filename
= Fexpand_file_name (filename
, Qnil
);
909 /* If the file name has special constructs in it,
910 call the corresponding file handler. */
911 handler
= Ffind_file_name_handler (filename
, Qfile_attributes
);
913 { /* Only pass the extra arg if it is used to help backward compatibility
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
);
918 return call3 (handler
, Qfile_attributes
, filename
, id_format
);
922 encoded
= ENCODE_FILE (filename
);
925 if (lstat (SSDATA (encoded
), &s
) < 0)
928 values
[0] = (S_ISLNK (s
.st_mode
) ? Ffile_symlink_p (filename
)
929 : S_ISDIR (s
.st_mode
) ? Qt
: Qnil
);
930 values
[1] = make_number (s
.st_nlink
);
932 if (!(NILP (id_format
) || EQ (id_format
, Qinteger
)))
935 uname
= stat_uname (&s
);
936 gname
= stat_gname (&s
);
940 values
[2] = DECODE_SYSTEM (build_string (uname
));
942 values
[2] = make_fixnum_or_float (s
.st_uid
);
944 values
[3] = DECODE_SYSTEM (build_string (gname
));
946 values
[3] = make_fixnum_or_float (s
.st_gid
);
948 values
[4] = make_lisp_time (get_stat_atime (&s
));
949 values
[5] = make_lisp_time (get_stat_mtime (&s
));
950 values
[6] = make_lisp_time (get_stat_ctime (&s
));
952 /* If the file size is a 4-byte type, assume that files of sizes in
953 the 2-4 GiB range wrap around to negative values, as this is a
954 common bug on older 32-bit platforms. */
955 if (sizeof (s
.st_size
) == 4)
956 values
[7] = make_fixnum_or_float (s
.st_size
& 0xffffffffu
);
958 values
[7] = make_fixnum_or_float (s
.st_size
);
960 filemodestring (&s
, modes
);
961 values
[8] = make_string (modes
, 10);
962 #ifdef BSD4_2 /* file gid will be dir gid */
963 dirname
= Ffile_name_directory (filename
);
964 if (! NILP (dirname
))
965 encoded
= ENCODE_FILE (dirname
);
966 if (! NILP (dirname
) && stat (SDATA (encoded
), &sdir
) == 0)
967 values
[9] = (sdir
.st_gid
!= s
.st_gid
) ? Qt
: Qnil
;
968 else /* if we can't tell, assume worst */
970 #else /* file gid will be egid */
971 values
[9] = (s
.st_gid
!= getegid ()) ? Qt
: Qnil
;
972 #endif /* not BSD4_2 */
973 values
[10] = INTEGER_TO_CONS (s
.st_ino
);
974 values
[11] = INTEGER_TO_CONS (s
.st_dev
);
976 return Flist (sizeof (values
) / sizeof (values
[0]), values
);
979 DEFUN ("file-attributes-lessp", Ffile_attributes_lessp
, Sfile_attributes_lessp
, 2, 2, 0,
980 doc
: /* Return t if first arg file attributes list is less than second.
981 Comparison is in lexicographic order and case is significant. */)
982 (Lisp_Object f1
, Lisp_Object f2
)
984 return Fstring_lessp (Fcar (f1
), Fcar (f2
));
988 DEFUN ("system-users", Fsystem_users
, Ssystem_users
, 0, 0, 0,
989 doc
: /* Return a list of user names currently registered in the system.
990 If we don't know how to determine that on this platform, just
991 return a list with one element, taken from `user-real-login-name'. */)
994 Lisp_Object users
= Qnil
;
995 #if defined HAVE_GETPWENT && defined HAVE_ENDPWENT
998 while ((pw
= getpwent ()))
999 users
= Fcons (DECODE_SYSTEM (build_string (pw
->pw_name
)), users
);
1003 if (EQ (users
, Qnil
))
1004 /* At least current user is always known. */
1005 users
= Fcons (Vuser_real_login_name
, Qnil
);
1009 DEFUN ("system-groups", Fsystem_groups
, Ssystem_groups
, 0, 0, 0,
1010 doc
: /* Return a list of user group names currently registered in the system.
1011 The value may be nil if not supported on this platform. */)
1014 Lisp_Object groups
= Qnil
;
1015 #if defined HAVE_GETGRENT && defined HAVE_ENDGRENT
1018 while ((gr
= getgrent ()))
1019 groups
= Fcons (DECODE_SYSTEM (build_string (gr
->gr_name
)), groups
);
1027 syms_of_dired (void)
1029 DEFSYM (Qdirectory_files
, "directory-files");
1030 DEFSYM (Qdirectory_files_and_attributes
, "directory-files-and-attributes");
1031 DEFSYM (Qfile_name_completion
, "file-name-completion");
1032 DEFSYM (Qfile_name_all_completions
, "file-name-all-completions");
1033 DEFSYM (Qfile_attributes
, "file-attributes");
1034 DEFSYM (Qfile_attributes_lessp
, "file-attributes-lessp");
1035 DEFSYM (Qdefault_directory
, "default-directory");
1037 defsubr (&Sdirectory_files
);
1038 defsubr (&Sdirectory_files_and_attributes
);
1039 defsubr (&Sfile_name_completion
);
1040 defsubr (&Sfile_name_all_completions
);
1041 defsubr (&Sfile_attributes
);
1042 defsubr (&Sfile_attributes_lessp
);
1043 defsubr (&Ssystem_users
);
1044 defsubr (&Ssystem_groups
);
1046 DEFVAR_LISP ("completion-ignored-extensions", Vcompletion_ignored_extensions
,
1047 doc
: /* Completion ignores file names ending in any string in this list.
1048 It does not ignore them if all possible completions end in one of
1049 these strings or when displaying a list of completions.
1050 It ignores directory names if they match any string in this list which
1051 ends in a slash. */);
1052 Vcompletion_ignored_extensions
= Qnil
;