diff options
Diffstat (limited to 'src/lread.c')
| -rw-r--r-- | src/lread.c | 101 |
1 files changed, 47 insertions, 54 deletions
diff --git a/src/lread.c b/src/lread.c index b57665e365c..f0423f166dd 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -20,7 +20,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | #include <config.h> | 22 | #include <config.h> |
| 23 | #include <stdio.h> | 23 | #include "sysstdio.h" |
| 24 | #include <sys/types.h> | 24 | #include <sys/types.h> |
| 25 | #include <sys/stat.h> | 25 | #include <sys/stat.h> |
| 26 | #include <sys/file.h> | 26 | #include <sys/file.h> |
| @@ -38,7 +38,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 38 | #include "keyboard.h" | 38 | #include "keyboard.h" |
| 39 | #include "frame.h" | 39 | #include "frame.h" |
| 40 | #include "termhooks.h" | 40 | #include "termhooks.h" |
| 41 | #include "coding.h" | ||
| 42 | #include "blockinput.h" | 41 | #include "blockinput.h" |
| 43 | 42 | ||
| 44 | #ifdef MSDOS | 43 | #ifdef MSDOS |
| @@ -96,9 +95,6 @@ static Lisp_Object Qload_in_progress; | |||
| 96 | It must be set to nil before all top-level calls to read0. */ | 95 | It must be set to nil before all top-level calls to read0. */ |
| 97 | static Lisp_Object read_objects; | 96 | static Lisp_Object read_objects; |
| 98 | 97 | ||
| 99 | /* List of descriptors now open for Fload. */ | ||
| 100 | static Lisp_Object load_descriptor_list; | ||
| 101 | |||
| 102 | /* File for get_file_char to read from. Use by load. */ | 98 | /* File for get_file_char to read from. Use by load. */ |
| 103 | static FILE *instream; | 99 | static FILE *instream; |
| 104 | 100 | ||
| @@ -150,7 +146,6 @@ static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool, | |||
| 150 | Lisp_Object, Lisp_Object, | 146 | Lisp_Object, Lisp_Object, |
| 151 | Lisp_Object, Lisp_Object); | 147 | Lisp_Object, Lisp_Object); |
| 152 | static Lisp_Object load_unwind (Lisp_Object); | 148 | static Lisp_Object load_unwind (Lisp_Object); |
| 153 | static Lisp_Object load_descriptor_unwind (Lisp_Object); | ||
| 154 | 149 | ||
| 155 | /* Functions that read one byte from the current source READCHARFUN | 150 | /* Functions that read one byte from the current source READCHARFUN |
| 156 | or unreads one byte. If the integer argument C is -1, it returns | 151 | or unreads one byte. If the integer argument C is -1, it returns |
| @@ -828,7 +823,7 @@ lisp_file_lexically_bound_p (Lisp_Object readcharfun) | |||
| 828 | { | 823 | { |
| 829 | bool rv = 0; | 824 | bool rv = 0; |
| 830 | enum { | 825 | enum { |
| 831 | NOMINAL, AFTER_FIRST_DASH, AFTER_ASTERIX, | 826 | NOMINAL, AFTER_FIRST_DASH, AFTER_ASTERIX |
| 832 | } beg_end_state = NOMINAL; | 827 | } beg_end_state = NOMINAL; |
| 833 | bool in_file_vars = 0; | 828 | bool in_file_vars = 0; |
| 834 | 829 | ||
| @@ -1298,7 +1293,7 @@ Return t if the file exists and loads successfully. */) | |||
| 1298 | if (fd >= 0) | 1293 | if (fd >= 0) |
| 1299 | { | 1294 | { |
| 1300 | emacs_close (fd); | 1295 | emacs_close (fd); |
| 1301 | stream = fopen (SSDATA (efound), fmode); | 1296 | stream = emacs_fopen (SSDATA (efound), fmode); |
| 1302 | } | 1297 | } |
| 1303 | else | 1298 | else |
| 1304 | stream = NULL; | 1299 | stream = NULL; |
| @@ -1329,11 +1324,8 @@ Return t if the file exists and loads successfully. */) | |||
| 1329 | } | 1324 | } |
| 1330 | 1325 | ||
| 1331 | record_unwind_protect (load_unwind, make_save_pointer (stream)); | 1326 | record_unwind_protect (load_unwind, make_save_pointer (stream)); |
| 1332 | record_unwind_protect (load_descriptor_unwind, load_descriptor_list); | ||
| 1333 | specbind (Qload_file_name, found); | 1327 | specbind (Qload_file_name, found); |
| 1334 | specbind (Qinhibit_file_name_operation, Qnil); | 1328 | specbind (Qinhibit_file_name_operation, Qnil); |
| 1335 | load_descriptor_list | ||
| 1336 | = Fcons (make_number (fileno (stream)), load_descriptor_list); | ||
| 1337 | specbind (Qload_in_progress, Qt); | 1329 | specbind (Qload_in_progress, Qt); |
| 1338 | 1330 | ||
| 1339 | instream = stream; | 1331 | instream = stream; |
| @@ -1396,26 +1388,6 @@ load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */ | |||
| 1396 | } | 1388 | } |
| 1397 | return Qnil; | 1389 | return Qnil; |
| 1398 | } | 1390 | } |
| 1399 | |||
| 1400 | static Lisp_Object | ||
| 1401 | load_descriptor_unwind (Lisp_Object oldlist) | ||
| 1402 | { | ||
| 1403 | load_descriptor_list = oldlist; | ||
| 1404 | return Qnil; | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | /* Close all descriptors in use for Floads. | ||
| 1408 | This is used when starting a subprocess. */ | ||
| 1409 | |||
| 1410 | void | ||
| 1411 | close_load_descs (void) | ||
| 1412 | { | ||
| 1413 | #ifndef WINDOWSNT | ||
| 1414 | Lisp_Object tail; | ||
| 1415 | for (tail = load_descriptor_list; CONSP (tail); tail = XCDR (tail)) | ||
| 1416 | emacs_close (XFASTINT (XCAR (tail))); | ||
| 1417 | #endif | ||
| 1418 | } | ||
| 1419 | 1391 | ||
| 1420 | static bool | 1392 | static bool |
| 1421 | complete_filename_p (Lisp_Object pathname) | 1393 | complete_filename_p (Lisp_Object pathname) |
| @@ -1440,8 +1412,8 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) | |||
| 1440 | { | 1412 | { |
| 1441 | Lisp_Object file; | 1413 | Lisp_Object file; |
| 1442 | int fd = openp (path, filename, suffixes, &file, predicate); | 1414 | int fd = openp (path, filename, suffixes, &file, predicate); |
| 1443 | if (NILP (predicate) && fd > 0) | 1415 | if (NILP (predicate) && fd >= 0) |
| 1444 | close (fd); | 1416 | emacs_close (fd); |
| 1445 | return file; | 1417 | return file; |
| 1446 | } | 1418 | } |
| 1447 | 1419 | ||
| @@ -1449,14 +1421,15 @@ static Lisp_Object Qdir_ok; | |||
| 1449 | 1421 | ||
| 1450 | /* Search for a file whose name is STR, looking in directories | 1422 | /* Search for a file whose name is STR, looking in directories |
| 1451 | in the Lisp list PATH, and trying suffixes from SUFFIX. | 1423 | in the Lisp list PATH, and trying suffixes from SUFFIX. |
| 1452 | On success, returns a file descriptor. On failure, returns -1. | 1424 | On success, return a file descriptor (or 1 or -2 as described below). |
| 1425 | On failure, return -1 and set errno. | ||
| 1453 | 1426 | ||
| 1454 | SUFFIXES is a list of strings containing possible suffixes. | 1427 | SUFFIXES is a list of strings containing possible suffixes. |
| 1455 | The empty suffix is automatically added if the list is empty. | 1428 | The empty suffix is automatically added if the list is empty. |
| 1456 | 1429 | ||
| 1457 | PREDICATE non-nil means don't open the files, | 1430 | PREDICATE non-nil means don't open the files, |
| 1458 | just look for one that satisfies the predicate. In this case, | 1431 | just look for one that satisfies the predicate. In this case, |
| 1459 | returns 1 on success. The predicate can be a lisp function or | 1432 | return 1 on success. The predicate can be a lisp function or |
| 1460 | an integer to pass to `access' (in which case file-name-handlers | 1433 | an integer to pass to `access' (in which case file-name-handlers |
| 1461 | are ignored). | 1434 | are ignored). |
| 1462 | 1435 | ||
| @@ -1468,7 +1441,8 @@ static Lisp_Object Qdir_ok; | |||
| 1468 | but store the found remote file name in *STOREPTR. */ | 1441 | but store the found remote file name in *STOREPTR. */ |
| 1469 | 1442 | ||
| 1470 | int | 1443 | int |
| 1471 | openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *storeptr, Lisp_Object predicate) | 1444 | openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, |
| 1445 | Lisp_Object *storeptr, Lisp_Object predicate) | ||
| 1472 | { | 1446 | { |
| 1473 | ptrdiff_t fn_size = 100; | 1447 | ptrdiff_t fn_size = 100; |
| 1474 | char buf[100]; | 1448 | char buf[100]; |
| @@ -1479,6 +1453,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto | |||
| 1479 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; | 1453 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; |
| 1480 | Lisp_Object string, tail, encoded_fn; | 1454 | Lisp_Object string, tail, encoded_fn; |
| 1481 | ptrdiff_t max_suffix_len = 0; | 1455 | ptrdiff_t max_suffix_len = 0; |
| 1456 | int last_errno = ENOENT; | ||
| 1482 | 1457 | ||
| 1483 | CHECK_STRING (str); | 1458 | CHECK_STRING (str); |
| 1484 | 1459 | ||
| @@ -1548,14 +1523,22 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto | |||
| 1548 | if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) | 1523 | if ((!NILP (handler) || !NILP (predicate)) && !NATNUMP (predicate)) |
| 1549 | { | 1524 | { |
| 1550 | bool exists; | 1525 | bool exists; |
| 1526 | last_errno = ENOENT; | ||
| 1551 | if (NILP (predicate)) | 1527 | if (NILP (predicate)) |
| 1552 | exists = !NILP (Ffile_readable_p (string)); | 1528 | exists = !NILP (Ffile_readable_p (string)); |
| 1553 | else | 1529 | else |
| 1554 | { | 1530 | { |
| 1555 | Lisp_Object tmp = call1 (predicate, string); | 1531 | Lisp_Object tmp = call1 (predicate, string); |
| 1556 | exists = !NILP (tmp) | 1532 | if (NILP (tmp)) |
| 1557 | && (EQ (tmp, Qdir_ok) | 1533 | exists = 0; |
| 1558 | || NILP (Ffile_directory_p (string))); | 1534 | else if (EQ (tmp, Qdir_ok) |
| 1535 | || NILP (Ffile_directory_p (string))) | ||
| 1536 | exists = 1; | ||
| 1537 | else | ||
| 1538 | { | ||
| 1539 | exists = 0; | ||
| 1540 | last_errno = EISDIR; | ||
| 1541 | } | ||
| 1559 | } | 1542 | } |
| 1560 | 1543 | ||
| 1561 | if (exists) | 1544 | if (exists) |
| @@ -1577,21 +1560,36 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto | |||
| 1577 | 1560 | ||
| 1578 | /* Check that we can access or open it. */ | 1561 | /* Check that we can access or open it. */ |
| 1579 | if (NATNUMP (predicate)) | 1562 | if (NATNUMP (predicate)) |
| 1580 | fd = (((XFASTINT (predicate) & ~INT_MAX) == 0 | 1563 | { |
| 1581 | && (faccessat (AT_FDCWD, pfn, XFASTINT (predicate), | 1564 | fd = -1; |
| 1565 | if (INT_MAX < XFASTINT (predicate)) | ||
| 1566 | last_errno = EINVAL; | ||
| 1567 | else if (faccessat (AT_FDCWD, pfn, XFASTINT (predicate), | ||
| 1582 | AT_EACCESS) | 1568 | AT_EACCESS) |
| 1583 | == 0) | 1569 | == 0) |
| 1584 | && ! file_directory_p (pfn)) | 1570 | { |
| 1585 | ? 1 : -1); | 1571 | if (file_directory_p (pfn)) |
| 1572 | last_errno = EISDIR; | ||
| 1573 | else | ||
| 1574 | fd = 1; | ||
| 1575 | } | ||
| 1576 | } | ||
| 1586 | else | 1577 | else |
| 1587 | { | 1578 | { |
| 1588 | struct stat st; | ||
| 1589 | fd = emacs_open (pfn, O_RDONLY, 0); | 1579 | fd = emacs_open (pfn, O_RDONLY, 0); |
| 1590 | if (fd >= 0 | 1580 | if (fd < 0) |
| 1591 | && (fstat (fd, &st) != 0 || S_ISDIR (st.st_mode))) | 1581 | last_errno = errno; |
| 1582 | else | ||
| 1592 | { | 1583 | { |
| 1593 | emacs_close (fd); | 1584 | struct stat st; |
| 1594 | fd = -1; | 1585 | int err = (fstat (fd, &st) != 0 ? errno |
| 1586 | : S_ISDIR (st.st_mode) ? EISDIR : 0); | ||
| 1587 | if (err) | ||
| 1588 | { | ||
| 1589 | last_errno = err; | ||
| 1590 | emacs_close (fd); | ||
| 1591 | fd = -1; | ||
| 1592 | } | ||
| 1595 | } | 1593 | } |
| 1596 | } | 1594 | } |
| 1597 | 1595 | ||
| @@ -1610,6 +1608,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, Lisp_Object *sto | |||
| 1610 | } | 1608 | } |
| 1611 | 1609 | ||
| 1612 | UNGCPRO; | 1610 | UNGCPRO; |
| 1611 | errno = last_errno; | ||
| 1613 | return -1; | 1612 | return -1; |
| 1614 | } | 1613 | } |
| 1615 | 1614 | ||
| @@ -4350,9 +4349,6 @@ init_lread (void) | |||
| 4350 | 4349 | ||
| 4351 | load_in_progress = 0; | 4350 | load_in_progress = 0; |
| 4352 | Vload_file_name = Qnil; | 4351 | Vload_file_name = Qnil; |
| 4353 | |||
| 4354 | load_descriptor_list = Qnil; | ||
| 4355 | |||
| 4356 | Vstandard_input = Qt; | 4352 | Vstandard_input = Qt; |
| 4357 | Vloads_in_progress = Qnil; | 4353 | Vloads_in_progress = Qnil; |
| 4358 | } | 4354 | } |
| @@ -4625,9 +4621,6 @@ variables, this must be set in the first line of a file. */); | |||
| 4625 | 4621 | ||
| 4626 | /* Vsource_directory was initialized in init_lread. */ | 4622 | /* Vsource_directory was initialized in init_lread. */ |
| 4627 | 4623 | ||
| 4628 | load_descriptor_list = Qnil; | ||
| 4629 | staticpro (&load_descriptor_list); | ||
| 4630 | |||
| 4631 | DEFSYM (Qcurrent_load_list, "current-load-list"); | 4624 | DEFSYM (Qcurrent_load_list, "current-load-list"); |
| 4632 | DEFSYM (Qstandard_input, "standard-input"); | 4625 | DEFSYM (Qstandard_input, "standard-input"); |
| 4633 | DEFSYM (Qread_char, "read-char"); | 4626 | DEFSYM (Qread_char, "read-char"); |