Mercurial > emacs
comparison src/lread.c @ 44222:885bedb3a37b
(openp, Fload): Encode the file name before pasing it
to `stat', `access', and `emacs_open'.
(openp): GCPRO the encoded file name. Don't recompute Lisp
strings unnecessarily.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Fri, 29 Mar 2002 12:37:22 +0000 |
parents | ae392efb1660 |
children | a3bd03ed0409 |
comparison
equal
deleted
inserted
replaced
44221:b13eadb97179 | 44222:885bedb3a37b |
---|---|
32 #include "charset.h" | 32 #include "charset.h" |
33 #include <epaths.h> | 33 #include <epaths.h> |
34 #include "commands.h" | 34 #include "commands.h" |
35 #include "keyboard.h" | 35 #include "keyboard.h" |
36 #include "termhooks.h" | 36 #include "termhooks.h" |
37 #include "coding.h" | |
37 | 38 |
38 #ifdef lint | 39 #ifdef lint |
39 #include <sys/inode.h> | 40 #include <sys/inode.h> |
40 #endif /* lint */ | 41 #endif /* lint */ |
41 | 42 |
631 register int fd = -1; | 632 register int fd = -1; |
632 register Lisp_Object lispstream; | 633 register Lisp_Object lispstream; |
633 int count = specpdl_ptr - specpdl; | 634 int count = specpdl_ptr - specpdl; |
634 Lisp_Object temp; | 635 Lisp_Object temp; |
635 struct gcpro gcpro1; | 636 struct gcpro gcpro1; |
636 Lisp_Object found; | 637 Lisp_Object found, efound; |
637 /* 1 means we printed the ".el is newer" message. */ | 638 /* 1 means we printed the ".el is newer" message. */ |
638 int newer = 0; | 639 int newer = 0; |
639 /* 1 means we are loading a compiled file. */ | 640 /* 1 means we are loading a compiled file. */ |
640 int compiled = 0; | 641 int compiled = 0; |
641 Lisp_Object handler; | 642 Lisp_Object handler; |
768 message_with_string ("File `%s' not compiled in Emacs", found, 1); | 769 message_with_string ("File `%s' not compiled in Emacs", found, 1); |
769 } | 770 } |
770 | 771 |
771 compiled = 1; | 772 compiled = 1; |
772 | 773 |
774 GCPRO1 (efound); | |
775 efound = ENCODE_FILE (found); | |
776 | |
773 #ifdef DOS_NT | 777 #ifdef DOS_NT |
774 fmode = "rb"; | 778 fmode = "rb"; |
775 #endif /* DOS_NT */ | 779 #endif /* DOS_NT */ |
776 stat ((char *)XSTRING (found)->data, &s1); | 780 stat ((char *)XSTRING (efound)->data, &s1); |
777 XSTRING (found)->data[STRING_BYTES (XSTRING (found)) - 1] = 0; | 781 XSTRING (efound)->data[STRING_BYTES (XSTRING (efound)) - 1] = 0; |
778 result = stat ((char *)XSTRING (found)->data, &s2); | 782 result = stat ((char *)XSTRING (efound)->data, &s2); |
779 XSTRING (found)->data[STRING_BYTES (XSTRING (found)) - 1] = 'c'; | 783 XSTRING (efound)->data[STRING_BYTES (XSTRING (efound)) - 1] = 'c'; |
780 | 784 UNGCPRO; |
785 | |
781 if (result >= 0 && (unsigned) s1.st_mtime < (unsigned) s2.st_mtime) | 786 if (result >= 0 && (unsigned) s1.st_mtime < (unsigned) s2.st_mtime) |
782 { | 787 { |
783 /* Make the progress messages mention that source is newer. */ | 788 /* Make the progress messages mention that source is newer. */ |
784 newer = 1; | 789 newer = 1; |
785 | 790 |
810 } | 815 } |
811 } | 816 } |
812 | 817 |
813 #ifdef WINDOWSNT | 818 #ifdef WINDOWSNT |
814 emacs_close (fd); | 819 emacs_close (fd); |
815 stream = fopen ((char *) XSTRING (found)->data, fmode); | 820 GCPRO1 (efound); |
821 efound = ENCODE_FILE (found); | |
822 stream = fopen ((char *) XSTRING (efound)->data, fmode); | |
823 UNGCPRO; | |
816 #else /* not WINDOWSNT */ | 824 #else /* not WINDOWSNT */ |
817 stream = fdopen (fd, fmode); | 825 stream = fdopen (fd, fmode); |
818 #endif /* not WINDOWSNT */ | 826 #endif /* not WINDOWSNT */ |
819 if (stream == 0) | 827 if (stream == 0) |
820 { | 828 { |
966 register char *fn = buf; | 974 register char *fn = buf; |
967 int absolute = 0; | 975 int absolute = 0; |
968 int want_size; | 976 int want_size; |
969 Lisp_Object filename; | 977 Lisp_Object filename; |
970 struct stat st; | 978 struct stat st; |
971 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 979 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; |
972 Lisp_Object string, tail; | 980 Lisp_Object string, tail, encoded_fn; |
973 int max_suffix_len = 0; | 981 int max_suffix_len = 0; |
974 | 982 |
975 for (tail = suffixes; CONSP (tail); tail = XCDR (tail)) | 983 for (tail = suffixes; CONSP (tail); tail = XCDR (tail)) |
976 { | 984 { |
977 CHECK_STRING_CAR (tail); | 985 CHECK_STRING_CAR (tail); |
978 max_suffix_len = max (max_suffix_len, | 986 max_suffix_len = max (max_suffix_len, |
979 STRING_BYTES (XSTRING (XCAR (tail)))); | 987 STRING_BYTES (XSTRING (XCAR (tail)))); |
980 } | 988 } |
981 | 989 |
982 string = filename = Qnil; | 990 string = filename = Qnil; |
983 GCPRO5 (str, string, filename, path, suffixes); | 991 GCPRO6 (str, string, filename, path, suffixes, encoded_fn); |
984 | 992 |
985 if (storeptr) | 993 if (storeptr) |
986 *storeptr = Qnil; | 994 *storeptr = Qnil; |
987 | 995 |
988 if (complete_filename_p (str)) | 996 if (complete_filename_p (str)) |
989 absolute = 1; | 997 absolute = 1; |
1012 for (tail = NILP (suffixes) ? default_suffixes : suffixes; | 1020 for (tail = NILP (suffixes) ? default_suffixes : suffixes; |
1013 CONSP (tail); tail = XCDR (tail)) | 1021 CONSP (tail); tail = XCDR (tail)) |
1014 { | 1022 { |
1015 int lsuffix = STRING_BYTES (XSTRING (XCAR (tail))); | 1023 int lsuffix = STRING_BYTES (XSTRING (XCAR (tail))); |
1016 Lisp_Object handler; | 1024 Lisp_Object handler; |
1025 int exists; | |
1017 | 1026 |
1018 /* Concatenate path element/specified name with the suffix. | 1027 /* Concatenate path element/specified name with the suffix. |
1019 If the directory starts with /:, remove that. */ | 1028 If the directory starts with /:, remove that. */ |
1020 if (XSTRING (filename)->size > 2 | 1029 if (XSTRING (filename)->size > 2 |
1021 && XSTRING (filename)->data[0] == '/' | 1030 && XSTRING (filename)->data[0] == '/' |
1032 fn[STRING_BYTES (XSTRING (filename))] = 0; | 1041 fn[STRING_BYTES (XSTRING (filename))] = 0; |
1033 } | 1042 } |
1034 | 1043 |
1035 if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */ | 1044 if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */ |
1036 strncat (fn, XSTRING (XCAR (tail))->data, lsuffix); | 1045 strncat (fn, XSTRING (XCAR (tail))->data, lsuffix); |
1037 | 1046 |
1038 /* Check that the file exists and is not a directory. */ | 1047 /* Check that the file exists and is not a directory. */ |
1039 /* We used to only check for handlers on non-absolute file names: | 1048 /* We used to only check for handlers on non-absolute file names: |
1040 if (absolute) | 1049 if (absolute) |
1041 handler = Qnil; | 1050 handler = Qnil; |
1042 else | 1051 else |
1043 handler = Ffind_file_name_handler (filename, Qfile_exists_p); | 1052 handler = Ffind_file_name_handler (filename, Qfile_exists_p); |
1044 It's not clear why that was the case and it breaks things like | 1053 It's not clear why that was the case and it breaks things like |
1045 (load "/bar.el") where the file is actually "/bar.el.gz". */ | 1054 (load "/bar.el") where the file is actually "/bar.el.gz". */ |
1046 handler = Ffind_file_name_handler (filename, Qfile_exists_p); | 1055 handler = Ffind_file_name_handler (filename, Qfile_exists_p); |
1056 string = build_string (fn); | |
1047 if (!NILP (handler) && !exec_only) | 1057 if (!NILP (handler) && !exec_only) |
1048 { | 1058 { |
1049 int exists; | |
1050 | |
1051 string = build_string (fn); | |
1052 exists = !NILP (Ffile_readable_p (string)); | 1059 exists = !NILP (Ffile_readable_p (string)); |
1053 if (exists && !NILP (Ffile_directory_p (build_string (fn)))) | 1060 if (exists && !NILP (Ffile_directory_p (string))) |
1054 exists = 0; | 1061 exists = 0; |
1055 | 1062 |
1056 if (exists) | 1063 if (exists) |
1057 { | 1064 { |
1058 /* We succeeded; return this descriptor and filename. */ | 1065 /* We succeeded; return this descriptor and filename. */ |
1059 if (storeptr) | 1066 if (storeptr) |
1060 *storeptr = build_string (fn); | 1067 *storeptr = string; |
1061 UNGCPRO; | 1068 UNGCPRO; |
1062 return -2; | 1069 return -2; |
1063 } | 1070 } |
1064 } | 1071 } |
1065 else | 1072 else |
1066 { | 1073 { |
1067 int exists = (stat (fn, &st) >= 0 | 1074 char *pfn; |
1068 && (st.st_mode & S_IFMT) != S_IFDIR); | 1075 |
1076 encoded_fn = ENCODE_FILE (string); | |
1077 pfn = XSTRING (encoded_fn)->data; | |
1078 exists = (stat (pfn, &st) >= 0 | |
1079 && (st.st_mode & S_IFMT) != S_IFDIR); | |
1069 if (exists) | 1080 if (exists) |
1070 { | 1081 { |
1071 /* Check that we can access or open it. */ | 1082 /* Check that we can access or open it. */ |
1072 if (exec_only) | 1083 if (exec_only) |
1073 fd = (access (fn, X_OK) == 0) ? 1 : -1; | 1084 fd = (access (pfn, X_OK) == 0) ? 1 : -1; |
1074 else | 1085 else |
1075 fd = emacs_open (fn, O_RDONLY, 0); | 1086 fd = emacs_open (pfn, O_RDONLY, 0); |
1076 | 1087 |
1077 if (fd >= 0) | 1088 if (fd >= 0) |
1078 { | 1089 { |
1079 /* We succeeded; return this descriptor and filename. */ | 1090 /* We succeeded; return this descriptor and filename. */ |
1080 if (storeptr) | 1091 if (storeptr) |
1081 *storeptr = build_string (fn); | 1092 *storeptr = string; |
1082 UNGCPRO; | 1093 UNGCPRO; |
1083 return fd; | 1094 return fd; |
1084 } | 1095 } |
1085 } | 1096 } |
1086 } | 1097 } |