diff options
| author | Paul Eggert | 2019-09-06 14:30:33 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-09-06 14:31:38 -0700 |
| commit | a59839d7556ef85058e09b005f0ff32e59b20ec3 (patch) | |
| tree | 7e4eb3909246dde8efdcaecd77cfd41e75b93593 /src | |
| parent | 5b117511aa1b5c451773891b505a7098a67f9532 (diff) | |
| download | emacs-a59839d7556ef85058e09b005f0ff32e59b20ec3.tar.gz emacs-a59839d7556ef85058e09b005f0ff32e59b20ec3.zip | |
file-truename now uses realpath for local files
This uses fewer syscalls on GNU/Linux and other GNUish platforms.
* lisp/files.el (file-truename): Try fileio--truename
if there are no handlers.
* src/fileio.c: Include stdlib.h, for realpath.
(Ffileio__truename): New function.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fileio.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/fileio.c b/src/fileio.c index 968a55e5956..adf2f3d9705 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 20 | #include <config.h> | 20 | #include <config.h> |
| 21 | #include <limits.h> | 21 | #include <limits.h> |
| 22 | #include <fcntl.h> | 22 | #include <fcntl.h> |
| 23 | #include <stdlib.h> | ||
| 23 | #include "sysstdio.h" | 24 | #include "sysstdio.h" |
| 24 | #include <sys/types.h> | 25 | #include <sys/types.h> |
| 25 | #include <sys/stat.h> | 26 | #include <sys/stat.h> |
| @@ -2693,6 +2694,46 @@ file_name_absolute_p (char const *filename) | |||
| 2693 | && (!filename[1] || IS_DIRECTORY_SEP (filename[1]) | 2694 | && (!filename[1] || IS_DIRECTORY_SEP (filename[1]) |
| 2694 | || user_homedir (&filename[1])))); | 2695 | || user_homedir (&filename[1])))); |
| 2695 | } | 2696 | } |
| 2697 | |||
| 2698 | DEFUN ("fileio--truename", Ffileio__truename, Sfileio__truename, 1, 1, 0, | ||
| 2699 | doc: /* Return the true name of FILENAME, without file name handlers. | ||
| 2700 | |||
| 2701 | The returned string is an absolute file name that does not involve | ||
| 2702 | \".\", \"..\", or symbolic links. Signal an error if FILENAME does | ||
| 2703 | not exist or if its true name cannot be determined. */) | ||
| 2704 | (Lisp_Object filename) | ||
| 2705 | { | ||
| 2706 | CHECK_STRING (filename); | ||
| 2707 | Lisp_Object absname = Fexpand_file_name (filename, Qnil); | ||
| 2708 | Lisp_Object encoded_absname = ENCODE_FILE (absname); | ||
| 2709 | ptrdiff_t encoded_len = SBYTES (encoded_absname); | ||
| 2710 | char *encoded = SSDATA (encoded_absname); | ||
| 2711 | bool append_slash = (1 < encoded_len | ||
| 2712 | && IS_DIRECTORY_SEP (encoded[encoded_len - 1]) | ||
| 2713 | && !IS_DIRECTORY_SEP (encoded[encoded_len - 2])); | ||
| 2714 | char *truename = realpath (encoded, NULL); | ||
| 2715 | if (!truename) | ||
| 2716 | report_file_error ("Deriving truename", filename); | ||
| 2717 | ptrdiff_t truename_len = strlen (truename); | ||
| 2718 | if (truename_len == encoded_len - append_slash | ||
| 2719 | && memcmp (truename, encoded, truename_len) == 0) | ||
| 2720 | { | ||
| 2721 | /* ABSNAME is already the true name. */ | ||
| 2722 | xfree (truename); | ||
| 2723 | return absname; | ||
| 2724 | } | ||
| 2725 | else | ||
| 2726 | { | ||
| 2727 | if (append_slash) | ||
| 2728 | { | ||
| 2729 | truename = xrealloc (truename, truename_len + 2); | ||
| 2730 | strcpy (truename + truename_len, "/"); | ||
| 2731 | } | ||
| 2732 | Lisp_Object unibyte_truename = build_unibyte_string (truename); | ||
| 2733 | xfree (truename); | ||
| 2734 | return DECODE_FILE (unibyte_truename); | ||
| 2735 | } | ||
| 2736 | } | ||
| 2696 | 2737 | ||
| 2697 | DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, | 2738 | DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, |
| 2698 | doc: /* Return t if file FILENAME exists (whether or not you can read it). | 2739 | doc: /* Return t if file FILENAME exists (whether or not you can read it). |
| @@ -6428,6 +6469,7 @@ This includes interactive calls to `delete-file' and | |||
| 6428 | defsubr (&Sadd_name_to_file); | 6469 | defsubr (&Sadd_name_to_file); |
| 6429 | defsubr (&Smake_symbolic_link); | 6470 | defsubr (&Smake_symbolic_link); |
| 6430 | defsubr (&Sfile_name_absolute_p); | 6471 | defsubr (&Sfile_name_absolute_p); |
| 6472 | defsubr (&Sfileio__truename); | ||
| 6431 | defsubr (&Sfile_exists_p); | 6473 | defsubr (&Sfile_exists_p); |
| 6432 | defsubr (&Sfile_executable_p); | 6474 | defsubr (&Sfile_executable_p); |
| 6433 | defsubr (&Sfile_readable_p); | 6475 | defsubr (&Sfile_readable_p); |