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 }