diff options
Diffstat (limited to 'src/sysdep.c')
| -rw-r--r-- | src/sysdep.c | 280 |
1 files changed, 120 insertions, 160 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index b84e6a4ea3a..dbfd9efc7d4 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -21,9 +21,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 21 | 21 | ||
| 22 | #define SYSTIME_INLINE EXTERN_INLINE | 22 | #define SYSTIME_INLINE EXTERN_INLINE |
| 23 | 23 | ||
| 24 | #include <signal.h> | 24 | #include <execinfo.h> |
| 25 | #include <stdio.h> | 25 | #include <stdio.h> |
| 26 | #include <setjmp.h> | ||
| 27 | #ifdef HAVE_PWD_H | 26 | #ifdef HAVE_PWD_H |
| 28 | #include <pwd.h> | 27 | #include <pwd.h> |
| 29 | #include <grp.h> | 28 | #include <grp.h> |
| @@ -107,9 +106,6 @@ extern char *getwd (char *); | |||
| 107 | 106 | ||
| 108 | static int emacs_get_tty (int, struct emacs_tty *); | 107 | static int emacs_get_tty (int, struct emacs_tty *); |
| 109 | static int emacs_set_tty (int, struct emacs_tty *, int); | 108 | static int emacs_set_tty (int, struct emacs_tty *, int); |
| 110 | #if defined TIOCNOTTY || defined USG5 || defined CYGWIN | ||
| 111 | static _Noreturn void croak (char *); | ||
| 112 | #endif | ||
| 113 | 109 | ||
| 114 | /* ULLONG_MAX is missing on Red Hat Linux 7.3; see Bug#11781. */ | 110 | /* ULLONG_MAX is missing on Red Hat Linux 7.3; see Bug#11781. */ |
| 115 | #ifndef ULLONG_MAX | 111 | #ifndef ULLONG_MAX |
| @@ -302,27 +298,34 @@ wait_for_termination_1 (pid_t pid, int interruptible) | |||
| 302 | termination of subprocesses, perhaps involving a kernel bug too, | 298 | termination of subprocesses, perhaps involving a kernel bug too, |
| 303 | but no idea what it is. Just as a hunch we signal SIGCHLD to see | 299 | but no idea what it is. Just as a hunch we signal SIGCHLD to see |
| 304 | if that causes the problem to go away or get worse. */ | 300 | if that causes the problem to go away or get worse. */ |
| 305 | sigsetmask (sigmask (SIGCHLD)); | 301 | sigset_t sigchild_mask; |
| 302 | sigemptyset (&sigchild_mask); | ||
| 303 | sigaddset (&sigchild_mask, SIGCHLD); | ||
| 304 | pthread_sigmask (SIG_SETMASK, &sigchild_mask, 0); | ||
| 305 | |||
| 306 | if (0 > kill (pid, 0)) | 306 | if (0 > kill (pid, 0)) |
| 307 | { | 307 | { |
| 308 | sigsetmask (SIGEMPTYMASK); | 308 | pthread_sigmask (SIG_SETMASK, &empty_mask, 0); |
| 309 | kill (getpid (), SIGCHLD); | 309 | kill (getpid (), SIGCHLD); |
| 310 | break; | 310 | break; |
| 311 | } | 311 | } |
| 312 | if (wait_debugging) | 312 | if (wait_debugging) |
| 313 | sleep (1); | 313 | sleep (1); |
| 314 | else | 314 | else |
| 315 | sigpause (SIGEMPTYMASK); | 315 | sigsuspend (&empty_mask); |
| 316 | #else /* not BSD_SYSTEM, and not HPUX version >= 6 */ | 316 | #else /* not BSD_SYSTEM, and not HPUX version >= 6 */ |
| 317 | #ifdef WINDOWSNT | 317 | #ifdef WINDOWSNT |
| 318 | wait (0); | 318 | wait (0); |
| 319 | break; | 319 | break; |
| 320 | #else /* not WINDOWSNT */ | 320 | #else /* not WINDOWSNT */ |
| 321 | sigblock (sigmask (SIGCHLD)); | 321 | sigset_t blocked; |
| 322 | sigemptyset (&blocked); | ||
| 323 | sigaddset (&blocked, SIGCHLD); | ||
| 324 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 322 | errno = 0; | 325 | errno = 0; |
| 323 | if (kill (pid, 0) == -1 && errno == ESRCH) | 326 | if (kill (pid, 0) == -1 && errno == ESRCH) |
| 324 | { | 327 | { |
| 325 | sigunblock (sigmask (SIGCHLD)); | 328 | pthread_sigmask (SIG_UNBLOCK, &blocked, 0); |
| 326 | break; | 329 | break; |
| 327 | } | 330 | } |
| 328 | 331 | ||
| @@ -456,11 +459,11 @@ child_setup_tty (int out) | |||
| 456 | #endif /* not MSDOS */ | 459 | #endif /* not MSDOS */ |
| 457 | 460 | ||
| 458 | 461 | ||
| 459 | /* Record a signal code and the handler for it. */ | 462 | /* Record a signal code and the action for it. */ |
| 460 | struct save_signal | 463 | struct save_signal |
| 461 | { | 464 | { |
| 462 | int code; | 465 | int code; |
| 463 | void (*handler) (int); | 466 | struct sigaction action; |
| 464 | }; | 467 | }; |
| 465 | 468 | ||
| 466 | static void save_signal_handlers (struct save_signal *); | 469 | static void save_signal_handlers (struct save_signal *); |
| @@ -506,7 +509,7 @@ sys_subshell (void) | |||
| 506 | saved_handlers[0].code = SIGINT; | 509 | saved_handlers[0].code = SIGINT; |
| 507 | saved_handlers[1].code = SIGQUIT; | 510 | saved_handlers[1].code = SIGQUIT; |
| 508 | saved_handlers[2].code = SIGTERM; | 511 | saved_handlers[2].code = SIGTERM; |
| 509 | #ifdef SIGIO | 512 | #ifdef USABLE_SIGIO |
| 510 | saved_handlers[3].code = SIGIO; | 513 | saved_handlers[3].code = SIGIO; |
| 511 | saved_handlers[4].code = 0; | 514 | saved_handlers[4].code = 0; |
| 512 | #else | 515 | #else |
| @@ -618,8 +621,9 @@ save_signal_handlers (struct save_signal *saved_handlers) | |||
| 618 | { | 621 | { |
| 619 | while (saved_handlers->code) | 622 | while (saved_handlers->code) |
| 620 | { | 623 | { |
| 621 | saved_handlers->handler | 624 | struct sigaction action; |
| 622 | = (void (*) (int)) signal (saved_handlers->code, SIG_IGN); | 625 | emacs_sigaction_init (&action, SIG_IGN); |
| 626 | sigaction (saved_handlers->code, &action, &saved_handlers->action); | ||
| 623 | saved_handlers++; | 627 | saved_handlers++; |
| 624 | } | 628 | } |
| 625 | } | 629 | } |
| @@ -629,118 +633,80 @@ restore_signal_handlers (struct save_signal *saved_handlers) | |||
| 629 | { | 633 | { |
| 630 | while (saved_handlers->code) | 634 | while (saved_handlers->code) |
| 631 | { | 635 | { |
| 632 | signal (saved_handlers->code, saved_handlers->handler); | 636 | sigaction (saved_handlers->code, &saved_handlers->action, 0); |
| 633 | saved_handlers++; | 637 | saved_handlers++; |
| 634 | } | 638 | } |
| 635 | } | 639 | } |
| 636 | 640 | ||
| 637 | #ifndef SIGIO | 641 | #ifdef USABLE_SIGIO |
| 638 | /* If SIGIO is broken, don't do anything. */ | ||
| 639 | void | ||
| 640 | init_sigio (int fd) | ||
| 641 | { | ||
| 642 | } | ||
| 643 | |||
| 644 | static void | ||
| 645 | reset_sigio (int fd) | ||
| 646 | { | ||
| 647 | } | ||
| 648 | |||
| 649 | void | ||
| 650 | request_sigio (void) | ||
| 651 | { | ||
| 652 | } | ||
| 653 | |||
| 654 | void | ||
| 655 | unrequest_sigio (void) | ||
| 656 | { | ||
| 657 | } | ||
| 658 | |||
| 659 | #else | ||
| 660 | #ifdef F_SETFL | ||
| 661 | |||
| 662 | static int old_fcntl_flags[MAXDESC]; | 642 | static int old_fcntl_flags[MAXDESC]; |
| 643 | #endif | ||
| 663 | 644 | ||
| 664 | void | 645 | void |
| 665 | init_sigio (int fd) | 646 | init_sigio (int fd) |
| 666 | { | 647 | { |
| 667 | #ifdef FASYNC | 648 | #ifdef USABLE_SIGIO |
| 668 | old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC; | 649 | old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC; |
| 669 | fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC); | 650 | fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC); |
| 670 | #endif | ||
| 671 | interrupts_deferred = 0; | 651 | interrupts_deferred = 0; |
| 652 | #endif | ||
| 672 | } | 653 | } |
| 673 | 654 | ||
| 674 | static void | 655 | static void |
| 675 | reset_sigio (int fd) | 656 | reset_sigio (int fd) |
| 676 | { | 657 | { |
| 677 | #ifdef FASYNC | 658 | #ifdef USABLE_SIGIO |
| 678 | fcntl (fd, F_SETFL, old_fcntl_flags[fd]); | 659 | fcntl (fd, F_SETFL, old_fcntl_flags[fd]); |
| 679 | #endif | 660 | #endif |
| 680 | } | 661 | } |
| 681 | 662 | ||
| 682 | #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */ | ||
| 683 | /* XXX Uhm, FASYNC is not used anymore here. */ | ||
| 684 | /* XXX Yeah, but you need it for SIGIO, don't you? */ | ||
| 685 | |||
| 686 | void | 663 | void |
| 687 | request_sigio (void) | 664 | request_sigio (void) |
| 688 | { | 665 | { |
| 666 | #ifdef USABLE_SIGIO | ||
| 667 | sigset_t unblocked; | ||
| 668 | |||
| 689 | if (noninteractive) | 669 | if (noninteractive) |
| 690 | return; | 670 | return; |
| 691 | 671 | ||
| 692 | #ifdef SIGWINCH | 672 | sigemptyset (&unblocked); |
| 693 | sigunblock (sigmask (SIGWINCH)); | 673 | # ifdef SIGWINCH |
| 694 | #endif | 674 | sigaddset (&unblocked, SIGWINCH); |
| 695 | sigunblock (sigmask (SIGIO)); | 675 | # endif |
| 676 | sigaddset (&unblocked, SIGIO); | ||
| 677 | pthread_sigmask (SIG_UNBLOCK, &unblocked, 0); | ||
| 696 | 678 | ||
| 697 | interrupts_deferred = 0; | 679 | interrupts_deferred = 0; |
| 680 | #endif | ||
| 698 | } | 681 | } |
| 699 | 682 | ||
| 700 | void | 683 | void |
| 701 | unrequest_sigio (void) | 684 | unrequest_sigio (void) |
| 702 | { | 685 | { |
| 703 | if (noninteractive) | 686 | #ifdef USABLE_SIGIO |
| 704 | return; | 687 | sigset_t blocked; |
| 705 | 688 | ||
| 706 | #if 0 /* XXX What's wrong with blocking SIGIO under X? */ | 689 | if (noninteractive) |
| 707 | if (x_display_list) | ||
| 708 | return; | 690 | return; |
| 709 | #endif | ||
| 710 | 691 | ||
| 711 | #ifdef SIGWINCH | 692 | sigemptyset (&blocked); |
| 712 | sigblock (sigmask (SIGWINCH)); | 693 | # ifdef SIGWINCH |
| 713 | #endif | 694 | sigaddset (&blocked, SIGWINCH); |
| 714 | sigblock (sigmask (SIGIO)); | 695 | # endif |
| 696 | sigaddset (&blocked, SIGIO); | ||
| 697 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 715 | interrupts_deferred = 1; | 698 | interrupts_deferred = 1; |
| 716 | } | 699 | #endif |
| 717 | |||
| 718 | #else /* no FASYNC */ | ||
| 719 | #ifndef MSDOS | ||
| 720 | |||
| 721 | void | ||
| 722 | request_sigio (void) | ||
| 723 | { | ||
| 724 | if (noninteractive || read_socket_hook) | ||
| 725 | return; | ||
| 726 | |||
| 727 | croak ("request_sigio"); | ||
| 728 | } | 700 | } |
| 729 | 701 | ||
| 730 | void | 702 | void |
| 731 | unrequest_sigio (void) | 703 | ignore_sigio (void) |
| 732 | { | 704 | { |
| 733 | if (noninteractive || read_socket_hook) | 705 | #ifdef USABLE_SIGIO |
| 734 | return; | 706 | signal (SIGIO, SIG_IGN); |
| 735 | 707 | #endif | |
| 736 | croak ("unrequest_sigio"); | ||
| 737 | } | 708 | } |
| 738 | 709 | ||
| 739 | #endif /* MSDOS */ | ||
| 740 | #endif /* FASYNC */ | ||
| 741 | #endif /* F_SETFL */ | ||
| 742 | #endif /* SIGIO */ | ||
| 743 | |||
| 744 | 710 | ||
| 745 | /* Getting and setting emacs_tty structures. */ | 711 | /* Getting and setting emacs_tty structures. */ |
| 746 | 712 | ||
| @@ -1470,86 +1436,64 @@ init_system_name (void) | |||
| 1470 | } | 1436 | } |
| 1471 | } | 1437 | } |
| 1472 | 1438 | ||
| 1473 | /* POSIX signals support - DJB */ | ||
| 1474 | /* Anyone with POSIX signals should have ANSI C declarations */ | ||
| 1475 | |||
| 1476 | sigset_t empty_mask; | 1439 | sigset_t empty_mask; |
| 1477 | 1440 | ||
| 1478 | #ifndef WINDOWSNT | 1441 | /* Store into *ACTION a signal action suitable for Emacs, with handler |
| 1479 | 1442 | HANDLER. */ | |
| 1480 | signal_handler_t | 1443 | void |
| 1481 | sys_signal (int signal_number, signal_handler_t action) | 1444 | emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) |
| 1482 | { | 1445 | { |
| 1483 | struct sigaction new_action, old_action; | 1446 | sigemptyset (&action->sa_mask); |
| 1484 | sigemptyset (&new_action.sa_mask); | 1447 | action->sa_handler = handler; |
| 1485 | new_action.sa_handler = action; | 1448 | action->sa_flags = 0; |
| 1486 | new_action.sa_flags = 0; | ||
| 1487 | #if defined (SA_RESTART) | 1449 | #if defined (SA_RESTART) |
| 1488 | /* Emacs mostly works better with restartable system services. If this | 1450 | /* SA_RESTART causes interruptible functions with timeouts (e.g., |
| 1489 | flag exists, we probably want to turn it on here. | 1451 | 'select') to reset their timeout on some platforms (e.g., |
| 1490 | However, on some systems (only hpux11 at present) this resets the | 1452 | HP-UX 11), which is not what we want. Also, when Emacs is |
| 1491 | timeout of `select' which means that `select' never finishes if | 1453 | interactive, we don't want SA_RESTART because we need to poll |
| 1492 | it keeps getting signals. | ||
| 1493 | We define BROKEN_SA_RESTART on those systems. */ | ||
| 1494 | /* It's not clear why the comment above says "mostly works better". --Stef | ||
| 1495 | When SYNC_INPUT is set, we don't want SA_RESTART because we need to poll | ||
| 1496 | for pending input so we need long-running syscalls to be interrupted | 1454 | for pending input so we need long-running syscalls to be interrupted |
| 1497 | after a signal that sets the interrupt_input_pending flag. */ | 1455 | after a signal that sets the interrupt_input_pending flag. */ |
| 1498 | /* Non-interactive keyboard input goes through stdio, where we always | 1456 | /* Non-interactive keyboard input goes through stdio, where we always |
| 1499 | want restartable system calls. */ | 1457 | want restartable system calls. */ |
| 1500 | # if defined (BROKEN_SA_RESTART) || defined (SYNC_INPUT) | ||
| 1501 | if (noninteractive) | 1458 | if (noninteractive) |
| 1502 | # endif | 1459 | action->sa_flags = SA_RESTART; |
| 1503 | new_action.sa_flags = SA_RESTART; | ||
| 1504 | #endif | 1460 | #endif |
| 1505 | sigaction (signal_number, &new_action, &old_action); | ||
| 1506 | return (old_action.sa_handler); | ||
| 1507 | } | 1461 | } |
| 1508 | 1462 | ||
| 1509 | #endif /* WINDOWSNT */ | 1463 | #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD |
| 1510 | 1464 | static pthread_t main_thread; | |
| 1511 | #ifndef __GNUC__ | ||
| 1512 | /* If we're compiling with GCC, we don't need this function, since it | ||
| 1513 | can be written as a macro. */ | ||
| 1514 | sigset_t | ||
| 1515 | sys_sigmask (int sig) | ||
| 1516 | { | ||
| 1517 | sigset_t mask; | ||
| 1518 | sigemptyset (&mask); | ||
| 1519 | sigaddset (&mask, sig); | ||
| 1520 | return mask; | ||
| 1521 | } | ||
| 1522 | #endif | 1465 | #endif |
| 1523 | 1466 | ||
| 1524 | /* I'd like to have these guys return pointers to the mask storage in here, | 1467 | /* If we are on the main thread, handle the signal SIG with HANDLER. |
| 1525 | but there'd be trouble if the code was saving multiple masks. I'll be | 1468 | Otherwise, redirect the signal to the main thread, blocking it from |
| 1526 | safe and pass the structure. It normally won't be more than 2 bytes | 1469 | this thread. POSIX says any thread can receive a signal that is |
| 1527 | anyhow. - DJB */ | 1470 | associated with a process, process group, or asynchronous event. |
| 1528 | 1471 | On GNU/Linux that is not true, but for other systems (FreeBSD at | |
| 1529 | sigset_t | 1472 | least) it is. */ |
| 1530 | sys_sigblock (sigset_t new_mask) | 1473 | void |
| 1474 | handle_on_main_thread (int sig, signal_handler_t handler) | ||
| 1531 | { | 1475 | { |
| 1532 | sigset_t old_mask; | 1476 | /* Preserve errno, to avoid race conditions with signal handlers that |
| 1533 | pthread_sigmask (SIG_BLOCK, &new_mask, &old_mask); | 1477 | might change errno. Races can occur even in single-threaded hosts. */ |
| 1534 | return (old_mask); | 1478 | int old_errno = errno; |
| 1535 | } | ||
| 1536 | 1479 | ||
| 1537 | sigset_t | 1480 | bool on_main_thread = true; |
| 1538 | sys_sigunblock (sigset_t new_mask) | 1481 | #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD |
| 1539 | { | 1482 | if (! pthread_equal (pthread_self (), main_thread)) |
| 1540 | sigset_t old_mask; | 1483 | { |
| 1541 | pthread_sigmask (SIG_UNBLOCK, &new_mask, &old_mask); | 1484 | sigset_t blocked; |
| 1542 | return (old_mask); | 1485 | sigemptyset (&blocked); |
| 1543 | } | 1486 | sigaddset (&blocked, sig); |
| 1487 | pthread_sigmask (SIG_BLOCK, &blocked, 0); | ||
| 1488 | pthread_kill (main_thread, sig); | ||
| 1489 | on_main_thread = false; | ||
| 1490 | } | ||
| 1491 | #endif | ||
| 1492 | if (on_main_thread) | ||
| 1493 | handler (sig); | ||
| 1544 | 1494 | ||
| 1545 | sigset_t | 1495 | errno = old_errno; |
| 1546 | sys_sigsetmask (sigset_t new_mask) | ||
| 1547 | { | ||
| 1548 | sigset_t old_mask; | ||
| 1549 | pthread_sigmask (SIG_SETMASK, &new_mask, &old_mask); | ||
| 1550 | return (old_mask); | ||
| 1551 | } | 1496 | } |
| 1552 | |||
| 1553 | 1497 | ||
| 1554 | #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST | 1498 | #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST |
| 1555 | static char *my_sys_siglist[NSIG]; | 1499 | static char *my_sys_siglist[NSIG]; |
| @@ -1564,6 +1508,10 @@ init_signals (void) | |||
| 1564 | { | 1508 | { |
| 1565 | sigemptyset (&empty_mask); | 1509 | sigemptyset (&empty_mask); |
| 1566 | 1510 | ||
| 1511 | #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD | ||
| 1512 | main_thread = pthread_self (); | ||
| 1513 | #endif | ||
| 1514 | |||
| 1567 | #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST | 1515 | #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST |
| 1568 | if (! initialized) | 1516 | if (! initialized) |
| 1569 | { | 1517 | { |
| @@ -1856,6 +1804,33 @@ snprintf (char *buf, size_t bufsize, char const *format, ...) | |||
| 1856 | } | 1804 | } |
| 1857 | #endif | 1805 | #endif |
| 1858 | 1806 | ||
| 1807 | /* If a backtrace is available, output the top lines of it to stderr. | ||
| 1808 | Do not output more than BACKTRACE_LIMIT or BACKTRACE_LIMIT_MAX lines. | ||
| 1809 | This function may be called from a signal handler, so it should | ||
| 1810 | not invoke async-unsafe functions like malloc. */ | ||
| 1811 | void | ||
| 1812 | emacs_backtrace (int backtrace_limit) | ||
| 1813 | { | ||
| 1814 | enum { BACKTRACE_LIMIT_MAX = 500 }; | ||
| 1815 | void *buffer[BACKTRACE_LIMIT_MAX + 1]; | ||
| 1816 | int bounded_limit = min (backtrace_limit, BACKTRACE_LIMIT_MAX); | ||
| 1817 | int npointers = backtrace (buffer, bounded_limit + 1); | ||
| 1818 | if (npointers) | ||
| 1819 | ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12)); | ||
| 1820 | backtrace_symbols_fd (buffer, bounded_limit, STDERR_FILENO); | ||
| 1821 | if (bounded_limit < npointers) | ||
| 1822 | ignore_value (write (STDERR_FILENO, "...\n", 4)); | ||
| 1823 | } | ||
| 1824 | |||
| 1825 | #ifndef HAVE_NTGUI | ||
| 1826 | /* Using emacs_abort lets GDB return from a breakpoint here. */ | ||
| 1827 | void | ||
| 1828 | emacs_abort (void) | ||
| 1829 | { | ||
| 1830 | fatal_error_backtrace (SIGABRT, 10); | ||
| 1831 | } | ||
| 1832 | #endif | ||
| 1833 | |||
| 1859 | int | 1834 | int |
| 1860 | emacs_open (const char *path, int oflag, int mode) | 1835 | emacs_open (const char *path, int oflag, int mode) |
| 1861 | { | 1836 | { |
| @@ -1933,11 +1908,9 @@ emacs_write (int fildes, const char *buf, ptrdiff_t nbyte) | |||
| 1933 | { | 1908 | { |
| 1934 | if (errno == EINTR) | 1909 | if (errno == EINTR) |
| 1935 | { | 1910 | { |
| 1936 | #ifdef SYNC_INPUT | ||
| 1937 | /* I originally used `QUIT' but that might causes files to | 1911 | /* I originally used `QUIT' but that might causes files to |
| 1938 | be truncated if you hit C-g in the middle of it. --Stef */ | 1912 | be truncated if you hit C-g in the middle of it. --Stef */ |
| 1939 | process_pending_signals (); | 1913 | process_pending_signals (); |
| 1940 | #endif | ||
| 1941 | continue; | 1914 | continue; |
| 1942 | } | 1915 | } |
| 1943 | else | 1916 | else |
| @@ -2020,19 +1993,6 @@ getwd (char *pathname) | |||
| 2020 | } | 1993 | } |
| 2021 | 1994 | ||
| 2022 | #endif /* !defined (HAVE_GETWD) || defined (BROKEN_GETWD) */ | 1995 | #endif /* !defined (HAVE_GETWD) || defined (BROKEN_GETWD) */ |
| 2023 | |||
| 2024 | /* | ||
| 2025 | * This function will go away as soon as all the stubs fixed. (fnf) | ||
| 2026 | */ | ||
| 2027 | |||
| 2028 | void | ||
| 2029 | croak (char *badfunc) | ||
| 2030 | { | ||
| 2031 | printf ("%s not yet implemented\r\n", badfunc); | ||
| 2032 | reset_all_sys_modes (); | ||
| 2033 | exit (1); | ||
| 2034 | } | ||
| 2035 | |||
| 2036 | #endif /* USG */ | 1996 | #endif /* USG */ |
| 2037 | 1997 | ||
| 2038 | /* Directory routines for systems that don't have them. */ | 1998 | /* Directory routines for systems that don't have them. */ |