aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c42
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
2698DEFUN ("fileio--truename", Ffileio__truename, Sfileio__truename, 1, 1, 0,
2699 doc: /* Return the true name of FILENAME, without file name handlers.
2700
2701The returned string is an absolute file name that does not involve
2702\".\", \"..\", or symbolic links. Signal an error if FILENAME does
2703not 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
2697DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, 2738DEFUN ("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);