diff options
Diffstat (limited to 'src/lread.c')
| -rw-r--r-- | src/lread.c | 92 |
1 files changed, 50 insertions, 42 deletions
diff --git a/src/lread.c b/src/lread.c index 3a82e0057e2..5859a2f85a9 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -1403,7 +1403,7 @@ Returns the file's name in absolute form, or nil if not found. | |||
| 1403 | If SUFFIXES is non-nil, it should be a list of suffixes to append to | 1403 | If SUFFIXES is non-nil, it should be a list of suffixes to append to |
| 1404 | file name when searching. | 1404 | file name when searching. |
| 1405 | If non-nil, PREDICATE is used instead of `file-readable-p'. | 1405 | If non-nil, PREDICATE is used instead of `file-readable-p'. |
| 1406 | PREDICATE can also be an integer to pass to the access(2) function, | 1406 | PREDICATE can also be an integer to pass to the faccessat(2) function, |
| 1407 | in which case file-name-handlers are ignored. | 1407 | in which case file-name-handlers are ignored. |
| 1408 | This function will normally skip directories, so if you want it to find | 1408 | This function will normally skip directories, so if you want it to find |
| 1409 | directories, make sure the PREDICATE function returns `dir-ok' for them. */) | 1409 | directories, make sure the PREDICATE function returns `dir-ok' for them. */) |
| @@ -1441,7 +1441,6 @@ static Lisp_Object Qdir_ok; | |||
| 1441 | int | 1441 | int |
| 1442 | openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) | 1442 | openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) |
| 1443 | { | 1443 | { |
| 1444 | int fd; | ||
| 1445 | ptrdiff_t fn_size = 100; | 1444 | ptrdiff_t fn_size = 100; |
| 1446 | char buf[100]; | 1445 | char buf[100]; |
| 1447 | char *fn = buf; | 1446 | char *fn = buf; |
| @@ -1496,7 +1495,6 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto | |||
| 1496 | { | 1495 | { |
| 1497 | ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail)); | 1496 | ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail)); |
| 1498 | Lisp_Object handler; | 1497 | Lisp_Object handler; |
| 1499 | bool exists; | ||
| 1500 | 1498 | ||
| 1501 | /* Concatenate path element/specified name with the suffix. | 1499 | /* Concatenate path element/specified name with the suffix. |
| 1502 | If the directory starts with /:, remove that. */ | 1500 | If the directory starts with /:, remove that. */ |
| @@ -1520,6 +1518,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto | |||
| 1520 | handler = Ffind_file_name_handler (string, Qfile_exists_p); | 1518 | handler = Ffind_file_name_handler (string, Qfile_exists_p); |
| 1521 | if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) | 1519 | if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) |
| 1522 | { | 1520 | { |
| 1521 | bool exists; | ||
| 1523 | if (NILP (predicate)) | 1522 | if (NILP (predicate)) |
| 1524 | exists = !NILP (Ffile_readable_p (string)); | 1523 | exists = !NILP (Ffile_readable_p (string)); |
| 1525 | else | 1524 | else |
| @@ -1541,37 +1540,40 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto | |||
| 1541 | } | 1540 | } |
| 1542 | else | 1541 | else |
| 1543 | { | 1542 | { |
| 1544 | #ifndef WINDOWSNT | 1543 | int fd; |
| 1545 | struct stat st; | ||
| 1546 | #endif | ||
| 1547 | const char *pfn; | 1544 | const char *pfn; |
| 1548 | 1545 | ||
| 1549 | encoded_fn = ENCODE_FILE (string); | 1546 | encoded_fn = ENCODE_FILE (string); |
| 1550 | pfn = SSDATA (encoded_fn); | 1547 | pfn = SSDATA (encoded_fn); |
| 1551 | #ifdef WINDOWSNT | ||
| 1552 | exists = access (pfn, F_OK) == 0 && access (pfn, D_OK) < 0; | ||
| 1553 | #else | ||
| 1554 | exists = (stat (pfn, &st) == 0 && ! S_ISDIR (st.st_mode)); | ||
| 1555 | #endif | ||
| 1556 | if (exists) | ||
| 1557 | { | ||
| 1558 | /* Check that we can access or open it. */ | ||
| 1559 | if (NATNUMP (predicate)) | ||
| 1560 | fd = (((XFASTINT (predicate) & ~INT_MAX) == 0 | ||
| 1561 | && access (pfn, XFASTINT (predicate)) == 0) | ||
| 1562 | ? 1 : -1); | ||
| 1563 | else | ||
| 1564 | fd = emacs_open (pfn, O_RDONLY, 0); | ||
| 1565 | 1548 | ||
| 1566 | if (fd >= 0) | 1549 | /* Check that we can access or open it. */ |
| 1550 | if (NATNUMP (predicate)) | ||
| 1551 | fd = (((XFASTINT (predicate) & ~INT_MAX) == 0 | ||
| 1552 | && (faccessat (AT_FDCWD, pfn, XFASTINT (predicate), | ||
| 1553 | AT_EACCESS) | ||
| 1554 | == 0) | ||
| 1555 | && ! file_directory_p (pfn)) | ||
| 1556 | ? 1 : -1); | ||
| 1557 | else | ||
| 1558 | { | ||
| 1559 | struct stat st; | ||
| 1560 | fd = emacs_open (pfn, O_RDONLY, 0); | ||
| 1561 | if (0 <= fd | ||
| 1562 | && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode))) | ||
| 1567 | { | 1563 | { |
| 1568 | /* We succeeded; return this descriptor and filename. */ | 1564 | emacs_close (fd); |
| 1569 | if (storeptr) | 1565 | fd = -1; |
| 1570 | *storeptr = string; | ||
| 1571 | UNGCPRO; | ||
| 1572 | return fd; | ||
| 1573 | } | 1566 | } |
| 1574 | } | 1567 | } |
| 1568 | |||
| 1569 | if (fd >= 0) | ||
| 1570 | { | ||
| 1571 | /* We succeeded; return this descriptor and filename. */ | ||
| 1572 | if (storeptr) | ||
| 1573 | *storeptr = string; | ||
| 1574 | UNGCPRO; | ||
| 1575 | return fd; | ||
| 1576 | } | ||
| 1575 | } | 1577 | } |
| 1576 | } | 1578 | } |
| 1577 | if (absolute) | 1579 | if (absolute) |
| @@ -4087,9 +4089,8 @@ load_path_check (void) | |||
| 4087 | if (STRINGP (dirfile)) | 4089 | if (STRINGP (dirfile)) |
| 4088 | { | 4090 | { |
| 4089 | dirfile = Fdirectory_file_name (dirfile); | 4091 | dirfile = Fdirectory_file_name (dirfile); |
| 4090 | if (access (SSDATA (dirfile), 0) < 0) | 4092 | if (! file_accessible_directory_p (SSDATA (dirfile))) |
| 4091 | dir_warning ("Warning: Lisp directory `%s' does not exist.\n", | 4093 | dir_warning ("Lisp directory", XCAR (path_tail)); |
| 4092 | XCAR (path_tail)); | ||
| 4093 | } | 4094 | } |
| 4094 | } | 4095 | } |
| 4095 | } | 4096 | } |
| @@ -4201,11 +4202,11 @@ init_lread (void) | |||
| 4201 | Lisp_Object tem, tem1; | 4202 | Lisp_Object tem, tem1; |
| 4202 | 4203 | ||
| 4203 | /* Add to the path the lisp subdir of the installation | 4204 | /* Add to the path the lisp subdir of the installation |
| 4204 | dir, if it exists. Note: in out-of-tree builds, | 4205 | dir, if it is accessible. Note: in out-of-tree builds, |
| 4205 | this directory is empty save for Makefile. */ | 4206 | this directory is empty save for Makefile. */ |
| 4206 | tem = Fexpand_file_name (build_string ("lisp"), | 4207 | tem = Fexpand_file_name (build_string ("lisp"), |
| 4207 | Vinstallation_directory); | 4208 | Vinstallation_directory); |
| 4208 | tem1 = Ffile_exists_p (tem); | 4209 | tem1 = Ffile_accessible_directory_p (tem); |
| 4209 | if (!NILP (tem1)) | 4210 | if (!NILP (tem1)) |
| 4210 | { | 4211 | { |
| 4211 | if (NILP (Fmember (tem, Vload_path))) | 4212 | if (NILP (Fmember (tem, Vload_path))) |
| @@ -4222,10 +4223,10 @@ init_lread (void) | |||
| 4222 | Lisp dirs instead. */ | 4223 | Lisp dirs instead. */ |
| 4223 | Vload_path = nconc2 (Vload_path, dump_path); | 4224 | Vload_path = nconc2 (Vload_path, dump_path); |
| 4224 | 4225 | ||
| 4225 | /* Add leim under the installation dir, if it exists. */ | 4226 | /* Add leim under the installation dir, if it is accessible. */ |
| 4226 | tem = Fexpand_file_name (build_string ("leim"), | 4227 | tem = Fexpand_file_name (build_string ("leim"), |
| 4227 | Vinstallation_directory); | 4228 | Vinstallation_directory); |
| 4228 | tem1 = Ffile_exists_p (tem); | 4229 | tem1 = Ffile_accessible_directory_p (tem); |
| 4229 | if (!NILP (tem1)) | 4230 | if (!NILP (tem1)) |
| 4230 | { | 4231 | { |
| 4231 | if (NILP (Fmember (tem, Vload_path))) | 4232 | if (NILP (Fmember (tem, Vload_path))) |
| @@ -4237,7 +4238,7 @@ init_lread (void) | |||
| 4237 | { | 4238 | { |
| 4238 | tem = Fexpand_file_name (build_string ("site-lisp"), | 4239 | tem = Fexpand_file_name (build_string ("site-lisp"), |
| 4239 | Vinstallation_directory); | 4240 | Vinstallation_directory); |
| 4240 | tem1 = Ffile_exists_p (tem); | 4241 | tem1 = Ffile_accessible_directory_p (tem); |
| 4241 | if (!NILP (tem1)) | 4242 | if (!NILP (tem1)) |
| 4242 | { | 4243 | { |
| 4243 | if (NILP (Fmember (tem, Vload_path))) | 4244 | if (NILP (Fmember (tem, Vload_path))) |
| @@ -4282,7 +4283,7 @@ init_lread (void) | |||
| 4282 | { | 4283 | { |
| 4283 | tem = Fexpand_file_name (build_string ("site-lisp"), | 4284 | tem = Fexpand_file_name (build_string ("site-lisp"), |
| 4284 | Vsource_directory); | 4285 | Vsource_directory); |
| 4285 | tem1 = Ffile_exists_p (tem); | 4286 | tem1 = Ffile_accessible_directory_p (tem); |
| 4286 | if (!NILP (tem1)) | 4287 | if (!NILP (tem1)) |
| 4287 | { | 4288 | { |
| 4288 | if (NILP (Fmember (tem, Vload_path))) | 4289 | if (NILP (Fmember (tem, Vload_path))) |
| @@ -4338,21 +4339,28 @@ init_lread (void) | |||
| 4338 | Vloads_in_progress = Qnil; | 4339 | Vloads_in_progress = Qnil; |
| 4339 | } | 4340 | } |
| 4340 | 4341 | ||
| 4341 | /* Print a warning, using format string FORMAT, that directory DIRNAME | 4342 | /* Print a warning that directory intended for use USE and with name |
| 4342 | does not exist. Print it on stderr and put it in *Messages*. */ | 4343 | DIRNAME cannot be accessed. On entry, errno should correspond to |
| 4344 | the access failure. Print the warning on stderr and put it in | ||
| 4345 | *Messages*. */ | ||
| 4343 | 4346 | ||
| 4344 | void | 4347 | void |
| 4345 | dir_warning (const char *format, Lisp_Object dirname) | 4348 | dir_warning (char const *use, Lisp_Object dirname) |
| 4346 | { | 4349 | { |
| 4347 | fprintf (stderr, format, SDATA (dirname)); | 4350 | static char const format[] = "Warning: %s `%s': %s\n"; |
| 4351 | int access_errno = errno; | ||
| 4352 | fprintf (stderr, format, use, SSDATA (dirname), strerror (access_errno)); | ||
| 4348 | 4353 | ||
| 4349 | /* Don't log the warning before we've initialized!! */ | 4354 | /* Don't log the warning before we've initialized!! */ |
| 4350 | if (initialized) | 4355 | if (initialized) |
| 4351 | { | 4356 | { |
| 4357 | char const *diagnostic = emacs_strerror (access_errno); | ||
| 4352 | USE_SAFE_ALLOCA; | 4358 | USE_SAFE_ALLOCA; |
| 4353 | char *buffer = SAFE_ALLOCA (SBYTES (dirname) | 4359 | char *buffer = SAFE_ALLOCA (sizeof format - 3 * (sizeof "%s" - 1) |
| 4354 | + strlen (format) - (sizeof "%s" - 1) + 1); | 4360 | + strlen (use) + SBYTES (dirname) |
| 4355 | ptrdiff_t message_len = esprintf (buffer, format, SDATA (dirname)); | 4361 | + strlen (diagnostic)); |
| 4362 | ptrdiff_t message_len = esprintf (buffer, format, use, SSDATA (dirname), | ||
| 4363 | diagnostic); | ||
| 4356 | message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname)); | 4364 | message_dolog (buffer, message_len, 0, STRING_MULTIBYTE (dirname)); |
| 4357 | SAFE_FREE (); | 4365 | SAFE_FREE (); |
| 4358 | } | 4366 | } |