aboutsummaryrefslogtreecommitdiffstats
path: root/src/lread.c
diff options
context:
space:
mode:
authorPaul Eggert2012-10-19 09:52:02 -0700
committerPaul Eggert2012-10-19 09:52:02 -0700
commite752e0b0a2622d8d0ba518bf81f6fa652d926e67 (patch)
tree3b7cfbf8aa3ecaa587cd6fbc2d17b64d055d2b07 /src/lread.c
parent6ec83f926d5ff699901fb530162d7f1bdfa85808 (diff)
downloademacs-e752e0b0a2622d8d0ba518bf81f6fa652d926e67.tar.gz
emacs-e752e0b0a2622d8d0ba518bf81f6fa652d926e67.zip
Use faccessat, not access, when checking file permissions.
* .bzrignore: Add lib/fcntl.h. * configure.ac (euidaccess): Remove check; gnulib does this for us now. (gl_FCNTL_O_FLAGS): Define a dummy version. * lib/at-func.c, lib/euidaccess.c, lib/faccessat.c, lib/fcntl.in.h: * lib/getgroups.c, lib/group-member.c, lib/root-uid.h: * lib/xalloc-oversized.h, m4/euidaccess.m4, m4/faccessat.m4: * m4/fcntl_h.m4, m4/getgroups.m4, m4/group-member.m4: New files, from gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * admin/merge-gnulib (GNULIB_MODULES): Add faccessat. (GNULIB_TOOL_FLAGS): Avoid at-internal, fchdir, malloc-posix, openat-die, openat-h, save-cwd. Do not avoid fcntl-h. Omit gnulib's m4/fcntl-o.m4. * nt/inc/ms-w32.h (AT_FDCWD, AT_EACCESS): New symbols. (access): Remove. (faccessat): New macro. * src/Makefile.in (LIB_EACCESS): New macro. (LIBES): Use it. * src/callproc.c (init_callproc): * src/charset.c (init_charset): * src/fileio.c (check_existing, check_executable): * src/lread.c (openp, load_path_check): * src/process.c (allocate_pty): * src/xrdb.c (file_p): Use faccessat, not access or euidaccess. Use symbolic names instead of integers for the flags, as they're portable now. * src/charset.c, src/xrdb.c: Include <fcntl.h>, for the new flags used. * src/fileio.c (Ffile_readable_p): Use faccessat, not stat + open + close. (file_directory_p): New function, which uses 'stat' on most places but 'access' (for efficiency) if WINDOWSNT. * src/fileio.c (Ffile_directory_p, Fset_file_times): * src/xrdb.c (file_p): Use file_directory_p. * src/lisp.h (file_directory_p): New decl. * src/lread.c (openp): When opening a file, use fstat rather than stat, as that avoids a permissions race. When not opening a file, use file_directory_p rather than stat. * src/process.c, src/sysdep.c, src/term.c: All uses of '#ifdef O_NONBLOCK' changed to '#if O_NONBLOCK', to accommodate gnulib O_* tyle. * src/w32.c (sys_faccessat): Rename from sys_access and switch to faccessat's API. All uses changed. Fixes: debbugs:12632
Diffstat (limited to 'src/lread.c')
-rw-r--r--src/lread.c56
1 files changed, 29 insertions, 27 deletions
diff --git a/src/lread.c b/src/lread.c
index 6d4c0d990af..dedce50de2a 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1404,7 +1404,7 @@ Returns the file's name in absolute form, or nil if not found.
1404If SUFFIXES is non-nil, it should be a list of suffixes to append to 1404If SUFFIXES is non-nil, it should be a list of suffixes to append to
1405file name when searching. 1405file name when searching.
1406If non-nil, PREDICATE is used instead of `file-readable-p'. 1406If non-nil, PREDICATE is used instead of `file-readable-p'.
1407PREDICATE can also be an integer to pass to the access(2) function, 1407PREDICATE can also be an integer to pass to the faccessat(2) function,
1408in which case file-name-handlers are ignored. 1408in which case file-name-handlers are ignored.
1409This function will normally skip directories, so if you want it to find 1409This function will normally skip directories, so if you want it to find
1410directories, make sure the PREDICATE function returns `dir-ok' for them. */) 1410directories, make sure the PREDICATE function returns `dir-ok' for them. */)
@@ -1442,7 +1442,6 @@ static Lisp_Object Qdir_ok;
1442int 1442int
1443openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) 1443openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate)
1444{ 1444{
1445 int fd;
1446 ptrdiff_t fn_size = 100; 1445 ptrdiff_t fn_size = 100;
1447 char buf[100]; 1446 char buf[100];
1448 char *fn = buf; 1447 char *fn = buf;
@@ -1497,7 +1496,6 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1497 { 1496 {
1498 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail)); 1497 ptrdiff_t fnlen, lsuffix = SBYTES (XCAR (tail));
1499 Lisp_Object handler; 1498 Lisp_Object handler;
1500 bool exists;
1501 1499
1502 /* Concatenate path element/specified name with the suffix. 1500 /* Concatenate path element/specified name with the suffix.
1503 If the directory starts with /:, remove that. */ 1501 If the directory starts with /:, remove that. */
@@ -1521,6 +1519,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1521 handler = Ffind_file_name_handler (string, Qfile_exists_p); 1519 handler = Ffind_file_name_handler (string, Qfile_exists_p);
1522 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) 1520 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
1523 { 1521 {
1522 bool exists;
1524 if (NILP (predicate)) 1523 if (NILP (predicate))
1525 exists = !NILP (Ffile_readable_p (string)); 1524 exists = !NILP (Ffile_readable_p (string));
1526 else 1525 else
@@ -1542,37 +1541,40 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1542 } 1541 }
1543 else 1542 else
1544 { 1543 {
1545#ifndef WINDOWSNT 1544 int fd;
1546 struct stat st;
1547#endif
1548 const char *pfn; 1545 const char *pfn;
1549 1546
1550 encoded_fn = ENCODE_FILE (string); 1547 encoded_fn = ENCODE_FILE (string);
1551 pfn = SSDATA (encoded_fn); 1548 pfn = SSDATA (encoded_fn);
1552#ifdef WINDOWSNT
1553 exists = access (pfn, F_OK) == 0 && access (pfn, D_OK) < 0;
1554#else
1555 exists = (stat (pfn, &st) == 0 && ! S_ISDIR (st.st_mode));
1556#endif
1557 if (exists)
1558 {
1559 /* Check that we can access or open it. */
1560 if (NATNUMP (predicate))
1561 fd = (((XFASTINT (predicate) & ~INT_MAX) == 0
1562 && access (pfn, XFASTINT (predicate)) == 0)
1563 ? 1 : -1);
1564 else
1565 fd = emacs_open (pfn, O_RDONLY, 0);
1566 1549
1567 if (fd >= 0) 1550 /* Check that we can access or open it. */
1551 if (NATNUMP (predicate))
1552 fd = (((XFASTINT (predicate) & ~INT_MAX) == 0
1553 && (faccessat (AT_FDCWD, pfn, XFASTINT (predicate),
1554 AT_EACCESS)
1555 == 0)
1556 && ! file_directory_p (pfn))
1557 ? 1 : -1);
1558 else
1559 {
1560 struct stat st;
1561 fd = emacs_open (pfn, O_RDONLY, 0);
1562 if (0 <= fd
1563 && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode)))
1568 { 1564 {
1569 /* We succeeded; return this descriptor and filename. */ 1565 emacs_close (fd);
1570 if (storeptr) 1566 fd = -1;
1571 *storeptr = string;
1572 UNGCPRO;
1573 return fd;
1574 } 1567 }
1575 } 1568 }
1569
1570 if (fd >= 0)
1571 {
1572 /* We succeeded; return this descriptor and filename. */
1573 if (storeptr)
1574 *storeptr = string;
1575 UNGCPRO;
1576 return fd;
1577 }
1576 } 1578 }
1577 } 1579 }
1578 if (absolute) 1580 if (absolute)
@@ -4088,7 +4090,7 @@ load_path_check (void)
4088 if (STRINGP (dirfile)) 4090 if (STRINGP (dirfile))
4089 { 4091 {
4090 dirfile = Fdirectory_file_name (dirfile); 4092 dirfile = Fdirectory_file_name (dirfile);
4091 if (access (SSDATA (dirfile), 0) < 0) 4093 if (faccessat (AT_FDCWD, SSDATA (dirfile), F_OK, AT_EACCESS) != 0)
4092 dir_warning ("Warning: Lisp directory `%s' does not exist.\n", 4094 dir_warning ("Warning: Lisp directory `%s' does not exist.\n",
4093 XCAR (path_tail)); 4095 XCAR (path_tail));
4094 } 4096 }