aboutsummaryrefslogtreecommitdiffstats
path: root/src/lread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lread.c')
-rw-r--r--src/lread.c92
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.
1403If SUFFIXES is non-nil, it should be a list of suffixes to append to 1403If SUFFIXES is non-nil, it should be a list of suffixes to append to
1404file name when searching. 1404file name when searching.
1405If non-nil, PREDICATE is used instead of `file-readable-p'. 1405If non-nil, PREDICATE is used instead of `file-readable-p'.
1406PREDICATE can also be an integer to pass to the access(2) function, 1406PREDICATE can also be an integer to pass to the faccessat(2) function,
1407in which case file-name-handlers are ignored. 1407in which case file-name-handlers are ignored.
1408This function will normally skip directories, so if you want it to find 1408This function will normally skip directories, so if you want it to find
1409directories, make sure the PREDICATE function returns `dir-ok' for them. */) 1409directories, make sure the PREDICATE function returns `dir-ok' for them. */)
@@ -1441,7 +1441,6 @@ static Lisp_Object Qdir_ok;
1441int 1441int
1442openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) 1442openp (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
4344void 4347void
4345dir_warning (const char *format, Lisp_Object dirname) 4348dir_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 }