diff options
| author | Paul Eggert | 2012-10-19 09:52:02 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-10-19 09:52:02 -0700 |
| commit | e752e0b0a2622d8d0ba518bf81f6fa652d926e67 (patch) | |
| tree | 3b7cfbf8aa3ecaa587cd6fbc2d17b64d055d2b07 /src/lread.c | |
| parent | 6ec83f926d5ff699901fb530162d7f1bdfa85808 (diff) | |
| download | emacs-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.c | 56 |
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. | |||
| 1404 | If SUFFIXES is non-nil, it should be a list of suffixes to append to | 1404 | If SUFFIXES is non-nil, it should be a list of suffixes to append to |
| 1405 | file name when searching. | 1405 | file name when searching. |
| 1406 | If non-nil, PREDICATE is used instead of `file-readable-p'. | 1406 | If non-nil, PREDICATE is used instead of `file-readable-p'. |
| 1407 | PREDICATE can also be an integer to pass to the access(2) function, | 1407 | PREDICATE can also be an integer to pass to the faccessat(2) function, |
| 1408 | in which case file-name-handlers are ignored. | 1408 | in which case file-name-handlers are ignored. |
| 1409 | This function will normally skip directories, so if you want it to find | 1409 | This function will normally skip directories, so if you want it to find |
| 1410 | directories, make sure the PREDICATE function returns `dir-ok' for them. */) | 1410 | directories, make sure the PREDICATE function returns `dir-ok' for them. */) |
| @@ -1442,7 +1442,6 @@ static Lisp_Object Qdir_ok; | |||
| 1442 | int | 1442 | int |
| 1443 | openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) | 1443 | openp (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 | } |