diff options
| author | Paul Eggert | 2013-07-07 00:28:29 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-07 00:28:29 -0700 |
| commit | 5f86adcd2c79e58c6ceeb30fb26c44e830b26a3e (patch) | |
| tree | 594eecc4b1ef2e57230f67136801fcdfb2347b82 | |
| parent | 6ed7a66a3f8781f66fce33f326ac2c5057de4c97 (diff) | |
| download | emacs-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/ChangeLog | 7 | ||||
| -rw-r--r-- | src/callproc.c | 2 | ||||
| -rw-r--r-- | src/lread.c | 57 |
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 @@ | |||
| 1 | 2013-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 | |||
| 1 | 2013-07-06 Jan Djärv <jan.h.d@swipnet.se> | 8 | 2013-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 | ||
| 1469 | int | 1470 | int |
| 1470 | openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) | 1471 | openp (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 | ||