diff options
| author | Paul Eggert | 2015-05-24 14:20:09 -0700 |
|---|---|---|
| committer | Paul Eggert | 2015-05-24 14:20:09 -0700 |
| commit | 379d77dfa3a03083517114e1ce32bb72137aea05 (patch) | |
| tree | 74104c55d057e646d3ea10c1e05ae1400fe6b613 /lib-src | |
| parent | 3441b0cc61d88edb921bbf27462f3f961e794b4d (diff) | |
| download | emacs-379d77dfa3a03083517114e1ce32bb72137aea05.tar.gz emacs-379d77dfa3a03083517114e1ce32bb72137aea05.zip | |
Improve etags I/O error reporting
* lib-src/etags.c:
Don't include sys/types.h and sys/stat.h; no longer needed.
(infilename): New static var.
(process_file_name): Don't call 'stat'. Instead, just open the
file for reading and report any errors. Don't bother making
a copy of the file argument; it's not needed. Be more careful to
use the failing errno when reporting an error.
Quote the real name better (though no perfectly)
when passing it to the shell.
(reset_input): New function, which reports I/O errors.
All uses of 'rewind' changed to use this function.
(perhaps_more_input): New function, which also checks for
I/O errors. All uses of 'feof' changed to use this function.
(analyze_regex): Report an error if fclose fails.
(readline_internal): Report an error if getc fails.
(etags_mktmp): Return an error if close fails.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/etags.c | 183 |
1 files changed, 103 insertions, 80 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c index ea337d41008..48d2299410a 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c | |||
| @@ -127,8 +127,6 @@ char pot_etags_version[] = "@(#) pot revision number is 17.38.1.4"; | |||
| 127 | #include <sysstdio.h> | 127 | #include <sysstdio.h> |
| 128 | #include <errno.h> | 128 | #include <errno.h> |
| 129 | #include <fcntl.h> | 129 | #include <fcntl.h> |
| 130 | #include <sys/types.h> | ||
| 131 | #include <sys/stat.h> | ||
| 132 | #include <binary-io.h> | 130 | #include <binary-io.h> |
| 133 | #include <c-ctype.h> | 131 | #include <c-ctype.h> |
| 134 | #include <c-strcase.h> | 132 | #include <c-strcase.h> |
| @@ -355,7 +353,7 @@ static void just_read_file (FILE *); | |||
| 355 | 353 | ||
| 356 | static language *get_language_from_langname (const char *); | 354 | static language *get_language_from_langname (const char *); |
| 357 | static void readline (linebuffer *, FILE *); | 355 | static void readline (linebuffer *, FILE *); |
| 358 | static long readline_internal (linebuffer *, FILE *); | 356 | static long readline_internal (linebuffer *, FILE *, char const *); |
| 359 | static bool nocase_tail (const char *); | 357 | static bool nocase_tail (const char *); |
| 360 | static void get_tag (char *, char **); | 358 | static void get_tag (char *, char **); |
| 361 | 359 | ||
| @@ -407,6 +405,7 @@ static ptrdiff_t whatlen_max; /* maximum length of any 'what' member */ | |||
| 407 | 405 | ||
| 408 | static fdesc *fdhead; /* head of file description list */ | 406 | static fdesc *fdhead; /* head of file description list */ |
| 409 | static fdesc *curfdp; /* current file description */ | 407 | static fdesc *curfdp; /* current file description */ |
| 408 | static char *infilename; /* current input file name */ | ||
| 410 | static int lineno; /* line number of current line */ | 409 | static int lineno; /* line number of current line */ |
| 411 | static long charno; /* current character number */ | 410 | static long charno; /* current character number */ |
| 412 | static long linecharno; /* charno of start of current line */ | 411 | static long linecharno; /* charno of start of current line */ |
| @@ -1247,7 +1246,7 @@ main (int argc, char **argv) | |||
| 1247 | if (parsing_stdin) | 1246 | if (parsing_stdin) |
| 1248 | fatal ("cannot parse standard input AND read file names from it", | 1247 | fatal ("cannot parse standard input AND read file names from it", |
| 1249 | (char *)NULL); | 1248 | (char *)NULL); |
| 1250 | while (readline_internal (&filename_lb, stdin) > 0) | 1249 | while (readline_internal (&filename_lb, stdin, "-") > 0) |
| 1251 | process_file_name (filename_lb.buffer, lang); | 1250 | process_file_name (filename_lb.buffer, lang); |
| 1252 | } | 1251 | } |
| 1253 | else | 1252 | else |
| @@ -1470,7 +1469,6 @@ get_language_from_filename (char *file, int case_sensitive) | |||
| 1470 | static void | 1469 | static void |
| 1471 | process_file_name (char *file, language *lang) | 1470 | process_file_name (char *file, language *lang) |
| 1472 | { | 1471 | { |
| 1473 | struct stat stat_buf; | ||
| 1474 | FILE *inf; | 1472 | FILE *inf; |
| 1475 | fdesc *fdp; | 1473 | fdesc *fdp; |
| 1476 | compressor *compr; | 1474 | compressor *compr; |
| @@ -1487,13 +1485,13 @@ process_file_name (char *file, language *lang) | |||
| 1487 | compr = get_compressor_from_suffix (file, &ext); | 1485 | compr = get_compressor_from_suffix (file, &ext); |
| 1488 | if (compr) | 1486 | if (compr) |
| 1489 | { | 1487 | { |
| 1490 | real_name = compressed_name = savestr (file); | 1488 | compressed_name = file; |
| 1491 | uncompressed_name = savenstr (file, ext - file); | 1489 | uncompressed_name = savenstr (file, ext - file); |
| 1492 | } | 1490 | } |
| 1493 | else | 1491 | else |
| 1494 | { | 1492 | { |
| 1495 | compressed_name = NULL; | 1493 | compressed_name = NULL; |
| 1496 | real_name = uncompressed_name = savestr (file); | 1494 | uncompressed_name = file; |
| 1497 | } | 1495 | } |
| 1498 | 1496 | ||
| 1499 | /* If the canonicalized uncompressed name | 1497 | /* If the canonicalized uncompressed name |
| @@ -1505,83 +1503,91 @@ process_file_name (char *file, language *lang) | |||
| 1505 | goto cleanup; | 1503 | goto cleanup; |
| 1506 | } | 1504 | } |
| 1507 | 1505 | ||
| 1508 | if (stat (real_name, &stat_buf) != 0) | 1506 | inf = fopen (file, "r" FOPEN_BINARY); |
| 1507 | if (inf) | ||
| 1508 | real_name = file; | ||
| 1509 | else | ||
| 1509 | { | 1510 | { |
| 1510 | /* Reset real_name and try with a different name. */ | 1511 | int file_errno = errno; |
| 1511 | real_name = NULL; | 1512 | if (compressed_name) |
| 1512 | if (compressed_name != NULL) /* try with the given suffix */ | ||
| 1513 | { | 1513 | { |
| 1514 | if (stat (uncompressed_name, &stat_buf) == 0) | 1514 | /* Try with the given suffix. */ |
| 1515 | inf = fopen (uncompressed_name, "r" FOPEN_BINARY); | ||
| 1516 | if (inf) | ||
| 1515 | real_name = uncompressed_name; | 1517 | real_name = uncompressed_name; |
| 1516 | } | 1518 | } |
| 1517 | else /* try all possible suffixes */ | 1519 | else |
| 1518 | { | 1520 | { |
| 1521 | /* Try all possible suffixes. */ | ||
| 1519 | for (compr = compressors; compr->suffix != NULL; compr++) | 1522 | for (compr = compressors; compr->suffix != NULL; compr++) |
| 1520 | { | 1523 | { |
| 1521 | compressed_name = concat (file, ".", compr->suffix); | 1524 | compressed_name = concat (file, ".", compr->suffix); |
| 1522 | if (stat (compressed_name, &stat_buf) != 0) | 1525 | inf = fopen (compressed_name, "r" FOPEN_BINARY); |
| 1526 | if (inf) | ||
| 1527 | { | ||
| 1528 | real_name = compressed_name; | ||
| 1529 | break; | ||
| 1530 | } | ||
| 1531 | if (MSDOS) | ||
| 1523 | { | 1532 | { |
| 1524 | if (MSDOS) | 1533 | char *suf = compressed_name + strlen (file); |
| 1534 | size_t suflen = strlen (compr->suffix) + 1; | ||
| 1535 | for ( ; suf[1]; suf++, suflen--) | ||
| 1525 | { | 1536 | { |
| 1526 | char *suf = compressed_name + strlen (file); | 1537 | memmove (suf, suf + 1, suflen); |
| 1527 | size_t suflen = strlen (compr->suffix) + 1; | 1538 | inf = fopen (compressed_name, "r" FOPEN_BINARY); |
| 1528 | for ( ; suf[1]; suf++, suflen--) | 1539 | if (inf) |
| 1529 | { | 1540 | { |
| 1530 | memmove (suf, suf + 1, suflen); | 1541 | real_name = compressed_name; |
| 1531 | if (stat (compressed_name, &stat_buf) == 0) | 1542 | break; |
| 1532 | { | ||
| 1533 | real_name = compressed_name; | ||
| 1534 | break; | ||
| 1535 | } | ||
| 1536 | } | 1543 | } |
| 1537 | if (real_name != NULL) | 1544 | } |
| 1538 | break; | 1545 | if (inf) |
| 1539 | } /* MSDOS */ | 1546 | break; |
| 1540 | free (compressed_name); | ||
| 1541 | compressed_name = NULL; | ||
| 1542 | } | ||
| 1543 | else | ||
| 1544 | { | ||
| 1545 | real_name = compressed_name; | ||
| 1546 | break; | ||
| 1547 | } | 1547 | } |
| 1548 | free (compressed_name); | ||
| 1549 | compressed_name = NULL; | ||
| 1548 | } | 1550 | } |
| 1549 | } | 1551 | } |
| 1550 | if (real_name == NULL) | 1552 | if (! inf) |
| 1551 | { | 1553 | { |
| 1554 | errno = file_errno; | ||
| 1552 | perror (file); | 1555 | perror (file); |
| 1553 | goto cleanup; | 1556 | goto cleanup; |
| 1554 | } | 1557 | } |
| 1555 | } /* try with a different name */ | ||
| 1556 | |||
| 1557 | if (!S_ISREG (stat_buf.st_mode)) | ||
| 1558 | { | ||
| 1559 | error ("skipping %s: it is not a regular file.", real_name); | ||
| 1560 | goto cleanup; | ||
| 1561 | } | 1558 | } |
| 1559 | |||
| 1562 | if (real_name == compressed_name) | 1560 | if (real_name == compressed_name) |
| 1563 | { | 1561 | { |
| 1562 | fclose (inf); | ||
| 1564 | tmp_name = etags_mktmp (); | 1563 | tmp_name = etags_mktmp (); |
| 1565 | if (!tmp_name) | 1564 | if (!tmp_name) |
| 1566 | inf = NULL; | 1565 | inf = NULL; |
| 1567 | else | 1566 | else |
| 1568 | { | 1567 | { |
| 1569 | char *cmd1 = concat (compr->command, " ", real_name); | 1568 | char *cmd1 = concat (compr->command, " '", real_name); |
| 1570 | char *cmd = concat (cmd1, " > ", tmp_name); | 1569 | char *cmd = concat (cmd1, "' > ", tmp_name); |
| 1571 | free (cmd1); | 1570 | free (cmd1); |
| 1571 | int tmp_errno; | ||
| 1572 | if (system (cmd) == -1) | 1572 | if (system (cmd) == -1) |
| 1573 | inf = NULL; | 1573 | { |
| 1574 | inf = NULL; | ||
| 1575 | tmp_errno = EINVAL; | ||
| 1576 | } | ||
| 1574 | else | 1577 | else |
| 1575 | inf = fopen (tmp_name, "r" FOPEN_BINARY); | 1578 | { |
| 1579 | inf = fopen (tmp_name, "r" FOPEN_BINARY); | ||
| 1580 | tmp_errno = errno; | ||
| 1581 | } | ||
| 1576 | free (cmd); | 1582 | free (cmd); |
| 1583 | errno = tmp_errno; | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | if (!inf) | ||
| 1587 | { | ||
| 1588 | perror (real_name); | ||
| 1589 | goto cleanup; | ||
| 1577 | } | 1590 | } |
| 1578 | } | ||
| 1579 | else | ||
| 1580 | inf = fopen (real_name, "r" FOPEN_BINARY); | ||
| 1581 | if (inf == NULL) | ||
| 1582 | { | ||
| 1583 | perror (real_name); | ||
| 1584 | goto cleanup; | ||
| 1585 | } | 1591 | } |
| 1586 | 1592 | ||
| 1587 | process_file (inf, uncompressed_name, lang); | 1593 | process_file (inf, uncompressed_name, lang); |
| @@ -1596,8 +1602,10 @@ process_file_name (char *file, language *lang) | |||
| 1596 | pfatal (file); | 1602 | pfatal (file); |
| 1597 | 1603 | ||
| 1598 | cleanup: | 1604 | cleanup: |
| 1599 | free (compressed_name); | 1605 | if (compressed_name != file) |
| 1600 | free (uncompressed_name); | 1606 | free (compressed_name); |
| 1607 | if (uncompressed_name != file) | ||
| 1608 | free (uncompressed_name); | ||
| 1601 | last_node = NULL; | 1609 | last_node = NULL; |
| 1602 | curfdp = NULL; | 1610 | curfdp = NULL; |
| 1603 | return; | 1611 | return; |
| @@ -1609,6 +1617,7 @@ process_file (FILE *fh, char *fn, language *lang) | |||
| 1609 | static const fdesc emptyfdesc; | 1617 | static const fdesc emptyfdesc; |
| 1610 | fdesc *fdp; | 1618 | fdesc *fdp; |
| 1611 | 1619 | ||
| 1620 | infilename = fn; | ||
| 1612 | /* Create a new input file description entry. */ | 1621 | /* Create a new input file description entry. */ |
| 1613 | fdp = xnew (1, fdesc); | 1622 | fdp = xnew (1, fdesc); |
| 1614 | *fdp = emptyfdesc; | 1623 | *fdp = emptyfdesc; |
| @@ -1672,6 +1681,13 @@ process_file (FILE *fh, char *fn, language *lang) | |||
| 1672 | } | 1681 | } |
| 1673 | } | 1682 | } |
| 1674 | 1683 | ||
| 1684 | static void | ||
| 1685 | reset_input (FILE *inf) | ||
| 1686 | { | ||
| 1687 | if (fseek (inf, 0, SEEK_SET) != 0) | ||
| 1688 | perror (infilename); | ||
| 1689 | } | ||
| 1690 | |||
| 1675 | /* | 1691 | /* |
| 1676 | * This routine opens the specified file and calls the function | 1692 | * This routine opens the specified file and calls the function |
| 1677 | * which finds the function and type definitions. | 1693 | * which finds the function and type definitions. |
| @@ -1702,7 +1718,7 @@ find_entries (FILE *inf) | |||
| 1702 | 1718 | ||
| 1703 | /* Else look for sharp-bang as the first two characters. */ | 1719 | /* Else look for sharp-bang as the first two characters. */ |
| 1704 | if (parser == NULL | 1720 | if (parser == NULL |
| 1705 | && readline_internal (&lb, inf) > 0 | 1721 | && readline_internal (&lb, inf, infilename) > 0 |
| 1706 | && lb.len >= 2 | 1722 | && lb.len >= 2 |
| 1707 | && lb.buffer[0] == '#' | 1723 | && lb.buffer[0] == '#' |
| 1708 | && lb.buffer[1] == '!') | 1724 | && lb.buffer[1] == '!') |
| @@ -1731,7 +1747,7 @@ find_entries (FILE *inf) | |||
| 1731 | } | 1747 | } |
| 1732 | } | 1748 | } |
| 1733 | 1749 | ||
| 1734 | rewind (inf); | 1750 | reset_input (inf); |
| 1735 | 1751 | ||
| 1736 | /* Else try to guess the language given the case insensitive file name. */ | 1752 | /* Else try to guess the language given the case insensitive file name. */ |
| 1737 | if (parser == NULL) | 1753 | if (parser == NULL) |
| @@ -1755,7 +1771,7 @@ find_entries (FILE *inf) | |||
| 1755 | if (old_last_node == last_node) | 1771 | if (old_last_node == last_node) |
| 1756 | /* No Fortran entries found. Try C. */ | 1772 | /* No Fortran entries found. Try C. */ |
| 1757 | { | 1773 | { |
| 1758 | rewind (inf); | 1774 | reset_input (inf); |
| 1759 | curfdp->lang = get_language_from_langname (cplusplus ? "c++" : "c"); | 1775 | curfdp->lang = get_language_from_langname (cplusplus ? "c++" : "c"); |
| 1760 | find_entries (inf); | 1776 | find_entries (inf); |
| 1761 | } | 1777 | } |
| @@ -2965,7 +2981,7 @@ do { \ | |||
| 2965 | 2981 | ||
| 2966 | #define CNL() \ | 2982 | #define CNL() \ |
| 2967 | do { \ | 2983 | do { \ |
| 2968 | CNL_SAVE_DEFINEDEF(); \ | 2984 | CNL_SAVE_DEFINEDEF (); \ |
| 2969 | if (savetoken.valid) \ | 2985 | if (savetoken.valid) \ |
| 2970 | { \ | 2986 | { \ |
| 2971 | token = savetoken; \ | 2987 | token = savetoken; \ |
| @@ -2994,6 +3010,12 @@ make_C_tag (bool isfun) | |||
| 2994 | token.valid = false; | 3010 | token.valid = false; |
| 2995 | } | 3011 | } |
| 2996 | 3012 | ||
| 3013 | static bool | ||
| 3014 | perhaps_more_input (FILE *inf) | ||
| 3015 | { | ||
| 3016 | return !feof (inf) && !ferror (inf); | ||
| 3017 | } | ||
| 3018 | |||
| 2997 | 3019 | ||
| 2998 | /* | 3020 | /* |
| 2999 | * C_entries () | 3021 | * C_entries () |
| @@ -3051,7 +3073,7 @@ C_entries (int c_ext, FILE *inf) | |||
| 3051 | { qualifier = "::"; qlen = 2; } | 3073 | { qualifier = "::"; qlen = 2; } |
| 3052 | 3074 | ||
| 3053 | 3075 | ||
| 3054 | while (!feof (inf)) | 3076 | while (perhaps_more_input (inf)) |
| 3055 | { | 3077 | { |
| 3056 | c = *lp++; | 3078 | c = *lp++; |
| 3057 | if (c == '\\') | 3079 | if (c == '\\') |
| @@ -3892,13 +3914,10 @@ Yacc_entries (FILE *inf) | |||
| 3892 | 3914 | ||
| 3893 | /* Useful macros. */ | 3915 | /* Useful macros. */ |
| 3894 | #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \ | 3916 | #define LOOP_ON_INPUT_LINES(file_pointer, line_buffer, char_pointer) \ |
| 3895 | for (; /* loop initialization */ \ | 3917 | while (perhaps_more_input (file_pointer) \ |
| 3896 | !feof (file_pointer) /* loop test */ \ | 3918 | && (readline (&(line_buffer), file_pointer), \ |
| 3897 | && /* instructions at start of loop */ \ | 3919 | (char_pointer) = (line_buffer).buffer, \ |
| 3898 | (readline (&line_buffer, file_pointer), \ | 3920 | true)) \ |
| 3899 | char_pointer = line_buffer.buffer, \ | ||
| 3900 | true); \ | ||
| 3901 | ) | ||
| 3902 | 3921 | ||
| 3903 | #define LOOKING_AT(cp, kw) /* kw is the keyword, a literal string */ \ | 3922 | #define LOOKING_AT(cp, kw) /* kw is the keyword, a literal string */ \ |
| 3904 | ((assert ("" kw), true) /* syntax error if not a literal string */ \ | 3923 | ((assert ("" kw), true) /* syntax error if not a literal string */ \ |
| @@ -3919,7 +3938,7 @@ Yacc_entries (FILE *inf) | |||
| 3919 | static void | 3938 | static void |
| 3920 | just_read_file (FILE *inf) | 3939 | just_read_file (FILE *inf) |
| 3921 | { | 3940 | { |
| 3922 | while (!feof (inf)) | 3941 | while (perhaps_more_input (inf)) |
| 3923 | readline (&lb, inf); | 3942 | readline (&lb, inf); |
| 3924 | } | 3943 | } |
| 3925 | 3944 | ||
| @@ -4074,7 +4093,7 @@ Ada_getit (FILE *inf, const char *name_qualifier) | |||
| 4074 | char *name; | 4093 | char *name; |
| 4075 | char c; | 4094 | char c; |
| 4076 | 4095 | ||
| 4077 | while (!feof (inf)) | 4096 | while (perhaps_more_input (inf)) |
| 4078 | { | 4097 | { |
| 4079 | dbp = skip_spaces (dbp); | 4098 | dbp = skip_spaces (dbp); |
| 4080 | if (*dbp == '\0' | 4099 | if (*dbp == '\0' |
| @@ -4576,7 +4595,7 @@ Pascal_functions (FILE *inf) | |||
| 4576 | verify_tag = false; /* check if "extern" is ahead */ | 4595 | verify_tag = false; /* check if "extern" is ahead */ |
| 4577 | 4596 | ||
| 4578 | 4597 | ||
| 4579 | while (!feof (inf)) /* long main loop to get next char */ | 4598 | while (perhaps_more_input (inf)) /* long main loop to get next char */ |
| 4580 | { | 4599 | { |
| 4581 | c = *dbp++; | 4600 | c = *dbp++; |
| 4582 | if (c == '\0') /* if end of line */ | 4601 | if (c == '\0') /* if end of line */ |
| @@ -5033,7 +5052,7 @@ TEX_mode (FILE *inf) | |||
| 5033 | TEX_opgrp = '<'; | 5052 | TEX_opgrp = '<'; |
| 5034 | TEX_clgrp = '>'; | 5053 | TEX_clgrp = '>'; |
| 5035 | } | 5054 | } |
| 5036 | rewind (inf); | 5055 | reset_input (inf); |
| 5037 | } | 5056 | } |
| 5038 | 5057 | ||
| 5039 | /* Read environment and prepend it to the default string. | 5058 | /* Read environment and prepend it to the default string. |
| @@ -5279,7 +5298,7 @@ prolog_skip_comment (linebuffer *plb, FILE *inf) | |||
| 5279 | return; | 5298 | return; |
| 5280 | readline (plb, inf); | 5299 | readline (plb, inf); |
| 5281 | } | 5300 | } |
| 5282 | while (!feof (inf)); | 5301 | while (perhaps_more_input (inf)); |
| 5283 | } | 5302 | } |
| 5284 | 5303 | ||
| 5285 | /* | 5304 | /* |
| @@ -5629,10 +5648,11 @@ analyze_regex (char *regex_arg) | |||
| 5629 | if (regexfp == NULL) | 5648 | if (regexfp == NULL) |
| 5630 | pfatal (regexfile); | 5649 | pfatal (regexfile); |
| 5631 | linebuffer_init (®exbuf); | 5650 | linebuffer_init (®exbuf); |
| 5632 | while (readline_internal (®exbuf, regexfp) > 0) | 5651 | while (readline_internal (®exbuf, regexfp, regexfile) > 0) |
| 5633 | analyze_regex (regexbuf.buffer); | 5652 | analyze_regex (regexbuf.buffer); |
| 5634 | free (regexbuf.buffer); | 5653 | free (regexbuf.buffer); |
| 5635 | fclose (regexfp); | 5654 | if (fclose (regexfp) != 0) |
| 5655 | pfatal (regexfile); | ||
| 5636 | } | 5656 | } |
| 5637 | break; | 5657 | break; |
| 5638 | 5658 | ||
| @@ -5972,11 +5992,11 @@ get_tag (register char *bp, char **namepp) | |||
| 5972 | * appended to `filebuf'. | 5992 | * appended to `filebuf'. |
| 5973 | */ | 5993 | */ |
| 5974 | static long | 5994 | static long |
| 5975 | readline_internal (linebuffer *lbp, register FILE *stream) | 5995 | readline_internal (linebuffer *lbp, FILE *stream, char const *filename) |
| 5976 | { | 5996 | { |
| 5977 | char *buffer = lbp->buffer; | 5997 | char *buffer = lbp->buffer; |
| 5978 | register char *p = lbp->buffer; | 5998 | char *p = lbp->buffer; |
| 5979 | register char *pend; | 5999 | char *pend; |
| 5980 | int chars_deleted; | 6000 | int chars_deleted; |
| 5981 | 6001 | ||
| 5982 | pend = p + lbp->size; /* Separate to avoid 386/IX compiler bug. */ | 6002 | pend = p + lbp->size; /* Separate to avoid 386/IX compiler bug. */ |
| @@ -5995,6 +6015,8 @@ readline_internal (linebuffer *lbp, register FILE *stream) | |||
| 5995 | } | 6015 | } |
| 5996 | if (c == EOF) | 6016 | if (c == EOF) |
| 5997 | { | 6017 | { |
| 6018 | if (ferror (stream)) | ||
| 6019 | perror (filename); | ||
| 5998 | *p = '\0'; | 6020 | *p = '\0'; |
| 5999 | chars_deleted = 0; | 6021 | chars_deleted = 0; |
| 6000 | break; | 6022 | break; |
| @@ -6055,7 +6077,7 @@ readline (linebuffer *lbp, FILE *stream) | |||
| 6055 | long result; | 6077 | long result; |
| 6056 | 6078 | ||
| 6057 | linecharno = charno; /* update global char number of line start */ | 6079 | linecharno = charno; /* update global char number of line start */ |
| 6058 | result = readline_internal (lbp, stream); /* read line */ | 6080 | result = readline_internal (lbp, stream, infilename); /* read line */ |
| 6059 | lineno += 1; /* increment global line number */ | 6081 | lineno += 1; /* increment global line number */ |
| 6060 | charno += result; /* increment global char number */ | 6082 | charno += result; /* increment global char number */ |
| 6061 | 6083 | ||
| @@ -6386,13 +6408,13 @@ etags_mktmp (void) | |||
| 6386 | 6408 | ||
| 6387 | char *templt = concat (tmpdir, slash, "etXXXXXX"); | 6409 | char *templt = concat (tmpdir, slash, "etXXXXXX"); |
| 6388 | int fd = mkostemp (templt, O_CLOEXEC); | 6410 | int fd = mkostemp (templt, O_CLOEXEC); |
| 6389 | if (fd < 0) | 6411 | if (fd < 0 || close (fd) != 0) |
| 6390 | { | 6412 | { |
| 6413 | int temp_errno = errno; | ||
| 6391 | free (templt); | 6414 | free (templt); |
| 6415 | errno = temp_errno; | ||
| 6392 | templt = NULL; | 6416 | templt = NULL; |
| 6393 | } | 6417 | } |
| 6394 | else | ||
| 6395 | close (fd); | ||
| 6396 | 6418 | ||
| 6397 | #if defined (DOS_NT) | 6419 | #if defined (DOS_NT) |
| 6398 | /* The file name will be used in shell redirection, so it needs to have | 6420 | /* The file name will be used in shell redirection, so it needs to have |
| @@ -6402,6 +6424,7 @@ etags_mktmp (void) | |||
| 6402 | if (*p == '/') | 6424 | if (*p == '/') |
| 6403 | *p = '\\'; | 6425 | *p = '\\'; |
| 6404 | #endif | 6426 | #endif |
| 6427 | |||
| 6405 | return templt; | 6428 | return templt; |
| 6406 | } | 6429 | } |
| 6407 | 6430 | ||