diff options
Diffstat (limited to 'src/fileio.c')
| -rw-r--r-- | src/fileio.c | 183 |
1 files changed, 100 insertions, 83 deletions
diff --git a/src/fileio.c b/src/fileio.c index d9c7397c2de..4ba1c5914e8 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -396,13 +396,6 @@ Otherwise return a directory name. | |||
| 396 | Given a Unix syntax file name, returns a string ending in slash. */) | 396 | Given a Unix syntax file name, returns a string ending in slash. */) |
| 397 | (Lisp_Object filename) | 397 | (Lisp_Object filename) |
| 398 | { | 398 | { |
| 399 | #ifndef DOS_NT | ||
| 400 | register const char *beg; | ||
| 401 | #else | ||
| 402 | register char *beg; | ||
| 403 | Lisp_Object tem_fn; | ||
| 404 | #endif | ||
| 405 | register const char *p; | ||
| 406 | Lisp_Object handler; | 399 | Lisp_Object handler; |
| 407 | 400 | ||
| 408 | CHECK_STRING (filename); | 401 | CHECK_STRING (filename); |
| @@ -417,12 +410,8 @@ Given a Unix syntax file name, returns a string ending in slash. */) | |||
| 417 | return STRINGP (handled_name) ? handled_name : Qnil; | 410 | return STRINGP (handled_name) ? handled_name : Qnil; |
| 418 | } | 411 | } |
| 419 | 412 | ||
| 420 | #ifdef DOS_NT | 413 | char *beg = SSDATA (filename); |
| 421 | beg = xlispstrdupa (filename); | 414 | char const *p = beg + SBYTES (filename); |
| 422 | #else | ||
| 423 | beg = SSDATA (filename); | ||
| 424 | #endif | ||
| 425 | p = beg + SBYTES (filename); | ||
| 426 | 415 | ||
| 427 | while (p != beg && !IS_DIRECTORY_SEP (p[-1]) | 416 | while (p != beg && !IS_DIRECTORY_SEP (p[-1]) |
| 428 | #ifdef DOS_NT | 417 | #ifdef DOS_NT |
| @@ -438,6 +427,11 @@ Given a Unix syntax file name, returns a string ending in slash. */) | |||
| 438 | return Qnil; | 427 | return Qnil; |
| 439 | #ifdef DOS_NT | 428 | #ifdef DOS_NT |
| 440 | /* Expansion of "c:" to drive and default directory. */ | 429 | /* Expansion of "c:" to drive and default directory. */ |
| 430 | Lisp_Object tem_fn; | ||
| 431 | USE_SAFE_ALLOCA; | ||
| 432 | SAFE_ALLOCA_STRING (beg, filename); | ||
| 433 | p = beg + (p - SSDATA (filename)); | ||
| 434 | |||
| 441 | if (p[-1] == ':') | 435 | if (p[-1] == ':') |
| 442 | { | 436 | { |
| 443 | /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */ | 437 | /* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */ |
| @@ -481,6 +475,7 @@ Given a Unix syntax file name, returns a string ending in slash. */) | |||
| 481 | dostounix_filename (beg); | 475 | dostounix_filename (beg); |
| 482 | tem_fn = make_specified_string (beg, -1, p - beg, 0); | 476 | tem_fn = make_specified_string (beg, -1, p - beg, 0); |
| 483 | } | 477 | } |
| 478 | SAFE_FREE (); | ||
| 484 | return tem_fn; | 479 | return tem_fn; |
| 485 | #else /* DOS_NT */ | 480 | #else /* DOS_NT */ |
| 486 | return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename)); | 481 | return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename)); |
| @@ -733,7 +728,7 @@ Lisp_Object | |||
| 733 | make_temp_name (Lisp_Object prefix, bool base64_p) | 728 | make_temp_name (Lisp_Object prefix, bool base64_p) |
| 734 | { | 729 | { |
| 735 | Lisp_Object val, encoded_prefix; | 730 | Lisp_Object val, encoded_prefix; |
| 736 | int len; | 731 | ptrdiff_t len; |
| 737 | printmax_t pid; | 732 | printmax_t pid; |
| 738 | char *p, *data; | 733 | char *p, *data; |
| 739 | char pidbuf[INT_BUFSIZE_BOUND (printmax_t)]; | 734 | char pidbuf[INT_BUFSIZE_BOUND (printmax_t)]; |
| @@ -847,8 +842,6 @@ probably use `make-temp-file' instead, except in three circumstances: | |||
| 847 | return make_temp_name (prefix, 0); | 842 | return make_temp_name (prefix, 0); |
| 848 | } | 843 | } |
| 849 | 844 | ||
| 850 | |||
| 851 | |||
| 852 | DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, | 845 | DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, |
| 853 | doc: /* Convert filename NAME to absolute, and canonicalize it. | 846 | doc: /* Convert filename NAME to absolute, and canonicalize it. |
| 854 | Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative | 847 | Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative |
| @@ -878,7 +871,9 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 878 | /* These point to SDATA and need to be careful with string-relocation | 871 | /* These point to SDATA and need to be careful with string-relocation |
| 879 | during GC (via DECODE_FILE). */ | 872 | during GC (via DECODE_FILE). */ |
| 880 | char *nm; | 873 | char *nm; |
| 874 | char *nmlim; | ||
| 881 | const char *newdir; | 875 | const char *newdir; |
| 876 | const char *newdirlim; | ||
| 882 | /* This should only point to alloca'd data. */ | 877 | /* This should only point to alloca'd data. */ |
| 883 | char *target; | 878 | char *target; |
| 884 | 879 | ||
| @@ -886,10 +881,10 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 886 | struct passwd *pw; | 881 | struct passwd *pw; |
| 887 | #ifdef DOS_NT | 882 | #ifdef DOS_NT |
| 888 | int drive = 0; | 883 | int drive = 0; |
| 889 | bool collapse_newdir = 1; | 884 | bool collapse_newdir = true; |
| 890 | bool is_escaped = 0; | 885 | bool is_escaped = 0; |
| 891 | #endif /* DOS_NT */ | 886 | #endif /* DOS_NT */ |
| 892 | ptrdiff_t length; | 887 | ptrdiff_t length, nbytes; |
| 893 | Lisp_Object handler, result, handled_name; | 888 | Lisp_Object handler, result, handled_name; |
| 894 | bool multibyte; | 889 | bool multibyte; |
| 895 | Lisp_Object hdir; | 890 | Lisp_Object hdir; |
| @@ -1018,8 +1013,9 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1018 | default_directory = Fdowncase (default_directory); | 1013 | default_directory = Fdowncase (default_directory); |
| 1019 | #endif | 1014 | #endif |
| 1020 | 1015 | ||
| 1021 | /* Make a local copy of nm[] to protect it from GC in DECODE_FILE below. */ | 1016 | /* Make a local copy of NAME to protect it from GC in DECODE_FILE below. */ |
| 1022 | nm = xlispstrdupa (name); | 1017 | SAFE_ALLOCA_STRING (nm, name); |
| 1018 | nmlim = nm + SBYTES (name); | ||
| 1023 | 1019 | ||
| 1024 | #ifdef DOS_NT | 1020 | #ifdef DOS_NT |
| 1025 | /* Note if special escape prefix is present, but remove for now. */ | 1021 | /* Note if special escape prefix is present, but remove for now. */ |
| @@ -1104,7 +1100,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1104 | if (IS_DIRECTORY_SEP (nm[1])) | 1100 | if (IS_DIRECTORY_SEP (nm[1])) |
| 1105 | { | 1101 | { |
| 1106 | if (strcmp (nm, SSDATA (name)) != 0) | 1102 | if (strcmp (nm, SSDATA (name)) != 0) |
| 1107 | name = make_specified_string (nm, -1, strlen (nm), multibyte); | 1103 | name = make_specified_string (nm, -1, nmlim - nm, multibyte); |
| 1108 | } | 1104 | } |
| 1109 | else | 1105 | else |
| 1110 | #endif | 1106 | #endif |
| @@ -1115,18 +1111,19 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1115 | 1111 | ||
| 1116 | name = make_specified_string (nm, -1, p - nm, multibyte); | 1112 | name = make_specified_string (nm, -1, p - nm, multibyte); |
| 1117 | temp[0] = DRIVE_LETTER (drive); | 1113 | temp[0] = DRIVE_LETTER (drive); |
| 1118 | name = concat2 (build_string (temp), name); | 1114 | AUTO_STRING (drive_prefix, temp); |
| 1115 | name = concat2 (drive_prefix, name); | ||
| 1119 | } | 1116 | } |
| 1120 | #ifdef WINDOWSNT | 1117 | #ifdef WINDOWSNT |
| 1121 | if (!NILP (Vw32_downcase_file_names)) | 1118 | if (!NILP (Vw32_downcase_file_names)) |
| 1122 | name = Fdowncase (name); | 1119 | name = Fdowncase (name); |
| 1123 | #endif | 1120 | #endif |
| 1124 | return name; | ||
| 1125 | #else /* not DOS_NT */ | 1121 | #else /* not DOS_NT */ |
| 1126 | if (strcmp (nm, SSDATA (name)) == 0) | 1122 | if (strcmp (nm, SSDATA (name)) != 0) |
| 1127 | return name; | 1123 | name = make_specified_string (nm, -1, nmlim - nm, multibyte); |
| 1128 | return make_specified_string (nm, -1, strlen (nm), multibyte); | ||
| 1129 | #endif /* not DOS_NT */ | 1124 | #endif /* not DOS_NT */ |
| 1125 | SAFE_FREE (); | ||
| 1126 | return name; | ||
| 1130 | } | 1127 | } |
| 1131 | } | 1128 | } |
| 1132 | 1129 | ||
| @@ -1146,7 +1143,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1146 | return an absolute name, if the final prefix is not absolute we | 1143 | return an absolute name, if the final prefix is not absolute we |
| 1147 | append it to the current working directory. */ | 1144 | append it to the current working directory. */ |
| 1148 | 1145 | ||
| 1149 | newdir = 0; | 1146 | newdir = newdirlim = 0; |
| 1150 | 1147 | ||
| 1151 | if (nm[0] == '~') /* prefix ~ */ | 1148 | if (nm[0] == '~') /* prefix ~ */ |
| 1152 | { | 1149 | { |
| @@ -1156,7 +1153,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1156 | Lisp_Object tem; | 1153 | Lisp_Object tem; |
| 1157 | 1154 | ||
| 1158 | if (!(newdir = egetenv ("HOME"))) | 1155 | if (!(newdir = egetenv ("HOME"))) |
| 1159 | newdir = ""; | 1156 | newdir = newdirlim = ""; |
| 1160 | nm++; | 1157 | nm++; |
| 1161 | /* `egetenv' may return a unibyte string, which will bite us since | 1158 | /* `egetenv' may return a unibyte string, which will bite us since |
| 1162 | we expect the directory to be multibyte. */ | 1159 | we expect the directory to be multibyte. */ |
| @@ -1171,13 +1168,15 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1171 | else | 1168 | else |
| 1172 | #endif | 1169 | #endif |
| 1173 | tem = build_string (newdir); | 1170 | tem = build_string (newdir); |
| 1171 | newdirlim = newdir + SBYTES (tem); | ||
| 1174 | if (multibyte && !STRING_MULTIBYTE (tem)) | 1172 | if (multibyte && !STRING_MULTIBYTE (tem)) |
| 1175 | { | 1173 | { |
| 1176 | hdir = DECODE_FILE (tem); | 1174 | hdir = DECODE_FILE (tem); |
| 1177 | newdir = SSDATA (hdir); | 1175 | newdir = SSDATA (hdir); |
| 1176 | newdirlim = newdir + SBYTES (hdir); | ||
| 1178 | } | 1177 | } |
| 1179 | #ifdef DOS_NT | 1178 | #ifdef DOS_NT |
| 1180 | collapse_newdir = 0; | 1179 | collapse_newdir = false; |
| 1181 | #endif | 1180 | #endif |
| 1182 | } | 1181 | } |
| 1183 | else /* ~user/filename */ | 1182 | else /* ~user/filename */ |
| @@ -1201,14 +1200,16 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1201 | bite us since we expect the directory to be | 1200 | bite us since we expect the directory to be |
| 1202 | multibyte. */ | 1201 | multibyte. */ |
| 1203 | tem = build_string (newdir); | 1202 | tem = build_string (newdir); |
| 1203 | newdirlim = newdir + SBYTES (tem); | ||
| 1204 | if (multibyte && !STRING_MULTIBYTE (tem)) | 1204 | if (multibyte && !STRING_MULTIBYTE (tem)) |
| 1205 | { | 1205 | { |
| 1206 | hdir = DECODE_FILE (tem); | 1206 | hdir = DECODE_FILE (tem); |
| 1207 | newdir = SSDATA (hdir); | 1207 | newdir = SSDATA (hdir); |
| 1208 | newdirlim = newdir + SBYTES (hdir); | ||
| 1208 | } | 1209 | } |
| 1209 | nm = p; | 1210 | nm = p; |
| 1210 | #ifdef DOS_NT | 1211 | #ifdef DOS_NT |
| 1211 | collapse_newdir = 0; | 1212 | collapse_newdir = false; |
| 1212 | #endif | 1213 | #endif |
| 1213 | } | 1214 | } |
| 1214 | 1215 | ||
| @@ -1234,8 +1235,11 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1234 | Lisp_Object tem = build_string (adir); | 1235 | Lisp_Object tem = build_string (adir); |
| 1235 | 1236 | ||
| 1236 | tem = DECODE_FILE (tem); | 1237 | tem = DECODE_FILE (tem); |
| 1238 | newdirlim = adir + SBYTES (tem); | ||
| 1237 | memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); | 1239 | memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); |
| 1238 | } | 1240 | } |
| 1241 | else | ||
| 1242 | newdirlim = adir + strlen (adir); | ||
| 1239 | } | 1243 | } |
| 1240 | if (!adir) | 1244 | if (!adir) |
| 1241 | { | 1245 | { |
| @@ -1245,6 +1249,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1245 | adir[1] = ':'; | 1249 | adir[1] = ':'; |
| 1246 | adir[2] = '/'; | 1250 | adir[2] = '/'; |
| 1247 | adir[3] = 0; | 1251 | adir[3] = 0; |
| 1252 | newdirlim = adir + 3; | ||
| 1248 | } | 1253 | } |
| 1249 | newdir = adir; | 1254 | newdir = adir; |
| 1250 | } | 1255 | } |
| @@ -1265,6 +1270,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1265 | && !newdir) | 1270 | && !newdir) |
| 1266 | { | 1271 | { |
| 1267 | newdir = SSDATA (default_directory); | 1272 | newdir = SSDATA (default_directory); |
| 1273 | newdirlim = newdir + SBYTES (default_directory); | ||
| 1268 | #ifdef DOS_NT | 1274 | #ifdef DOS_NT |
| 1269 | /* Note if special escape prefix is present, but remove for now. */ | 1275 | /* Note if special escape prefix is present, but remove for now. */ |
| 1270 | if (newdir[0] == '/' && newdir[1] == ':') | 1276 | if (newdir[0] == '/' && newdir[1] == ':') |
| @@ -1309,12 +1315,15 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1309 | } | 1315 | } |
| 1310 | if (!IS_DIRECTORY_SEP (nm[0])) | 1316 | if (!IS_DIRECTORY_SEP (nm[0])) |
| 1311 | { | 1317 | { |
| 1312 | ptrdiff_t newlen = strlen (newdir); | 1318 | ptrdiff_t nmlen = nmlim - nm; |
| 1313 | char *tmp = alloca (newlen + file_name_as_directory_slop | 1319 | ptrdiff_t newdirlen = newdirlim - newdir; |
| 1314 | + strlen (nm) + 1); | 1320 | char *tmp = alloca (newdirlen + file_name_as_directory_slop |
| 1315 | file_name_as_directory (tmp, newdir, newlen, multibyte); | 1321 | + nmlen + 1); |
| 1316 | strcat (tmp, nm); | 1322 | ptrdiff_t dlen = file_name_as_directory (tmp, newdir, newdirlen, |
| 1323 | multibyte); | ||
| 1324 | memcpy (tmp + dlen, nm, nmlen + 1); | ||
| 1317 | nm = tmp; | 1325 | nm = tmp; |
| 1326 | nmlim = nm + dlen + nmlen; | ||
| 1318 | } | 1327 | } |
| 1319 | adir = alloca (adir_size); | 1328 | adir = alloca (adir_size); |
| 1320 | if (drive) | 1329 | if (drive) |
| @@ -1329,8 +1338,11 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1329 | Lisp_Object tem = build_string (adir); | 1338 | Lisp_Object tem = build_string (adir); |
| 1330 | 1339 | ||
| 1331 | tem = DECODE_FILE (tem); | 1340 | tem = DECODE_FILE (tem); |
| 1341 | newdirlim = adir + SBYTES (tem); | ||
| 1332 | memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); | 1342 | memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); |
| 1333 | } | 1343 | } |
| 1344 | else | ||
| 1345 | newdirlim = adir + strlen (adir); | ||
| 1334 | newdir = adir; | 1346 | newdir = adir; |
| 1335 | } | 1347 | } |
| 1336 | 1348 | ||
| @@ -1349,35 +1361,32 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1349 | if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]) | 1361 | if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]) |
| 1350 | && !IS_DIRECTORY_SEP (newdir[2])) | 1362 | && !IS_DIRECTORY_SEP (newdir[2])) |
| 1351 | { | 1363 | { |
| 1352 | char *adir = strcpy (alloca (strlen (newdir) + 1), newdir); | 1364 | char *adir = strcpy (alloca (newdirlim - newdir + 1), newdir); |
| 1353 | char *p = adir + 2; | 1365 | char *p = adir + 2; |
| 1354 | while (*p && !IS_DIRECTORY_SEP (*p)) p++; | 1366 | while (*p && !IS_DIRECTORY_SEP (*p)) p++; |
| 1355 | p++; | 1367 | p++; |
| 1356 | while (*p && !IS_DIRECTORY_SEP (*p)) p++; | 1368 | while (*p && !IS_DIRECTORY_SEP (*p)) p++; |
| 1357 | *p = 0; | 1369 | *p = 0; |
| 1358 | newdir = adir; | 1370 | newdir = adir; |
| 1371 | newdirlim = newdir + strlen (adir); | ||
| 1359 | } | 1372 | } |
| 1360 | else | 1373 | else |
| 1361 | #endif | 1374 | #endif |
| 1362 | newdir = ""; | 1375 | newdir = newdirlim = ""; |
| 1363 | } | 1376 | } |
| 1364 | } | 1377 | } |
| 1365 | #endif /* DOS_NT */ | 1378 | #endif /* DOS_NT */ |
| 1366 | 1379 | ||
| 1367 | if (newdir) | 1380 | /* Ignore any slash at the end of newdir, unless newdir is |
| 1368 | { | 1381 | just "/" or "//". */ |
| 1369 | /* Ignore any slash at the end of newdir, unless newdir is | 1382 | length = newdirlim - newdir; |
| 1370 | just "/" or "//". */ | 1383 | while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) |
| 1371 | length = strlen (newdir); | 1384 | && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) |
| 1372 | while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) | 1385 | length--; |
| 1373 | && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) | ||
| 1374 | length--; | ||
| 1375 | } | ||
| 1376 | else | ||
| 1377 | length = 0; | ||
| 1378 | 1386 | ||
| 1379 | /* Now concatenate the directory and name to new space in the stack frame. */ | 1387 | /* Now concatenate the directory and name to new space in the stack frame. */ |
| 1380 | tlen = length + file_name_as_directory_slop + strlen (nm) + 1; | 1388 | tlen = length + file_name_as_directory_slop + (nmlim - nm) + 1; |
| 1389 | eassert (tlen > file_name_as_directory_slop + 1); | ||
| 1381 | #ifdef DOS_NT | 1390 | #ifdef DOS_NT |
| 1382 | /* Reserve space for drive specifier and escape prefix, since either | 1391 | /* Reserve space for drive specifier and escape prefix, since either |
| 1383 | or both may need to be inserted. (The Microsoft x86 compiler | 1392 | or both may need to be inserted. (The Microsoft x86 compiler |
| @@ -1388,6 +1397,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1388 | target = SAFE_ALLOCA (tlen); | 1397 | target = SAFE_ALLOCA (tlen); |
| 1389 | #endif /* not DOS_NT */ | 1398 | #endif /* not DOS_NT */ |
| 1390 | *target = 0; | 1399 | *target = 0; |
| 1400 | nbytes = 0; | ||
| 1391 | 1401 | ||
| 1392 | if (newdir) | 1402 | if (newdir) |
| 1393 | { | 1403 | { |
| @@ -1405,13 +1415,14 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1405 | { | 1415 | { |
| 1406 | memcpy (target, newdir, length); | 1416 | memcpy (target, newdir, length); |
| 1407 | target[length] = 0; | 1417 | target[length] = 0; |
| 1418 | nbytes = length; | ||
| 1408 | } | 1419 | } |
| 1409 | } | 1420 | } |
| 1410 | else | 1421 | else |
| 1411 | file_name_as_directory (target, newdir, length, multibyte); | 1422 | nbytes = file_name_as_directory (target, newdir, length, multibyte); |
| 1412 | } | 1423 | } |
| 1413 | 1424 | ||
| 1414 | strcat (target, nm); | 1425 | memcpy (target + nbytes, nm, nmlim - nm + 1); |
| 1415 | 1426 | ||
| 1416 | /* Now canonicalize by removing `//', `/.' and `/foo/..' if they | 1427 | /* Now canonicalize by removing `//', `/.' and `/foo/..' if they |
| 1417 | appear. */ | 1428 | appear. */ |
| @@ -1717,7 +1728,8 @@ search_embedded_absfilename (char *nm, char *endp) | |||
| 1717 | for (s = p; *s && !IS_DIRECTORY_SEP (*s); s++); | 1728 | for (s = p; *s && !IS_DIRECTORY_SEP (*s); s++); |
| 1718 | if (p[0] == '~' && s > p + 1) /* We've got "/~something/". */ | 1729 | if (p[0] == '~' && s > p + 1) /* We've got "/~something/". */ |
| 1719 | { | 1730 | { |
| 1720 | char *o = alloca (s - p + 1); | 1731 | USE_SAFE_ALLOCA; |
| 1732 | char *o = SAFE_ALLOCA (s - p + 1); | ||
| 1721 | struct passwd *pw; | 1733 | struct passwd *pw; |
| 1722 | memcpy (o, p, s - p); | 1734 | memcpy (o, p, s - p); |
| 1723 | o [s - p] = 0; | 1735 | o [s - p] = 0; |
| @@ -1728,6 +1740,7 @@ search_embedded_absfilename (char *nm, char *endp) | |||
| 1728 | block_input (); | 1740 | block_input (); |
| 1729 | pw = getpwnam (o + 1); | 1741 | pw = getpwnam (o + 1); |
| 1730 | unblock_input (); | 1742 | unblock_input (); |
| 1743 | SAFE_FREE (); | ||
| 1731 | if (pw) | 1744 | if (pw) |
| 1732 | return p; | 1745 | return p; |
| 1733 | } | 1746 | } |
| @@ -1776,7 +1789,8 @@ those `/' is discarded. */) | |||
| 1776 | /* Always work on a copy of the string, in case GC happens during | 1789 | /* Always work on a copy of the string, in case GC happens during |
| 1777 | decode of environment variables, causing the original Lisp_String | 1790 | decode of environment variables, causing the original Lisp_String |
| 1778 | data to be relocated. */ | 1791 | data to be relocated. */ |
| 1779 | nm = xlispstrdupa (filename); | 1792 | USE_SAFE_ALLOCA; |
| 1793 | SAFE_ALLOCA_STRING (nm, filename); | ||
| 1780 | 1794 | ||
| 1781 | #ifdef DOS_NT | 1795 | #ifdef DOS_NT |
| 1782 | dostounix_filename (nm); | 1796 | dostounix_filename (nm); |
| @@ -1790,8 +1804,13 @@ those `/' is discarded. */) | |||
| 1790 | /* Start over with the new string, so we check the file-name-handler | 1804 | /* Start over with the new string, so we check the file-name-handler |
| 1791 | again. Important with filenames like "/home/foo//:/hello///there" | 1805 | again. Important with filenames like "/home/foo//:/hello///there" |
| 1792 | which would substitute to "/:/hello///there" rather than "/there". */ | 1806 | which would substitute to "/:/hello///there" rather than "/there". */ |
| 1793 | return Fsubstitute_in_file_name | 1807 | { |
| 1794 | (make_specified_string (p, -1, endp - p, multibyte)); | 1808 | Lisp_Object result |
| 1809 | = (Fsubstitute_in_file_name | ||
| 1810 | (make_specified_string (p, -1, endp - p, multibyte))); | ||
| 1811 | SAFE_FREE (); | ||
| 1812 | return result; | ||
| 1813 | } | ||
| 1795 | 1814 | ||
| 1796 | /* See if any variables are substituted into the string. */ | 1815 | /* See if any variables are substituted into the string. */ |
| 1797 | 1816 | ||
| @@ -1813,6 +1832,7 @@ those `/' is discarded. */) | |||
| 1813 | if (!NILP (Vw32_downcase_file_names)) | 1832 | if (!NILP (Vw32_downcase_file_names)) |
| 1814 | filename = Fdowncase (filename); | 1833 | filename = Fdowncase (filename); |
| 1815 | #endif | 1834 | #endif |
| 1835 | SAFE_FREE (); | ||
| 1816 | return filename; | 1836 | return filename; |
| 1817 | } | 1837 | } |
| 1818 | 1838 | ||
| @@ -1831,14 +1851,14 @@ those `/' is discarded. */) | |||
| 1831 | { | 1851 | { |
| 1832 | Lisp_Object xname = make_specified_string (xnm, -1, x - xnm, multibyte); | 1852 | Lisp_Object xname = make_specified_string (xnm, -1, x - xnm, multibyte); |
| 1833 | 1853 | ||
| 1834 | xname = Fdowncase (xname); | 1854 | filename = Fdowncase (xname); |
| 1835 | return xname; | ||
| 1836 | } | 1855 | } |
| 1837 | else | 1856 | else |
| 1838 | #endif | 1857 | #endif |
| 1839 | return (xnm == SSDATA (filename) | 1858 | if (xnm != SSDATA (filename)) |
| 1840 | ? filename | 1859 | filename = make_specified_string (xnm, -1, x - xnm, multibyte); |
| 1841 | : make_specified_string (xnm, -1, x - xnm, multibyte)); | 1860 | SAFE_FREE (); |
| 1861 | return filename; | ||
| 1842 | } | 1862 | } |
| 1843 | 1863 | ||
| 1844 | /* A slightly faster and more convenient way to get | 1864 | /* A slightly faster and more convenient way to get |
| @@ -2671,7 +2691,10 @@ emacs_readlinkat (int fd, char const *filename) | |||
| 2671 | 2691 | ||
| 2672 | val = build_unibyte_string (buf); | 2692 | val = build_unibyte_string (buf); |
| 2673 | if (buf[0] == '/' && strchr (buf, ':')) | 2693 | if (buf[0] == '/' && strchr (buf, ':')) |
| 2674 | val = concat2 (build_unibyte_string ("/:"), val); | 2694 | { |
| 2695 | AUTO_STRING (slash_colon, "/:"); | ||
| 2696 | val = concat2 (slash_colon, val); | ||
| 2697 | } | ||
| 2675 | if (buf != readlink_buf) | 2698 | if (buf != readlink_buf) |
| 2676 | xfree (buf); | 2699 | xfree (buf); |
| 2677 | val = DECODE_FILE (val); | 2700 | val = DECODE_FILE (val); |
| @@ -2765,23 +2788,24 @@ searchable directory. */) | |||
| 2765 | } | 2788 | } |
| 2766 | 2789 | ||
| 2767 | absname = ENCODE_FILE (absname); | 2790 | absname = ENCODE_FILE (absname); |
| 2768 | return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil; | 2791 | return file_accessible_directory_p (absname) ? Qt : Qnil; |
| 2769 | } | 2792 | } |
| 2770 | 2793 | ||
| 2771 | /* If FILE is a searchable directory or a symlink to a | 2794 | /* If FILE is a searchable directory or a symlink to a |
| 2772 | searchable directory, return true. Otherwise return | 2795 | searchable directory, return true. Otherwise return |
| 2773 | false and set errno to an error number. */ | 2796 | false and set errno to an error number. */ |
| 2774 | bool | 2797 | bool |
| 2775 | file_accessible_directory_p (char const *file) | 2798 | file_accessible_directory_p (Lisp_Object file) |
| 2776 | { | 2799 | { |
| 2777 | #ifdef DOS_NT | 2800 | #ifdef DOS_NT |
| 2778 | /* There's no need to test whether FILE is searchable, as the | 2801 | /* There's no need to test whether FILE is searchable, as the |
| 2779 | searchable/executable bit is invented on DOS_NT platforms. */ | 2802 | searchable/executable bit is invented on DOS_NT platforms. */ |
| 2780 | return file_directory_p (file); | 2803 | return file_directory_p (SSDATA (file)); |
| 2781 | #else | 2804 | #else |
| 2782 | /* On POSIXish platforms, use just one system call; this avoids a | 2805 | /* On POSIXish platforms, use just one system call; this avoids a |
| 2783 | race and is typically faster. */ | 2806 | race and is typically faster. */ |
| 2784 | ptrdiff_t len = strlen (file); | 2807 | const char *data = SSDATA (file); |
| 2808 | ptrdiff_t len = SBYTES (file); | ||
| 2785 | char const *dir; | 2809 | char const *dir; |
| 2786 | bool ok; | 2810 | bool ok; |
| 2787 | int saved_errno; | 2811 | int saved_errno; |
| @@ -2793,15 +2817,15 @@ file_accessible_directory_p (char const *file) | |||
| 2793 | "/" and "//" are distinct on some platforms, whereas "/", "///", | 2817 | "/" and "//" are distinct on some platforms, whereas "/", "///", |
| 2794 | "////", etc. are all equivalent. */ | 2818 | "////", etc. are all equivalent. */ |
| 2795 | if (! len) | 2819 | if (! len) |
| 2796 | dir = file; | 2820 | dir = data; |
| 2797 | else | 2821 | else |
| 2798 | { | 2822 | { |
| 2799 | /* Just check for trailing '/' when deciding whether to append '/'. | 2823 | /* Just check for trailing '/' when deciding whether to append '/'. |
| 2800 | That's simpler than testing the two special cases "/" and "//", | 2824 | That's simpler than testing the two special cases "/" and "//", |
| 2801 | and it's a safe optimization here. */ | 2825 | and it's a safe optimization here. */ |
| 2802 | char *buf = SAFE_ALLOCA (len + 3); | 2826 | char *buf = SAFE_ALLOCA (len + 3); |
| 2803 | memcpy (buf, file, len); | 2827 | memcpy (buf, data, len); |
| 2804 | strcpy (buf + len, &"/."[file[len - 1] == '/']); | 2828 | strcpy (buf + len, &"/."[data[len - 1] == '/']); |
| 2805 | dir = buf; | 2829 | dir = buf; |
| 2806 | } | 2830 | } |
| 2807 | 2831 | ||
| @@ -3624,13 +3648,14 @@ by calling `format-decode', which see. */) | |||
| 3624 | report_file_error ("Read error", orig_filename); | 3648 | report_file_error ("Read error", orig_filename); |
| 3625 | else if (nread > 0) | 3649 | else if (nread > 0) |
| 3626 | { | 3650 | { |
| 3651 | AUTO_STRING (name, " *code-converting-work*"); | ||
| 3627 | struct buffer *prev = current_buffer; | 3652 | struct buffer *prev = current_buffer; |
| 3628 | Lisp_Object workbuf; | 3653 | Lisp_Object workbuf; |
| 3629 | struct buffer *buf; | 3654 | struct buffer *buf; |
| 3630 | 3655 | ||
| 3631 | record_unwind_current_buffer (); | 3656 | record_unwind_current_buffer (); |
| 3632 | 3657 | ||
| 3633 | workbuf = Fget_buffer_create (build_string (" *code-converting-work*")); | 3658 | workbuf = Fget_buffer_create (name); |
| 3634 | buf = XBUFFER (workbuf); | 3659 | buf = XBUFFER (workbuf); |
| 3635 | 3660 | ||
| 3636 | delete_all_overlays (buf); | 3661 | delete_all_overlays (buf); |
| @@ -5292,20 +5317,12 @@ If BUF is omitted or nil, it defaults to the current buffer. | |||
| 5292 | See Info node `(elisp)Modification Time' for more details. */) | 5317 | See Info node `(elisp)Modification Time' for more details. */) |
| 5293 | (Lisp_Object buf) | 5318 | (Lisp_Object buf) |
| 5294 | { | 5319 | { |
| 5295 | struct buffer *b; | 5320 | struct buffer *b = decode_buffer (buf); |
| 5296 | struct stat st; | 5321 | struct stat st; |
| 5297 | Lisp_Object handler; | 5322 | Lisp_Object handler; |
| 5298 | Lisp_Object filename; | 5323 | Lisp_Object filename; |
| 5299 | struct timespec mtime; | 5324 | struct timespec mtime; |
| 5300 | 5325 | ||
| 5301 | if (NILP (buf)) | ||
| 5302 | b = current_buffer; | ||
| 5303 | else | ||
| 5304 | { | ||
| 5305 | CHECK_BUFFER (buf); | ||
| 5306 | b = XBUFFER (buf); | ||
| 5307 | } | ||
| 5308 | |||
| 5309 | if (!STRINGP (BVAR (b, filename))) return Qt; | 5326 | if (!STRINGP (BVAR (b, filename))) return Qt; |
| 5310 | if (b->modtime.tv_nsec == UNKNOWN_MODTIME_NSECS) return Qt; | 5327 | if (b->modtime.tv_nsec == UNKNOWN_MODTIME_NSECS) return Qt; |
| 5311 | 5328 | ||
| @@ -5399,7 +5416,7 @@ An argument specifies the modification time value to use | |||
| 5399 | static Lisp_Object | 5416 | static Lisp_Object |
| 5400 | auto_save_error (Lisp_Object error_val) | 5417 | auto_save_error (Lisp_Object error_val) |
| 5401 | { | 5418 | { |
| 5402 | Lisp_Object args[3], msg; | 5419 | Lisp_Object msg; |
| 5403 | int i; | 5420 | int i; |
| 5404 | struct gcpro gcpro1; | 5421 | struct gcpro gcpro1; |
| 5405 | 5422 | ||
| @@ -5407,10 +5424,10 @@ auto_save_error (Lisp_Object error_val) | |||
| 5407 | 5424 | ||
| 5408 | ring_bell (XFRAME (selected_frame)); | 5425 | ring_bell (XFRAME (selected_frame)); |
| 5409 | 5426 | ||
| 5410 | args[0] = build_string ("Auto-saving %s: %s"); | 5427 | AUTO_STRING (format, "Auto-saving %s: %s"); |
| 5411 | args[1] = BVAR (current_buffer, name); | 5428 | msg = Fformat (3, ((Lisp_Object []) |
| 5412 | args[2] = Ferror_message_string (error_val); | 5429 | {format, BVAR (current_buffer, name), |
| 5413 | msg = Fformat (3, args); | 5430 | Ferror_message_string (error_val)})); |
| 5414 | GCPRO1 (msg); | 5431 | GCPRO1 (msg); |
| 5415 | 5432 | ||
| 5416 | for (i = 0; i < 3; ++i) | 5433 | for (i = 0; i < 3; ++i) |