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>
35 /* The d_nameln member of a struct dirent includes the '\0' character
36 on some systems, but not on others. What's worse, you can't tell
37 at compile-time which one it will be, since it really depends on
38 the sort of system providing the filesystem you're reading from,
39 not the system you are running on. Paul Eggert
40 <eggert@bi.twinsun.com> says this occurs when Emacs is running on a
41 SunOS 4.1.2 host, reading a directory that is remote-mounted from a
42 Solaris 2.1 host and is in a native Solaris 2.1 filesystem.
44 Since applying strlen to the name always works, we'll just do that. */
45 #define NAMLEN(p) strlen (p->d_name)
50 #define DIRENTRY struct dirent
52 #else /* not HAVE_DIRENT_H */
57 #define DIRENTRY struct direct
59 extern DIR *opendir (char *);
60 extern struct direct
*readdir (DIR *);
62 #endif /* HAVE_DIRENT_H */
65 #include <stat-time.h>
68 #define DIRENTRY_NONEMPTY(p) ((p)->d_name[0] != 0)
70 #define DIRENTRY_NONEMPTY(p) ((p)->d_ino)
75 #include "character.h"
81 #include "blockinput.h"
83 static Lisp_Object Qdirectory_files
;
84 static Lisp_Object Qdirectory_files_and_attributes
;
85 static Lisp_Object Qfile_name_completion
;
86 static Lisp_Object Qfile_name_all_completions
;
87 static Lisp_Object Qfile_attributes
;
88 static Lisp_Object Qfile_attributes_lessp
;
90 static ptrdiff_t scmp (const char *, const char *, ptrdiff_t);
91 static Lisp_Object
Ffile_attributes (Lisp_Object
, Lisp_Object
);
95 directory_files_internal_w32_unwind (Lisp_Object arg
)
97 Vw32_get_true_file_attributes
= arg
;
103 directory_files_internal_unwind (Lisp_Object dh
)
105 DIR *d
= (DIR *) XSAVE_VALUE (dh
)->pointer
;
112 /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
113 When ATTRS is zero, return a list of directory filenames; when
114 non-zero, return a list of directory filenames and their attributes.
115 In the latter case, ID_FORMAT is passed to Ffile_attributes. */
118 directory_files_internal (Lisp_Object directory
, Lisp_Object full
, Lisp_Object match
, Lisp_Object nosort
, int attrs
, Lisp_Object id_format
)
121 ptrdiff_t directory_nbytes
;
122 Lisp_Object list
, dirfilename
, encoded_directory
;
123 struct re_pattern_buffer
*bufp
= NULL
;
125 ptrdiff_t count
= SPECPDL_INDEX ();
126 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
129 Lisp_Object w32_save
= Qnil
;
132 /* Because of file name handlers, these functions might call
133 Ffuncall, and cause a GC. */
134 list
= encoded_directory
= dirfilename
= Qnil
;
135 GCPRO5 (match
, directory
, list
, dirfilename
, encoded_directory
);
136 dirfilename
= Fdirectory_file_name (directory
);
140 CHECK_STRING (match
);
142 /* MATCH might be a flawed regular expression. Rather than
143 catching and signaling our own errors, we just call
144 compile_pattern to do the work for us. */
145 /* Pass 1 for the MULTIBYTE arg
146 because we do make multibyte strings if the contents warrant. */
148 /* Windows users want case-insensitive wildcards. */
149 bufp
= compile_pattern (match
, 0,
150 BVAR (&buffer_defaults
, case_canon_table
), 0, 1);
151 # else /* !WINDOWSNT */
152 bufp
= compile_pattern (match
, 0, Qnil
, 0, 1);
153 # endif /* !WINDOWSNT */
156 /* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
157 run_pre_post_conversion_on_str which calls Lisp directly and
159 if (STRING_MULTIBYTE (dirfilename
))
160 dirfilename
= ENCODE_FILE (dirfilename
);
161 encoded_directory
= (STRING_MULTIBYTE (directory
)
162 ? ENCODE_FILE (directory
) : directory
);
164 /* Now *bufp is the compiled form of MATCH; don't call anything
165 which might compile a new regexp until we're done with the loop! */
168 d
= opendir (SSDATA (dirfilename
));
171 report_file_error ("Opening directory", Fcons (directory
, Qnil
));
173 /* Unfortunately, we can now invoke expand-file-name and
174 file-attributes on filenames, both of which can throw, so we must
175 do a proper unwind-protect. */
176 record_unwind_protect (directory_files_internal_unwind
,
177 make_save_value (d
, 0));
182 extern int is_slow_fs (const char *);
184 /* Do this only once to avoid doing it (in w32.c:stat) for each
185 file in the directory, when we call Ffile_attributes below. */
186 record_unwind_protect (directory_files_internal_w32_unwind
,
187 Vw32_get_true_file_attributes
);
188 w32_save
= Vw32_get_true_file_attributes
;
189 if (EQ (Vw32_get_true_file_attributes
, Qlocal
))
191 /* w32.c:stat will notice these bindings and avoid calling
192 GetDriveType for each file. */
193 if (is_slow_fs (SDATA (dirfilename
)))
194 Vw32_get_true_file_attributes
= Qnil
;
196 Vw32_get_true_file_attributes
= Qt
;
201 directory_nbytes
= SBYTES (directory
);
202 re_match_object
= Qt
;
204 /* Decide whether we need to add a directory separator. */
205 if (directory_nbytes
== 0
206 || !IS_ANY_SEP (SREF (directory
, directory_nbytes
- 1)))
209 /* Loop reading blocks until EOF or error. */
228 if (DIRENTRY_NONEMPTY (dp
))
232 Lisp_Object name
, finalname
;
233 struct gcpro gcpro1
, gcpro2
;
236 name
= finalname
= make_unibyte_string (dp
->d_name
, len
);
237 GCPRO2 (finalname
, name
);
239 /* Note: DECODE_FILE can GC; it should protect its argument,
241 name
= DECODE_FILE (name
);
244 /* Now that we have unwind_protect in place, we might as well
245 allow matching to be interrupted. */
250 || (0 <= re_search (bufp
, SSDATA (name
), len
, 0, len
, 0)))
259 Lisp_Object fullname
;
260 ptrdiff_t nbytes
= len
+ directory_nbytes
+ needsep
;
263 fullname
= make_uninit_multibyte_string (nbytes
, nbytes
);
264 memcpy (SDATA (fullname
), SDATA (directory
),
268 SSET (fullname
, directory_nbytes
, DIRECTORY_SEP
);
270 memcpy (SDATA (fullname
) + directory_nbytes
+ needsep
,
273 nchars
= chars_in_text (SDATA (fullname
), nbytes
);
275 /* Some bug somewhere. */
279 STRING_SET_CHARS (fullname
, nchars
);
280 if (nchars
== nbytes
)
281 STRING_SET_UNIBYTE (fullname
);
283 finalname
= fullname
;
290 /* Construct an expanded filename for the directory entry.
291 Use the decoded names for input to Ffile_attributes. */
292 Lisp_Object decoded_fullname
, fileattrs
;
293 struct gcpro gcpro1
, gcpro2
;
295 decoded_fullname
= fileattrs
= Qnil
;
296 GCPRO2 (decoded_fullname
, fileattrs
);
298 /* Both Fexpand_file_name and Ffile_attributes can GC. */
299 decoded_fullname
= Fexpand_file_name (name
, directory
);
300 fileattrs
= Ffile_attributes (decoded_fullname
, id_format
);
302 list
= Fcons (Fcons (finalname
, fileattrs
), list
);
306 list
= Fcons (finalname
, list
);
318 Vw32_get_true_file_attributes
= w32_save
;
321 /* Discard the unwind protect. */
322 specpdl_ptr
= specpdl
+ count
;
325 list
= Fsort (Fnreverse (list
),
326 attrs
? Qfile_attributes_lessp
: Qstring_lessp
);
328 RETURN_UNGCPRO (list
);
332 DEFUN ("directory-files", Fdirectory_files
, Sdirectory_files
, 1, 4, 0,
333 doc
: /* Return a list of names of files in DIRECTORY.
334 There are three optional arguments:
335 If FULL is non-nil, return absolute file names. Otherwise return names
336 that are relative to the specified directory.
337 If MATCH is non-nil, mention only file names that match the regexp MATCH.
338 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
339 Otherwise, the list returned is sorted with `string-lessp'.
340 NOSORT is useful if you plan to sort the result yourself. */)
341 (Lisp_Object directory
, Lisp_Object full
, Lisp_Object match
, Lisp_Object nosort
)
344 directory
= Fexpand_file_name (directory
, Qnil
);
346 /* If the file name has special constructs in it,
347 call the corresponding file handler. */
348 handler
= Ffind_file_name_handler (directory
, Qdirectory_files
);
350 return call5 (handler
, Qdirectory_files
, directory
,
351 full
, match
, nosort
);
353 return directory_files_internal (directory
, full
, match
, nosort
, 0, Qnil
);
356 DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes
,
357 Sdirectory_files_and_attributes
, 1, 5, 0,
358 doc
: /* Return a list of names of files and their attributes in DIRECTORY.
359 There are four optional arguments:
360 If FULL is non-nil, return absolute file names. Otherwise return names
361 that are relative to the specified directory.
362 If MATCH is non-nil, mention only file names that match the regexp MATCH.
363 If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
364 NOSORT is useful if you plan to sort the result yourself.
365 ID-FORMAT specifies the preferred format of attributes uid and gid, see
366 `file-attributes' for further documentation.
367 On MS-Windows, performance depends on `w32-get-true-file-attributes',
369 (Lisp_Object directory
, Lisp_Object full
, Lisp_Object match
, Lisp_Object nosort
, Lisp_Object id_format
)
372 directory
= Fexpand_file_name (directory
, Qnil
);
374 /* If the file name has special constructs in it,
375 call the corresponding file handler. */
376 handler
= Ffind_file_name_handler (directory
, Qdirectory_files_and_attributes
);
378 return call6 (handler
, Qdirectory_files_and_attributes
,
379 directory
, full
, match
, nosort
, id_format
);
381 return directory_files_internal (directory
, full
, match
, nosort
, 1, id_format
);
385 static Lisp_Object file_name_completion
386 (Lisp_Object file
, Lisp_Object dirname
, int all_flag
, int ver_flag
,
387 Lisp_Object predicate
);
389 DEFUN ("file-name-completion", Ffile_name_completion
, Sfile_name_completion
,
391 doc
: /* Complete file name FILE in directory DIRECTORY.
392 Returns the longest string
393 common to all file names in DIRECTORY that start with FILE.
394 If there is only one and FILE matches it exactly, returns t.
395 Returns nil if DIRECTORY contains no name starting with FILE.
397 If PREDICATE is non-nil, call PREDICATE with each possible
398 completion (in absolute form) and ignore it if PREDICATE returns nil.
400 This function ignores some of the possible completions as
401 determined by the variable `completion-ignored-extensions', which see. */)
402 (Lisp_Object file
, Lisp_Object directory
, Lisp_Object predicate
)
405 directory
= Fexpand_file_name (directory
, Qnil
);
407 /* If the directory name has special constructs in it,
408 call the corresponding file handler. */
409 handler
= Ffind_file_name_handler (directory
, Qfile_name_completion
);
411 return call4 (handler
, Qfile_name_completion
, file
, directory
, predicate
);
413 /* If the file name has special constructs in it,
414 call the corresponding file handler. */
415 handler
= Ffind_file_name_handler (file
, Qfile_name_completion
);
417 return call4 (handler
, Qfile_name_completion
, file
, directory
, predicate
);
419 return file_name_completion (file
, directory
, 0, 0, predicate
);
422 DEFUN ("file-name-all-completions", Ffile_name_all_completions
,
423 Sfile_name_all_completions
, 2, 2, 0,
424 doc
: /* Return a list of all completions of file name FILE in directory DIRECTORY.
425 These are all file names in directory DIRECTORY which begin with FILE. */)
426 (Lisp_Object file
, Lisp_Object directory
)
429 directory
= Fexpand_file_name (directory
, Qnil
);
431 /* If the directory name has special constructs in it,
432 call the corresponding file handler. */
433 handler
= Ffind_file_name_handler (directory
, Qfile_name_all_completions
);
435 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
437 /* If the file name has special constructs in it,
438 call the corresponding file handler. */
439 handler
= Ffind_file_name_handler (file
, Qfile_name_all_completions
);
441 return call3 (handler
, Qfile_name_all_completions
, file
, directory
);
443 return file_name_completion (file
, directory
, 1, 0, Qnil
);
446 static int file_name_completion_stat (Lisp_Object dirname
, DIRENTRY
*dp
, struct stat
*st_addr
);
447 static Lisp_Object Qdefault_directory
;
450 file_name_completion (Lisp_Object file
, Lisp_Object dirname
, int all_flag
, int ver_flag
, Lisp_Object predicate
)
453 ptrdiff_t bestmatchsize
= 0;
455 /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded.
456 If ALL_FLAG is 0, BESTMATCH is either nil
457 or the best match so far, not decoded. */
458 Lisp_Object bestmatch
, tem
, elt
, name
;
459 Lisp_Object encoded_file
;
460 Lisp_Object encoded_dir
;
463 /* If includeall is zero, exclude files in completion-ignored-extensions as
464 well as "." and "..". Until shown otherwise, assume we can't exclude
467 ptrdiff_t count
= SPECPDL_INDEX ();
468 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
, gcpro5
;
474 #ifdef FILE_SYSTEM_CASE
475 file
= FILE_SYSTEM_CASE (file
);
478 encoded_file
= encoded_dir
= Qnil
;
479 GCPRO5 (file
, dirname
, bestmatch
, encoded_file
, encoded_dir
);
480 specbind (Qdefault_directory
, dirname
);
482 /* Do completion on the encoded file name
483 because the other names in the directory are (we presume)
484 encoded likewise. We decode the completed string at the end. */
485 /* Actually, this is not quite true any more: we do most of the completion
486 work with decoded file names, but we still do some filtering based
487 on the encoded file name. */
488 encoded_file
= STRING_MULTIBYTE (file
) ? ENCODE_FILE (file
) : file
;
490 encoded_dir
= ENCODE_FILE (dirname
);
493 d
= opendir (SSDATA (Fdirectory_file_name (encoded_dir
)));
496 report_file_error ("Opening directory", Fcons (dirname
, Qnil
));
498 record_unwind_protect (directory_files_internal_unwind
,
499 make_save_value (d
, 0));
501 /* Loop reading blocks */
502 /* (att3b compiler bug requires do a null comparison this way) */
526 if (! DIRENTRY_NONEMPTY (dp
)
527 || len
< SCHARS (encoded_file
)
528 || 0 <= scmp (dp
->d_name
, SSDATA (encoded_file
),
529 SCHARS (encoded_file
)))
532 if (file_name_completion_stat (encoded_dir
, dp
, &st
) < 0)
535 directoryp
= S_ISDIR (st
.st_mode
);
537 /* If all_flag is set, always include all.
538 It would not actually be helpful to the user to ignore any possible
539 completions when making a list of them. */
544 #if 0 /* FIXME: The `scmp' call compares an encoded and a decoded string. */
545 /* If this entry matches the current bestmatch, the only
546 thing it can do is increase matchcount, so don't bother
547 investigating it any further. */
548 if (!completion_ignore_case
549 /* The return result depends on whether it's the sole match. */
551 && !includeall
/* This match may allow includeall to 0. */
552 && len
>= bestmatchsize
553 && 0 > scmp (dp
->d_name
, SSDATA (bestmatch
), bestmatchsize
))
559 #ifndef TRIVIAL_DIRECTORY_ENTRY
560 #define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
562 /* "." and ".." are never interesting as completions, and are
563 actually in the way in a directory with only one file. */
564 if (TRIVIAL_DIRECTORY_ENTRY (dp
->d_name
))
566 else if (len
> SCHARS (encoded_file
))
567 /* Ignore directories if they match an element of
568 completion-ignored-extensions which ends in a slash. */
569 for (tem
= Vcompletion_ignored_extensions
;
570 CONSP (tem
); tem
= XCDR (tem
))
578 /* Need to encode ELT, since scmp compares unibyte
580 elt
= ENCODE_FILE (elt
);
581 elt_len
= SCHARS (elt
) - 1; /* -1 for trailing / */
585 if (p1
[elt_len
] != '/')
587 skip
= len
- elt_len
;
591 if (0 <= scmp (dp
->d_name
+ skip
, p1
, elt_len
))
598 /* Compare extensions-to-be-ignored against end of this file name */
599 /* if name is not an exact match against specified string */
600 if (len
> SCHARS (encoded_file
))
601 /* and exit this for loop if a match is found */
602 for (tem
= Vcompletion_ignored_extensions
;
603 CONSP (tem
); tem
= XCDR (tem
))
606 if (!STRINGP (elt
)) continue;
607 /* Need to encode ELT, since scmp compares unibyte
609 elt
= ENCODE_FILE (elt
);
610 skip
= len
- SCHARS (elt
);
611 if (skip
< 0) continue;
613 if (0 <= scmp (dp
->d_name
+ skip
,
621 /* If an ignored-extensions match was found,
622 don't process this name as a completion. */
626 if (!includeall
&& canexclude
)
627 /* We're not including all files and this file can be excluded. */
630 if (includeall
&& !canexclude
)
631 { /* If we have one non-excludable file, we want to exclude the
634 /* Throw away any previous excludable match found. */
640 /* FIXME: If we move this `decode' earlier we can eliminate
641 the repeated ENCODE_FILE on Vcompletion_ignored_extensions. */
642 name
= make_unibyte_string (dp
->d_name
, len
);
643 name
= DECODE_FILE (name
);
648 /* Ignore this element if it fails to match all the regexps. */
649 if (completion_ignore_case
)
651 for (regexps
= Vcompletion_regexp_list
; CONSP (regexps
);
652 regexps
= XCDR (regexps
))
653 if (fast_string_match_ignore_case (XCAR (regexps
), name
) < 0)
658 for (regexps
= Vcompletion_regexp_list
; CONSP (regexps
);
659 regexps
= XCDR (regexps
))
660 if (fast_string_match (XCAR (regexps
), name
) < 0)
668 /* This is a possible completion */
670 /* This completion is a directory; make it end with '/'. */
671 name
= Ffile_name_as_directory (name
);
673 /* Test the predicate, if any. */
674 if (!NILP (predicate
))
680 val
= call1 (predicate
, name
);
687 /* Suitably record this match. */
689 matchcount
+= matchcount
<= 1;
692 bestmatch
= Fcons (name
, bestmatch
);
693 else if (NILP (bestmatch
))
696 bestmatchsize
= SCHARS (name
);
700 Lisp_Object zero
= make_number (0);
701 /* FIXME: This is a copy of the code in Ftry_completion. */
702 ptrdiff_t compare
= min (bestmatchsize
, SCHARS (name
));
704 = Fcompare_strings (bestmatch
, zero
,
705 make_number (compare
),
707 make_number (compare
),
708 completion_ignore_case
? Qt
: Qnil
);
710 = (EQ (cmp
, Qt
) ? compare
711 : XINT (cmp
) < 0 ? - XINT (cmp
) - 1
714 if (completion_ignore_case
)
716 /* If this is an exact match except for case,
717 use it as the best match rather than one that is not
718 an exact match. This way, we get the case pattern
719 of the actual match. */
720 /* This tests that the current file is an exact match
721 but BESTMATCH is not (it is too long). */
722 if ((matchsize
== SCHARS (name
)
723 && matchsize
+ !!directoryp
< SCHARS (bestmatch
))
725 /* If there is no exact match ignoring case,
726 prefer a match that does not change the case
728 /* If there is more than one exact match aside from
729 case, and one of them is exact including case,
731 /* This == checks that, of current file and BESTMATCH,
732 either both or neither are exact. */
733 (((matchsize
== SCHARS (name
))
735 (matchsize
+ !!directoryp
== SCHARS (bestmatch
)))
736 && (cmp
= Fcompare_strings (name
, zero
,
737 make_number (SCHARS (file
)),
742 && (cmp
= Fcompare_strings (bestmatch
, zero
,
743 make_number (SCHARS (file
)),
750 bestmatchsize
= matchsize
;
752 /* If the best completion so far is reduced to the string
753 we're trying to complete, then we already know there's no
754 other completion, so there's no point looking any further. */
755 if (matchsize
<= SCHARS (file
)
756 && !includeall
/* A future match may allow includeall to 0. */
757 /* If completion-ignore-case is non-nil, don't
758 short-circuit because we want to find the best
759 possible match *including* case differences. */
760 && (!completion_ignore_case
|| matchsize
== 0)
761 /* The return value depends on whether it's the sole match. */
769 /* This closes the directory. */
770 bestmatch
= unbind_to (count
, bestmatch
);
772 if (all_flag
|| NILP (bestmatch
))
774 /* Return t if the supplied string is an exact match (counting case);
775 it does not require any change to be made. */
776 if (matchcount
== 1 && !NILP (Fequal (bestmatch
, file
)))
778 bestmatch
= Fsubstring (bestmatch
, make_number (0),
779 make_number (bestmatchsize
));
783 /* Compare exactly LEN chars of strings at S1 and S2,
784 ignoring case if appropriate.
785 Return -1 if strings match,
786 else number of chars that match at the beginning. */
789 scmp (const char *s1
, const char *s2
, ptrdiff_t len
)
791 register ptrdiff_t l
= len
;
793 if (completion_ignore_case
)
796 && (downcase ((unsigned char) *s1
++)
797 == downcase ((unsigned char) *s2
++)))
802 while (l
&& *s1
++ == *s2
++)
812 file_name_completion_stat (Lisp_Object dirname
, DIRENTRY
*dp
, struct stat
*st_addr
)
814 ptrdiff_t len
= NAMLEN (dp
);
815 ptrdiff_t pos
= SCHARS (dirname
);
819 SAFE_ALLOCA (fullname
, char *, len
+ pos
+ 2);
822 /* Some fields of struct stat are *very* expensive to compute on MS-DOS,
823 but aren't required here. Avoid computing the following fields:
824 st_inode, st_size and st_nlink for directories, and the execute bits
825 in st_mode for non-directory files with non-standard extensions. */
827 unsigned short save_djstat_flags
= _djstat_flags
;
829 _djstat_flags
= _STAT_INODE
| _STAT_EXEC_MAGIC
| _STAT_DIRSIZE
;
832 memcpy (fullname
, SDATA (dirname
), pos
);
833 if (!IS_DIRECTORY_SEP (fullname
[pos
- 1]))
834 fullname
[pos
++] = DIRECTORY_SEP
;
836 memcpy (fullname
+ pos
, dp
->d_name
, len
);
837 fullname
[pos
+ len
] = 0;
839 /* We want to return success if a link points to a nonexistent file,
840 but we want to return the status for what the link points to,
841 in case it is a directory. */
842 value
= lstat (fullname
, st_addr
);
843 if (value
== 0 && S_ISLNK (st_addr
->st_mode
))
844 stat (fullname
, st_addr
);
846 _djstat_flags
= save_djstat_flags
;
853 stat_uname (struct stat
*st
)
858 struct passwd
*pw
= (struct passwd
*) getpwuid (st
->st_uid
);
868 stat_gname (struct stat
*st
)
873 struct group
*gr
= (struct group
*) getgrgid (st
->st_gid
);
882 DEFUN ("file-attributes", Ffile_attributes
, Sfile_attributes
, 1, 2, 0,
883 doc
: /* Return a list of attributes of file FILENAME.
884 Value is nil if specified file cannot be opened.
886 ID-FORMAT specifies the preferred format of attributes uid and gid (see
887 below) - valid values are 'string and 'integer. The latter is the
888 default, but we plan to change that, so you should specify a non-nil value
889 for ID-FORMAT if you use the returned uid or gid.
891 Elements of the attribute list are:
892 0. t for directory, string (name linked to) for symbolic link, or nil.
893 1. Number of links to file.
894 2. File uid as a string or a number. If a string value cannot be
895 looked up, a numeric value, either an integer or a float, is returned.
896 3. File gid, likewise.
897 4. Last access time, as a list of integers (HIGH LOW USEC PSEC) in the
898 same style as (current-time).
899 (See a note below about access time on FAT-based filesystems.)
900 5. Last modification time, likewise. This is the time of the last
901 change to the file's contents.
902 6. Last status change time, likewise. This is the time of last change
903 to the file's attributes: owner and group, access mode bits, etc.
905 This is a floating point number if the size is too large for an integer.
906 8. File modes, as a string of ten letters or dashes as in ls -l.
907 9. t if file's gid would change if file were deleted and recreated.
908 10. inode number. If it is larger than what an Emacs integer can hold,
909 this is of the form (HIGH . LOW): first the high bits, then the low 16 bits.
910 If even HIGH is too large for an Emacs integer, this is instead of the form
911 (HIGH MIDDLE . LOW): first the high bits, then the middle 24 bits,
912 and finally the low 16 bits.
913 11. Filesystem device number. If it is larger than what the Emacs
914 integer can hold, this is a cons cell, similar to the inode number.
916 On most filesystems, the combination of the inode and the device
917 number uniquely identifies the file.
919 On MS-Windows, performance depends on `w32-get-true-file-attributes',
922 On some FAT-based filesystems, only the date of last access is recorded,
923 so last access time will always be midnight of that day. */)
924 (Lisp_Object filename
, Lisp_Object id_format
)
926 Lisp_Object values
[12];
934 /* An array to hold the mode string generated by filemodestring,
935 including its terminating space and null byte. */
936 char modes
[sizeof "-rwxr-xr-x "];
940 char *uname
= NULL
, *gname
= NULL
;
942 filename
= Fexpand_file_name (filename
, Qnil
);
944 /* If the file name has special constructs in it,
945 call the corresponding file handler. */
946 handler
= Ffind_file_name_handler (filename
, Qfile_attributes
);
948 { /* Only pass the extra arg if it is used to help backward compatibility
949 with old file handlers which do not implement the new arg. --Stef */
950 if (NILP (id_format
))
951 return call2 (handler
, Qfile_attributes
, filename
);
953 return call3 (handler
, Qfile_attributes
, filename
, id_format
);
957 encoded
= ENCODE_FILE (filename
);
960 if (lstat (SSDATA (encoded
), &s
) < 0)
963 values
[0] = (S_ISLNK (s
.st_mode
) ? Ffile_symlink_p (filename
)
964 : S_ISDIR (s
.st_mode
) ? Qt
: Qnil
);
965 values
[1] = make_number (s
.st_nlink
);
967 if (!(NILP (id_format
) || EQ (id_format
, Qinteger
)))
970 uname
= stat_uname (&s
);
971 gname
= stat_gname (&s
);
975 values
[2] = DECODE_SYSTEM (build_string (uname
));
977 values
[2] = make_fixnum_or_float (s
.st_uid
);
979 values
[3] = DECODE_SYSTEM (build_string (gname
));
981 values
[3] = make_fixnum_or_float (s
.st_gid
);
983 values
[4] = make_lisp_time (get_stat_atime (&s
));
984 values
[5] = make_lisp_time (get_stat_mtime (&s
));
985 values
[6] = make_lisp_time (get_stat_ctime (&s
));
987 /* If the file size is a 4-byte type, assume that files of sizes in
988 the 2-4 GiB range wrap around to negative values, as this is a
989 common bug on older 32-bit platforms. */
990 if (sizeof (s
.st_size
) == 4)
991 values
[7] = make_fixnum_or_float (s
.st_size
& 0xffffffffu
);
993 values
[7] = make_fixnum_or_float (s
.st_size
);
995 filemodestring (&s
, modes
);
996 values
[8] = make_string (modes
, 10);
997 #ifdef BSD4_2 /* file gid will be dir gid */
998 dirname
= Ffile_name_directory (filename
);
999 if (! NILP (dirname
))
1000 encoded
= ENCODE_FILE (dirname
);
1001 if (! NILP (dirname
) && stat (SDATA (encoded
), &sdir
) == 0)
1002 values
[9] = (sdir
.st_gid
!= s
.st_gid
) ? Qt
: Qnil
;
1003 else /* if we can't tell, assume worst */
1005 #else /* file gid will be egid */
1006 values
[9] = (s
.st_gid
!= getegid ()) ? Qt
: Qnil
;
1007 #endif /* not BSD4_2 */
1008 values
[10] = INTEGER_TO_CONS (s
.st_ino
);
1009 values
[11] = INTEGER_TO_CONS (s
.st_dev
);
1011 return Flist (sizeof (values
) / sizeof (values
[0]), values
);
1014 DEFUN ("file-attributes-lessp", Ffile_attributes_lessp
, Sfile_attributes_lessp
, 2, 2, 0,
1015 doc
: /* Return t if first arg file attributes list is less than second.
1016 Comparison is in lexicographic order and case is significant. */)
1017 (Lisp_Object f1
, Lisp_Object f2
)
1019 return Fstring_lessp (Fcar (f1
), Fcar (f2
));
1023 DEFUN ("system-users", Fsystem_users
, Ssystem_users
, 0, 0, 0,
1024 doc
: /* Return a list of user names currently registered in the system.
1025 If we don't know how to determine that on this platform, just
1026 return a list with one element, taken from `user-real-login-name'. */)
1029 Lisp_Object users
= Qnil
;
1030 #if defined HAVE_GETPWENT && defined HAVE_ENDPWENT
1033 while ((pw
= getpwent ()))
1034 users
= Fcons (DECODE_SYSTEM (build_string (pw
->pw_name
)), users
);
1038 if (EQ (users
, Qnil
))
1039 /* At least current user is always known. */
1040 users
= Fcons (Vuser_real_login_name
, Qnil
);
1044 DEFUN ("system-groups", Fsystem_groups
, Ssystem_groups
, 0, 0, 0,
1045 doc
: /* Return a list of user group names currently registered in the system.
1046 The value may be nil if not supported on this platform. */)
1049 Lisp_Object groups
= Qnil
;
1050 #if defined HAVE_GETGRENT && defined HAVE_ENDGRENT
1053 while ((gr
= getgrent ()))
1054 groups
= Fcons (DECODE_SYSTEM (build_string (gr
->gr_name
)), groups
);
1062 syms_of_dired (void)
1064 DEFSYM (Qdirectory_files
, "directory-files");
1065 DEFSYM (Qdirectory_files_and_attributes
, "directory-files-and-attributes");
1066 DEFSYM (Qfile_name_completion
, "file-name-completion");
1067 DEFSYM (Qfile_name_all_completions
, "file-name-all-completions");
1068 DEFSYM (Qfile_attributes
, "file-attributes");
1069 DEFSYM (Qfile_attributes_lessp
, "file-attributes-lessp");
1070 DEFSYM (Qdefault_directory
, "default-directory");
1072 defsubr (&Sdirectory_files
);
1073 defsubr (&Sdirectory_files_and_attributes
);
1074 defsubr (&Sfile_name_completion
);
1075 defsubr (&Sfile_name_all_completions
);
1076 defsubr (&Sfile_attributes
);
1077 defsubr (&Sfile_attributes_lessp
);
1078 defsubr (&Ssystem_users
);
1079 defsubr (&Ssystem_groups
);
1081 DEFVAR_LISP ("completion-ignored-extensions", Vcompletion_ignored_extensions
,
1082 doc
: /* Completion ignores file names ending in any string in this list.
1083 It does not ignore them if all possible completions end in one of
1084 these strings or when displaying a list of completions.
1085 It ignores directory names if they match any string in this list which
1086 ends in a slash. */);
1087 Vcompletion_ignored_extensions
= Qnil
;