aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2013-07-07 00:28:29 -0700
committerPaul Eggert2013-07-07 00:28:29 -0700
commit5f86adcd2c79e58c6ceeb30fb26c44e830b26a3e (patch)
tree594eecc4b1ef2e57230f67136801fcdfb2347b82
parent6ed7a66a3f8781f66fce33f326ac2c5057de4c97 (diff)
downloademacs-5f86adcd2c79e58c6ceeb30fb26c44e830b26a3e.tar.gz
emacs-5f86adcd2c79e58c6ceeb30fb26c44e830b26a3e.zip
Fix openp errno handling.
* callproc.c (Fcall_process): Preserve openp errno around close. * lread.c (openp): Set errno when returning -1, as some callers expect this.
-rw-r--r--src/ChangeLog7
-rw-r--r--src/callproc.c2
-rw-r--r--src/lread.c57
3 files changed, 51 insertions, 15 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index b95488c1e70..f8221e2fd36 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
12013-07-07 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix openp errno handling.
4 * callproc.c (Fcall_process): Preserve openp errno around close.
5 * lread.c (openp): Set errno when returning -1, as some callers
6 expect this.
7
12013-07-06 Jan Djärv <jan.h.d@swipnet.se> 82013-07-06 Jan Djärv <jan.h.d@swipnet.se>
2 9
3 * nsterm.m (sendEvent:): Handle NSAPP_DATA2_RUNFILEDIALOG. 10 * nsterm.m (sendEvent:): Handle NSAPP_DATA2_RUNFILEDIALOG.
diff --git a/src/callproc.c b/src/callproc.c
index 6de8113dc14..185dc9a493e 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -436,7 +436,9 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS) *
436 } 436 }
437 if (NILP (path)) 437 if (NILP (path))
438 { 438 {
439 int openp_errno = errno;
439 emacs_close (filefd); 440 emacs_close (filefd);
441 errno = openp_errno;
440 report_file_error ("Searching for program", Fcons (args[0], Qnil)); 442 report_file_error ("Searching for program", Fcons (args[0], Qnil));
441 } 443 }
442 444
diff --git a/src/lread.c b/src/lread.c
index 06badce12be..2ceeb106653 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1448,14 +1448,15 @@ static Lisp_Object Qdir_ok;
1448 1448
1449/* Search for a file whose name is STR, looking in directories 1449/* Search for a file whose name is STR, looking in directories
1450 in the Lisp list PATH, and trying suffixes from SUFFIX. 1450 in the Lisp list PATH, and trying suffixes from SUFFIX.
1451 On success, returns a file descriptor. On failure, returns -1. 1451 On success, return a file descriptor (or 1 or -2 as described below).
1452 On failure, return -1 and set errno.
1452 1453
1453 SUFFIXES is a list of strings containing possible suffixes. 1454 SUFFIXES is a list of strings containing possible suffixes.
1454 The empty suffix is automatically added if the list is empty. 1455 The empty suffix is automatically added if the list is empty.
1455 1456
1456 PREDICATE non-nil means don't open the files, 1457 PREDICATE non-nil means don't open the files,
1457 just look for one that satisfies the predicate. In this case, 1458 just look for one that satisfies the predicate. In this case,
1458 returns 1 on success. The predicate can be a lisp function or 1459 return 1 on success. The predicate can be a lisp function or
1459 an integer to pass to `access' (in which case file-name-handlers 1460 an integer to pass to `access' (in which case file-name-handlers
1460 are ignored). 1461 are ignored).
1461 1462
@@ -1467,7 +1468,8 @@ static Lisp_Object Qdir_ok;
1467 but store the found remote file name in *STOREPTR. */ 1468 but store the found remote file name in *STOREPTR. */
1468 1469
1469int 1470int
1470openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) 1471openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1472 Lisp_Object *storeptr, Lisp_Object predicate)
1471{ 1473{
1472 ptrdiff_t fn_size = 100; 1474 ptrdiff_t fn_size = 100;
1473 char buf[100]; 1475 char buf[100];
@@ -1478,6 +1480,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1478 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; 1480 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
1479 Lisp_Object string, tail, encoded_fn; 1481 Lisp_Object string, tail, encoded_fn;
1480 ptrdiff_t max_suffix_len = 0; 1482 ptrdiff_t max_suffix_len = 0;
1483 int last_errno = ENOENT;
1481 1484
1482 CHECK_STRING (str); 1485 CHECK_STRING (str);
1483 1486
@@ -1547,14 +1550,22 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1547 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) 1550 if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate))
1548 { 1551 {
1549 bool exists; 1552 bool exists;
1553 last_errno = ENOENT;
1550 if (NILP (predicate)) 1554 if (NILP (predicate))
1551 exists = !NILP (Ffile_readable_p (string)); 1555 exists = !NILP (Ffile_readable_p (string));
1552 else 1556 else
1553 { 1557 {
1554 Lisp_Object tmp = call1 (predicate, string); 1558 Lisp_Object tmp = call1 (predicate, string);
1555 exists = !NILP (tmp) 1559 if (NILP (tmp))
1556 && (EQ (tmp, Qdir_ok) 1560 exists = 0;
1557 || NILP (Ffile_directory_p (string))); 1561 else if (EQ (tmp, Qdir_ok)
1562 || NILP (Ffile_directory_p (string)))
1563 exists = 1;
1564 else
1565 {
1566 exists = 0;
1567 last_errno = EISDIR;
1568 }
1558 } 1569 }
1559 1570
1560 if (exists) 1571 if (exists)
@@ -1576,21 +1587,36 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1576 1587
1577 /* Check that we can access or open it. */ 1588 /* Check that we can access or open it. */
1578 if (NATNUMP (predicate)) 1589 if (NATNUMP (predicate))
1579 fd = (((XFASTINT (predicate) & ~INT_MAX) == 0 1590 {
1580 && (faccessat (AT_FDCWD, pfn, XFASTINT (predicate), 1591 fd = -1;
1592 if (INT_MAX < XFASTINT (predicate))
1593 last_errno = EINVAL;
1594 else if (faccessat (AT_FDCWD, pfn, XFASTINT (predicate),
1581 AT_EACCESS) 1595 AT_EACCESS)
1582 == 0) 1596 == 0)
1583 && ! file_directory_p (pfn)) 1597 {
1584 ? 1 : -1); 1598 if (file_directory_p (pfn))
1599 last_errno = EISDIR;
1600 else
1601 fd = 1;
1602 }
1603 }
1585 else 1604 else
1586 { 1605 {
1587 struct stat st;
1588 fd = emacs_open (pfn, O_RDONLY, 0); 1606 fd = emacs_open (pfn, O_RDONLY, 0);
1589 if (fd >= 0 1607 if (fd < 0)
1590 && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode))) 1608 last_errno = errno;
1609 else
1591 { 1610 {
1592 emacs_close (fd); 1611 struct stat st;
1593 fd = -1; 1612 int err = (fstat (fd, &st) != 0 ? errno
1613 : S_ISDIR (st.st_mode) ? EISDIR : 0);
1614 if (err)
1615 {
1616 last_errno = err;
1617 emacs_close (fd);
1618 fd = -1;
1619 }
1594 } 1620 }
1595 } 1621 }
1596 1622
@@ -1609,6 +1635,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto
1609 } 1635 }
1610 1636
1611 UNGCPRO; 1637 UNGCPRO;
1638 errno = last_errno;
1612 return -1; 1639 return -1;
1613} 1640}
1614 1641