comparison src/sysdep.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents 76d5a3dd827a
children e65d9cf16707
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* Interfaces to system-dependent kernel and library entries. 1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985-1988, 1992-1995 Free Software Foundation, Inc. 2 Copyright (C) 1985-1988, 1992-1995 Free Software Foundation, Inc.
3 Copyright (C) 1995 Tinker Systems. 3 Copyright (C) 1995 Tinker Systems.
4 Copyright (C) 2000, 2001 Ben Wing.
4 5
5 This file is part of XEmacs. 6 This file is part of XEmacs.
6 7
7 XEmacs is free software; you can redistribute it and/or modify it 8 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 9 under the terms of the GNU General Public License as published by the
17 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to 19 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */ 21 Boston, MA 02111-1307, USA. */
21 22
23
22 /* Synched up with: FSF 19.30 except for some Windows-NT crap. */ 24 /* Synched up with: FSF 19.30 except for some Windows-NT crap. */
23 25
24 /* Substantially cleaned up by Ben Wing, Dec. 1994 / Jan. 1995. */ 26 /* Authorship:
25 27
26 /* In this file, open, read and write refer to the system calls, 28 Current primary author: Various
27 not our sugared interfaces sys_open, sys_read and sys_write. 29
28 */ 30 Originally from FSF. Major changes at various times.
29 31 Substantially cleaned up by Ben Wing, Dec. 1994 / Jan. 1995.
30 #define DONT_ENCAPSULATE 32 SIGIO stuff ripped apart and redone by Ben Wing. (during 19.14 devel?)
33 Signal stuff totally redone by Ben Wing. (during 19.14 devel? that would
34 be Dec 1995 - Apr 1996.)
35 Controlling terminal stuff redone by Ben Wing for 19.13.
36 System call encapsulation stuff written by Ben Wing for 19.12. (1995)
37 Ripped up and redone avoiding preprocessor tricks Aug - Sep 2001 during
38 Mule-on-Windows development.
39 */
31 40
32 #include <config.h> 41 #include <config.h>
33
34 #ifdef WIN32_NATIVE
35 #ifdef MINGW
36 #include <../mingw/process.h>
37 #else
38 /* <process.h> should not conflict with "process.h", as per ANSI definition.
39 This is not true with visual c though. The trick below works with
40 VC4.2b, 5.0 and 6.0. It assumes that VC is installed in a kind of
41 standard way, so include path ends with /include.
42
43 Unfortunately, this must go before lisp.h, since process.h defines abort()
44 which will conflict with the macro defined in lisp.h
45 */
46 #include <../include/process.h>
47 #endif /* MINGW */
48 #endif /* WIN32_NATIVE */
49
50 #include "lisp.h" 42 #include "lisp.h"
51 43
52 /* ------------------------------- */ 44 /* ------------------------------- */
53 /* basic includes */ 45 /* basic includes */
54 /* ------------------------------- */ 46 /* ------------------------------- */
69 #include "process.h" 61 #include "process.h"
70 #include "sysdep.h" 62 #include "sysdep.h"
71 #include "window.h" 63 #include "window.h"
72 64
73 #include <setjmp.h> 65 #include <setjmp.h>
74 #ifdef HAVE_LIBGEN_H /* Must come before sysfile.h */
75 #include <libgen.h>
76 #endif
77 #include "sysfile.h" 66 #include "sysfile.h"
78 #include "syswait.h" 67 #include "syswait.h"
79 #include "sysdir.h" 68 #include "sysdir.h"
80 #include "systime.h" 69 #include "systime.h"
81 #if defined(WIN32_NATIVE) || defined(CYGWIN)
82 #include "syssignal.h" 70 #include "syssignal.h"
83 #endif 71 #include "syspwd.h"
84
85 #include "sysproc.h" 72 #include "sysproc.h"
86 73
87 #ifndef WIN32_NATIVE
88 #include <sys/times.h>
89 #endif
90
91 #ifdef WIN32_NATIVE 74 #ifdef WIN32_NATIVE
92 #include <sys/utime.h> 75 #include "syswindows.h"
93 #include "ntheap.h"
94 #include "nt.h"
95 #endif 76 #endif
96 77
97 /* ------------------------------- */ 78 /* ------------------------------- */
98 /* TTY definitions */ 79 /* TTY definitions */
99 /* ------------------------------- */ 80 /* ------------------------------- */
408 while (1) 389 while (1)
409 { 390 {
410 QUIT; 391 QUIT;
411 if (kill (pid, 0) < 0) 392 if (kill (pid, 0) < 0)
412 return; 393 return;
413 emacs_sleep (1); 394 stop_interrupts ();
395 sleep (1);
396 start_interrupts ();
414 } 397 }
415 #endif /* OS features */ 398 #endif /* OS features */
416 } 399 }
417 400
418 401
618 EMACS_SIGNAL (saved_handlers->code, saved_handlers->handler); 601 EMACS_SIGNAL (saved_handlers->code, saved_handlers->handler);
619 saved_handlers++; 602 saved_handlers++;
620 } 603 }
621 } 604 }
622 605
623 #ifdef WIN32_NATIVE
624
625 pid_t
626 sys_getpid (void)
627 {
628 return abs (getpid ());
629 }
630
631 #endif /* WIN32_NATIVE */
632 606
633 /* Fork a subshell. */ 607 /* Fork a subshell. */
634 static void 608 static void
635 sys_subshell (void) 609 sys_subshell (void)
636 { 610 {
637 #ifndef WIN32_NATIVE
638 int pid;
639 #endif
640 struct save_signal saved_handlers[5];
641 Lisp_Object dir; 611 Lisp_Object dir;
642 unsigned char *str = 0; 612 Intbyte *str = 0;
643 int len; 613 Bytecount len;
644 struct gcpro gcpro1; 614 struct gcpro gcpro1;
645 615 Intbyte *sh = 0;
646 saved_handlers[0].code = SIGINT; 616 Extbyte *shext;
647 saved_handlers[1].code = SIGQUIT; 617
648 saved_handlers[2].code = SIGTERM; 618 /* Use our buffer's default directory for the subshell. */
649 #ifdef SIGIO 619
650 saved_handlers[3].code = SIGIO; 620 /* Note: These calls are spread out to insure that the return values
651 saved_handlers[4].code = 0; 621 of the calls (which may be newly-created strings) are properly
652 #else 622 GC-protected. */
653 saved_handlers[3].code = 0; 623
654 #endif
655
656 /* Mentioning current_buffer->buffer would mean including buffer.h,
657 which somehow wedges the hp compiler. So instead... */
658
659 if (NILP (Fboundp (Qdefault_directory)))
660 goto xyzzy;
661 dir = Fsymbol_value (Qdefault_directory);
662 if (!STRINGP (dir))
663 goto xyzzy;
664
665 GCPRO1 (dir); 624 GCPRO1 (dir);
625
626 dir = current_buffer->directory;
627 /* If the current dir has no terminating slash, we'll get undesirable
628 results, so put the slash back. */
629 dir = Ffile_name_as_directory (dir);
666 dir = Funhandled_file_name_directory (dir); 630 dir = Funhandled_file_name_directory (dir);
667 dir = expand_and_dir_to_file (dir, Qnil); 631 dir = expand_and_dir_to_file (dir, Qnil);
668 UNGCPRO; 632
669 str = (unsigned char *) alloca (XSTRING_LENGTH (dir) + 2); 633 str = (Intbyte *) alloca (XSTRING_LENGTH (dir) + 2);
670 len = XSTRING_LENGTH (dir); 634 len = XSTRING_LENGTH (dir);
671 memcpy (str, XSTRING_DATA (dir), len); 635 memcpy (str, XSTRING_DATA (dir), len);
672 if (!IS_ANY_SEP (str[len - 1])) 636 if (!IS_ANY_SEP (str[len - 1]))
673 str[len++] = DIRECTORY_SEP; 637 str[len++] = DIRECTORY_SEP;
674 str[len] = 0; 638 str[len] = 0;
675 xyzzy: 639
676 640 if (sh == 0)
677 #ifndef WIN32_NATIVE 641 sh = egetenv ("SHELL");
678 pid = fork (); 642 if (sh == 0)
679 643 sh = "sh";
680 if (pid == -1) 644
645 C_STRING_TO_EXTERNAL (sh, shext, Qfile_name);
646
647 UNGCPRO;
648
649 #ifdef WIN32_NATIVE
650
651 if (str)
652 qxe_chdir (str);
653
654 /* Waits for process completion */
655 if (_spawnlp (_P_WAIT, shext, shext, NULL) != 0)
681 report_process_error ("Can't spawn subshell", Qunbound); 656 report_process_error ("Can't spawn subshell", Qunbound);
682 if (pid == 0) 657 else
658 return; /* we're done, no need to wait for termination */
659
660 #else /* not WIN32_NATIVE */
661
662 {
663 int pid;
664 struct save_signal saved_handlers[5];
665
666 saved_handlers[0].code = SIGINT;
667 saved_handlers[1].code = SIGQUIT;
668 saved_handlers[2].code = SIGTERM;
669 #ifdef SIGIO
670 saved_handlers[3].code = SIGIO;
671 saved_handlers[4].code = 0;
672 #else
673 saved_handlers[3].code = 0;
674 #endif
675
676 pid = fork ();
677
678 if (pid == -1)
679 report_process_error ("Can't spawn subshell", Qunbound);
680 if (pid == 0)
681 {
682 if (str)
683 qxe_chdir (str);
684
685 #if !defined (NO_SUBPROCESSES)
686 close_process_descs (); /* Close Emacs's pipes/ptys */
687 #endif
688
689 #ifdef SET_EMACS_PRIORITY
690 if (emacs_priority != 0)
691 nice (-emacs_priority); /* Give the new shell the default priority */
692 #endif
693
694 execlp (shext, shext, 0);
695 retry_write (1, "Can't execute subshell", 22);
696 _exit (1);
697 }
698
699 save_signal_handlers (saved_handlers);
700 synch_process_alive = 1;
701 wait_for_termination (pid);
702 restore_signal_handlers (saved_handlers);
703 }
704
683 #endif /* not WIN32_NATIVE */ 705 #endif /* not WIN32_NATIVE */
684 {
685 char *sh = 0;
686
687 if (sh == 0)
688 sh = (char *) egetenv ("SHELL");
689 if (sh == 0)
690 sh = "sh";
691
692 /* Use our buffer's default directory for the subshell. */
693 if (str)
694 sys_chdir (str);
695
696 #ifdef WIN32_NATIVE
697
698 /* Waits for process completion */
699 if (_spawnlp (_P_WAIT, sh, sh, NULL) != 0)
700 report_process_error ("Can't spawn subshell", Qunbound);
701 else
702 return; /* we're done, no need to wait for termination */
703 }
704
705 #else
706
707 #if !defined (NO_SUBPROCESSES)
708 close_process_descs (); /* Close Emacs's pipes/ptys */
709 #endif
710
711 #ifdef SET_EMACS_PRIORITY
712 if (emacs_priority != 0)
713 nice (-emacs_priority); /* Give the new shell the default priority */
714 #endif
715
716 execlp (sh, sh, 0);
717 write (1, "Can't execute subshell", 22);
718 _exit (1);
719 }
720
721 save_signal_handlers (saved_handlers);
722 synch_process_alive = 1;
723 wait_for_termination (pid);
724 restore_signal_handlers (saved_handlers);
725
726 #endif /* not WIN32_NATIVE */
727
728 } 706 }
729 707
730 #endif /* !defined (SIGTSTP) && !defined (USG_JOBCTRL) */ 708 #endif /* !defined (SIGTSTP) && !defined (USG_JOBCTRL) */
731 709
732 710
1258 int fd = open ("/dev/tty", O_RDWR, 0); 1236 int fd = open ("/dev/tty", O_RDWR, 0);
1259 pid_t me = getpid (); 1237 pid_t me = getpid ();
1260 EMACS_BLOCK_SIGNAL (SIGTTOU); 1238 EMACS_BLOCK_SIGNAL (SIGTTOU);
1261 EMACS_SET_TTY_PROCESS_GROUP (fd, &me); 1239 EMACS_SET_TTY_PROCESS_GROUP (fd, &me);
1262 EMACS_UNBLOCK_SIGNAL (SIGTTOU); 1240 EMACS_UNBLOCK_SIGNAL (SIGTTOU);
1263 close (fd); 1241 retry_close (fd);
1264 } 1242 }
1265 #endif 1243 #endif
1266 } 1244 }
1267 1245
1268 /* Split off the foreground process group to Emacs alone. 1246 /* Split off the foreground process group to Emacs alone.
1289 { 1267 {
1290 int fd = open ("/dev/tty", O_RDWR, 0); 1268 int fd = open ("/dev/tty", O_RDWR, 0);
1291 EMACS_BLOCK_SIGNAL (SIGTTOU); 1269 EMACS_BLOCK_SIGNAL (SIGTTOU);
1292 EMACS_SET_TTY_PROCESS_GROUP (fd, &inherited_tty_pgroup); 1270 EMACS_SET_TTY_PROCESS_GROUP (fd, &inherited_tty_pgroup);
1293 EMACS_UNBLOCK_SIGNAL (SIGTTOU); 1271 EMACS_UNBLOCK_SIGNAL (SIGTTOU);
1294 close (fd); 1272 retry_close (fd);
1295 } 1273 }
1296 #endif 1274 #endif
1297 } 1275 }
1298 1276
1299 /* Set the tty to our original foreground group. 1277 /* Set the tty to our original foreground group.
1337 if (! noninteractive) 1315 if (! noninteractive)
1338 { 1316 {
1339 int fd = open ("/dev/tty", O_RDWR, 0); 1317 int fd = open ("/dev/tty", O_RDWR, 0);
1340 inherited_pgroup = EMACS_GET_PROCESS_GROUP (); 1318 inherited_pgroup = EMACS_GET_PROCESS_GROUP ();
1341 EMACS_GET_TTY_PROCESS_GROUP (fd, &inherited_tty_pgroup); 1319 EMACS_GET_TTY_PROCESS_GROUP (fd, &inherited_tty_pgroup);
1342 close (fd); 1320 retry_close (fd);
1343 EMACS_SEPARATE_PROCESS_GROUP (); 1321 EMACS_SEPARATE_PROCESS_GROUP ();
1344 } 1322 }
1345 #endif 1323 #endif
1346 } 1324 }
1347 1325
1365 another terminal). 1343 another terminal).
1366 */ 1344 */
1367 { 1345 {
1368 int j = open ("/dev/tty", O_RDWR, 0); 1346 int j = open ("/dev/tty", O_RDWR, 0);
1369 ioctl (j, TIOCNOTTY, 0); 1347 ioctl (j, TIOCNOTTY, 0);
1370 close (j); 1348 retry_close (j);
1371 } 1349 }
1372 # endif /* TIOCNOTTY */ 1350 # endif /* TIOCNOTTY */
1373 /* 1351 /*
1374 On systems without TIOCNOTTY and without 1352 On systems without TIOCNOTTY and without
1375 setsid(), we don't need to do anything more to 1353 setsid(), we don't need to do anything more to
1755 We need it to be only LF. This is the way that is 1733 We need it to be only LF. This is the way that is
1756 done. */ 1734 done. */
1757 struct termio tty; 1735 struct termio tty;
1758 1736
1759 if (ioctl (output_fd, HFTGETID, &tty) != -1) 1737 if (ioctl (output_fd, HFTGETID, &tty) != -1)
1760 write (output_fd, "\033[20l", 5); 1738 retry_write (output_fd, "\033[20l", 5);
1761 } 1739 }
1762 #endif 1740 #endif
1763 #endif 1741 #endif
1764 1742
1765 #if 0 /* We do our own buffering with lstreams. */ 1743 #if 0 /* We do our own buffering with lstreams. */
1944 /* HFT consoles normally use ^J as a LF/CR. We forced it to 1922 /* HFT consoles normally use ^J as a LF/CR. We forced it to
1945 do the LF only. Now, we need to reset it. */ 1923 do the LF only. Now, we need to reset it. */
1946 struct termio tty; 1924 struct termio tty;
1947 1925
1948 if (ioctl (output_fd, HFTGETID, &tty) != -1) 1926 if (ioctl (output_fd, HFTGETID, &tty) != -1)
1949 write (output_fd, "\033[20h", 5); 1927 retry_write (output_fd, "\033[20h", 5);
1950 } 1928 }
1951 #endif 1929 #endif
1952 1930
1953 tty_redisplay_shutdown (con); 1931 tty_redisplay_shutdown (con);
1954 /* reset_tty_modes() flushes the connection at its end. */ 1932 /* reset_tty_modes() flushes the connection at its end. */
2243 #endif /* ORDINARY_LINK */ 2221 #endif /* ORDINARY_LINK */
2244 #endif /* DATA_START */ 2222 #endif /* DATA_START */
2245 } 2223 }
2246 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */ 2224 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2247 2225
2248 #if !defined(CANNOT_DUMP) && !defined(PDUMP)
2249 /* Some systems that cannot dump also cannot implement these. */
2250
2251 /*
2252 * Return the address of the end of the text segment prior to
2253 * doing an unexec. After unexec the return value is undefined.
2254 */
2255
2256 char *
2257 end_of_text (void)
2258 {
2259 #ifdef TEXT_END
2260 return ((char *) TEXT_END);
2261 #else
2262 extern int etext;
2263 return ((char *) &etext);
2264 #endif
2265 }
2266
2267 /*
2268 * Return the address of the end of the data segment prior to
2269 * doing an unexec. After unexec the return value is undefined.
2270 */
2271
2272 char *
2273 end_of_data (void)
2274 {
2275 #ifdef DATA_END
2276 return ((char *) DATA_END);
2277 #else
2278 extern int edata;
2279 return ((char *) &edata);
2280 #endif
2281 }
2282
2283 #endif /* !defined(CANNOT_DUMP) && !defined(PDUMP) */
2284
2285 2226
2286 /************************************************************************/ 2227 /************************************************************************/
2287 /* get the system name */ 2228 /* get the system name */
2288 /************************************************************************/ 2229 /************************************************************************/
2289 2230
2294 2235
2295 void 2236 void
2296 init_system_name (void) 2237 init_system_name (void)
2297 { 2238 {
2298 #if defined (WIN32_NATIVE) 2239 #if defined (WIN32_NATIVE)
2299 char hostname [MAX_COMPUTERNAME_LENGTH + 1]; 2240 Extbyte hostname[MAX_XETCHAR_SIZE * (MAX_COMPUTERNAME_LENGTH + 1)];
2300 DWORD size = sizeof (hostname); 2241 DWORD size = sizeof (hostname) / XETCHAR_SIZE;
2301 GetComputerName (hostname, &size); 2242 qxeGetComputerName (hostname, &size);
2302 Vsystem_name = build_string (hostname); 2243 Vsystem_name = build_tstr_string (hostname);
2303 #elif !defined (HAVE_GETHOSTNAME) 2244 #elif !defined (HAVE_GETHOSTNAME)
2304 struct utsname uts; 2245 struct utsname uts;
2305 uname (&uts); 2246 uname (&uts);
2306 Vsystem_name = build_string (uts.nodename); 2247 Vsystem_name = build_string (uts.nodename);
2307 #else /* HAVE_GETHOSTNAME */ 2248 #else /* HAVE_GETHOSTNAME */
2535 return ((const char *) GETTEXT ("Unknown error")); 2476 return ((const char *) GETTEXT ("Unknown error"));
2536 } 2477 }
2537 2478
2538 #endif /* ! HAVE_STRERROR */ 2479 #endif /* ! HAVE_STRERROR */
2539 2480
2540 #ifdef WIN32_NATIVE
2541
2542 struct errentry {
2543 unsigned long oscode; /* Win32 error */
2544 int errnocode; /* unix errno */
2545 };
2546
2547 static struct errentry errtable[] = {
2548 { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */
2549 { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */
2550 { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */
2551 { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */
2552 { ERROR_ACCESS_DENIED, EACCES }, /* 5 */
2553 { ERROR_INVALID_HANDLE, EBADF }, /* 6 */
2554 { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */
2555 { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */
2556 { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */
2557 { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */
2558 { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */
2559 { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */
2560 { ERROR_INVALID_DATA, EINVAL }, /* 13 */
2561 { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */
2562 { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */
2563 { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */
2564 { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */
2565 { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */
2566 { ERROR_BAD_NETPATH, ENOENT }, /* 53 */
2567 { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */
2568 { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */
2569 { ERROR_FILE_EXISTS, EEXIST }, /* 80 */
2570 { ERROR_CANNOT_MAKE, EACCES }, /* 82 */
2571 { ERROR_FAIL_I24, EACCES }, /* 83 */
2572 { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */
2573 { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */
2574 { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */
2575 { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */
2576 { ERROR_DISK_FULL, ENOSPC }, /* 112 */
2577 { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */
2578 { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */
2579 { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */
2580 { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */
2581 { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */
2582 { ERROR_NEGATIVE_SEEK, EINVAL }, /* 131 */
2583 { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */
2584 { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, /* 145 */
2585 { ERROR_NOT_LOCKED, EACCES }, /* 158 */
2586 { ERROR_BAD_PATHNAME, ENOENT }, /* 161 */
2587 { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */
2588 { ERROR_LOCK_FAILED, EACCES }, /* 167 */
2589 { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */
2590 { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */
2591 { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */
2592 { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */
2593 };
2594
2595 /* The following two constants must be the minimum and maximum
2596 values in the (contiguous) range of Exec Failure errors. */
2597 #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
2598 #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
2599
2600 /* These are the low and high value in the range of errors that are
2601 access violations */
2602 #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
2603 #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
2604
2605 void
2606 mswindows_set_errno (unsigned long win32_error)
2607 {
2608 int i;
2609
2610 /* check the table for the OS error code */
2611 for (i = 0; i < countof (errtable); ++i)
2612 {
2613 if (win32_error == errtable[i].oscode)
2614 {
2615 errno = errtable[i].errnocode;
2616 return;
2617 }
2618 }
2619
2620 /* The error code wasn't in the table. We check for a range of
2621 * EACCES errors or exec failure errors (ENOEXEC). Otherwise EINVAL is
2622 * returned. */
2623 if (win32_error >= MIN_EACCES_RANGE && win32_error <= MAX_EACCES_RANGE)
2624 errno = EACCES;
2625 else if (win32_error >= MIN_EXEC_ERROR && win32_error <= MAX_EXEC_ERROR)
2626 errno = ENOEXEC;
2627 else
2628 errno = EINVAL;
2629 }
2630
2631 void
2632 mswindows_set_last_errno (void)
2633 {
2634 mswindows_set_errno (GetLastError ());
2635 }
2636
2637 #endif /* WIN32_NATIVE */
2638
2639 2481
2640 /************************************************************************/ 2482 /************************************************************************/
2641 /* Encapsulations of system calls */ 2483 /* Encapsulations of system calls */
2642 /************************************************************************/ 2484 /************************************************************************/
2643 2485
2644 #define PATHNAME_CONVERT_OUT(path) \ 2486 #ifdef WIN32_NATIVE
2645 TO_EXTERNAL_FORMAT (C_STRING, (path), C_STRING_ALLOCA, (path), Qfile_name); 2487 #define PATHNAME_CONVERT_OUT(path, pathout) C_STRING_TO_TSTR (path, pathout)
2488 #else
2489 #define PATHNAME_CONVERT_OUT(path, pathout) \
2490 C_STRING_TO_EXTERNAL (path, pathout, Qfile_name)
2491 #endif
2646 2492
2647 /***************** low-level calls ****************/ 2493 /***************** low-level calls ****************/
2648 2494
2649 /* 2495 /*
2650 * On USG systems the system calls are INTERRUPTIBLE by signals 2496 * On USG systems the system calls are INTERRUPTIBLE by signals
2662 /* Ben sez: read Dick Gabriel's essay about the Worse Is Better 2508 /* Ben sez: read Dick Gabriel's essay about the Worse Is Better
2663 approach to programming and its connection to the silly 2509 approach to programming and its connection to the silly
2664 interruptible-system-call business. To find it, look on 2510 interruptible-system-call business. To find it, look on
2665 Jamie's home page (http://www.jwz.org/worse-is-better.html). */ 2511 Jamie's home page (http://www.jwz.org/worse-is-better.html). */
2666 2512
2667 #ifdef ENCAPSULATE_OPEN 2513 #ifdef WIN32_NATIVE
2514
2515 static int
2516 underlying_open_1 (const Extbyte *path, int oflag, int mode)
2517 {
2518 if (XEUNICODE_P)
2519 return _wopen ((const wchar_t *) path, oflag, mode);
2520 else
2521 return _open (path, oflag, mode);
2522 }
2523
2524 #endif /* WIN32_NATIVE */
2525
2526 /* Just one call with normal open() semantics. */
2527
2528 static int
2529 underlying_open (const Extbyte *path, int oflag, int mode)
2530 {
2531 #ifdef WIN32_NATIVE
2532 {
2533 /* Try to open file without _O_CREAT, to be able to write to hidden
2534 and system files. Force all file handles to be
2535 non-inheritable. */
2536 int res = underlying_open_1 (path, (oflag & ~_O_CREAT) | _O_NOINHERIT,
2537 mode);
2538 if (res >= 0)
2539 return res;
2540 return underlying_open_1 (path, oflag | _O_NOINHERIT, mode);
2541 }
2542 #else
2543 return open (path, oflag, mode);
2544 #endif /* WIN32_NATIVE */
2545 }
2546
2547 /* Like qxe_open() below but operates on externally-encoded filenames. */
2548
2668 int 2549 int
2669 sys_open (const char *path, int oflag, ...) 2550 retry_open (const Extbyte *path, int oflag, ...)
2670 { 2551 {
2671 int mode; 2552 int mode;
2672 va_list ap; 2553 va_list ap;
2673 2554
2674 va_start (ap, oflag); 2555 va_start (ap, oflag);
2675 mode = va_arg (ap, int); 2556 mode = va_arg (ap, int);
2676 va_end (ap); 2557 va_end (ap);
2677 2558
2678 PATHNAME_CONVERT_OUT (path);
2679
2680 #ifdef WIN32_NATIVE
2681 /* Make all handles non-inheritable */
2682 oflag |= _O_NOINHERIT;
2683 #endif
2684
2685 #ifdef INTERRUPTIBLE_OPEN 2559 #ifdef INTERRUPTIBLE_OPEN
2686 { 2560 {
2687 int rtnval; 2561 int rtnval;
2688 while ((rtnval = open (path, oflag, mode)) == -1 2562 while ((rtnval = underlying_open (path, oflag, mode)) == -1
2689 && (errno == EINTR)) 2563 && (errno == EINTR))
2690 DO_NOTHING; 2564 DO_NOTHING;
2691 return rtnval; 2565 return rtnval;
2692 } 2566 }
2693 #else 2567 #else
2694 return open (path, oflag, mode); 2568 return underlying_open (path, oflag, mode);
2695 #endif 2569 #endif
2696 } 2570 }
2697 #endif /* ENCAPSULATE_OPEN */ 2571
2698 2572 /* The basic external entry point to open(). Handles conversion to
2699 /* Like sys_open, only when open() is interrupted by EINTR, check for 2573 external encoding, interruptions, etc. */
2574
2575 int
2576 qxe_open (const Intbyte *path, int oflag, ...)
2577 {
2578 Extbyte *pathout;
2579 int mode;
2580 va_list ap;
2581
2582 va_start (ap, oflag);
2583 mode = va_arg (ap, int);
2584 va_end (ap);
2585
2586 PATHNAME_CONVERT_OUT (path, pathout);
2587 return retry_open (pathout, oflag, mode);
2588 }
2589
2590 /* Like qxe_open, only when open() is interrupted by EINTR, check for
2700 QUIT. This allows the callers of this function to be interrupted 2591 QUIT. This allows the callers of this function to be interrupted
2701 with C-g when, say, reading from named pipes. However, this should 2592 with C-g when, say, reading from named pipes. However, this should
2702 be used with caution, as it can GC. 2593 be used with caution, as it can GC.
2703 2594
2704 This function will not function as expected on systems where open() 2595 This function will not function as expected on systems where open()
2705 is not interrupted by C-g. However, the worst that can happen is 2596 is not interrupted by C-g. However, the worst that can happen is
2706 the fallback to simple open(). */ 2597 the fallback to simple open(). */
2707 int 2598 int
2708 interruptible_open (const char *path, int oflag, int mode) 2599 qxe_interruptible_open (const Intbyte *path, int oflag, int mode)
2709 { 2600 {
2710 /* This function can GC */ 2601 /* This function can GC */
2711 size_t len = strlen (path); 2602 Extbyte *pathout;
2712 char *nonreloc = (char *) alloca (len + 1); 2603
2713 2604 PATHNAME_CONVERT_OUT (path, pathout);
2714 /* Must copy PATH, because it might be the data of a Lisp_String,
2715 which could be relocated by GC when checking for QUIT. */
2716 memcpy (nonreloc, path, len + 1);
2717
2718 PATHNAME_CONVERT_OUT (nonreloc);
2719 2605
2720 #ifdef WIN32_NATIVE 2606 #ifdef WIN32_NATIVE
2721 /* Make all handles non-inheritable */ 2607 /* Make all handles non-inheritable */
2722 oflag |= _O_NOINHERIT; 2608 oflag |= _O_NOINHERIT;
2723 #endif 2609 #endif
2724 2610
2725 for (;;) 2611 for (;;)
2726 { 2612 {
2727 int rtnval = open (nonreloc, oflag, mode); 2613 int rtnval = underlying_open (pathout, oflag, mode);
2728 if (!(rtnval == -1 && errno == EINTR)) 2614 if (!(rtnval == -1 && errno == EINTR))
2729 return rtnval; 2615 return rtnval;
2730 /* open() was interrupted. Was QUIT responsible? */ 2616 /* open() was interrupted. Was QUIT responsible? */
2731 QUIT; 2617 QUIT;
2732 } 2618 }
2733 } 2619 }
2734 2620
2735 #ifdef ENCAPSULATE_CLOSE
2736 int 2621 int
2737 sys_close (int filedes) 2622 retry_close (int filedes)
2738 { 2623 {
2739 #ifdef INTERRUPTIBLE_CLOSE 2624 #ifdef INTERRUPTIBLE_CLOSE
2740 int did_retry = 0; 2625 int did_retry = 0;
2741 REGISTER int rtnval; 2626 REGISTER int rtnval;
2742 2627
2753 return rtnval; 2638 return rtnval;
2754 #else 2639 #else
2755 return close (filedes); 2640 return close (filedes);
2756 #endif 2641 #endif
2757 } 2642 }
2758 #endif /* ENCAPSULATE_CLOSE */ 2643
2759 2644 static ssize_t
2760 ssize_t 2645 retry_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
2761 sys_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
2762 { 2646 {
2763 ssize_t rtnval; 2647 ssize_t rtnval;
2764 2648
2765 /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */ 2649 /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
2766 while ((rtnval = read (fildes, buf, nbyte)) == -1 2650 while ((rtnval = read (fildes, buf, nbyte)) == -1
2770 REALLY_QUIT; 2654 REALLY_QUIT;
2771 } 2655 }
2772 return rtnval; 2656 return rtnval;
2773 } 2657 }
2774 2658
2775 #ifdef ENCAPSULATE_READ
2776 ssize_t 2659 ssize_t
2777 sys_read (int fildes, void *buf, size_t nbyte) 2660 retry_read (int fildes, void *buf, size_t nbyte)
2778 { 2661 {
2779 return sys_read_1 (fildes, buf, nbyte, 0); 2662 return retry_read_1 (fildes, buf, nbyte, 0);
2780 } 2663 }
2781 #endif /* ENCAPSULATE_READ */ 2664
2782 2665 static ssize_t
2783 ssize_t 2666 retry_write_1 (int fildes, const void *buf, size_t nbyte, int allow_quit)
2784 sys_write_1 (int fildes, const void *buf, size_t nbyte, int allow_quit)
2785 { 2667 {
2786 ssize_t bytes_written = 0; 2668 ssize_t bytes_written = 0;
2787 const char *b = (const char *) buf; 2669 const char *b = (const char *) buf;
2788 2670
2789 /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */ 2671 /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
2806 bytes_written += rtnval; 2688 bytes_written += rtnval;
2807 } 2689 }
2808 return bytes_written; 2690 return bytes_written;
2809 } 2691 }
2810 2692
2811 #ifdef ENCAPSULATE_WRITE
2812 ssize_t 2693 ssize_t
2813 sys_write (int fildes, const void *buf, size_t nbyte) 2694 retry_write (int fildes, const void *buf, size_t nbyte)
2814 { 2695 {
2815 return sys_write_1 (fildes, buf, nbyte, 0); 2696 return retry_write_1 (fildes, buf, nbyte, 0);
2816 } 2697 }
2817 #endif /* ENCAPSULATE_WRITE */ 2698
2699 /* Versions of read() and write() that allow quitting out of the actual
2700 I/O. We don't use immediate_quit (i.e. direct longjmp() out of the
2701 signal handler) because that's way too losing.
2702
2703 (#### Actually, longjmp()ing out of the signal handler may not be
2704 as losing as I thought. See qxe_reliable_signal() in sysdep.c.) */
2705
2706 Bytecount
2707 read_allowing_quit (int fildes, void *buf, Bytecount size)
2708 {
2709 QUIT;
2710 return retry_read_1 (fildes, buf, size, 1);
2711 }
2712
2713 Bytecount
2714 write_allowing_quit (int fildes, const void *buf, Bytecount size)
2715 {
2716 QUIT;
2717 return retry_write_1 (fildes, buf, size, 1);
2718 }
2818 2719
2819 2720
2820 /**************** stdio calls ****************/ 2721 /**************** stdio calls ****************/
2821 2722
2822 /* There is at least some evidence that the stdio calls are interruptible 2723 /* There is at least some evidence that the stdio calls are interruptible
2824 case, it doesn't hurt to encapsulate them. */ 2725 case, it doesn't hurt to encapsulate them. */
2825 2726
2826 /* #### Should also encapsulate fflush(). 2727 /* #### Should also encapsulate fflush().
2827 #### Should conceivably encapsulate getchar() etc. What a pain! */ 2728 #### Should conceivably encapsulate getchar() etc. What a pain! */
2828 2729
2829 #ifdef ENCAPSULATE_FOPEN
2830 FILE * 2730 FILE *
2831 sys_fopen (const char *path, const char *type) 2731 retry_fopen (const Extbyte *path, const Char_ASCII *mode)
2832 { 2732 {
2833 PATHNAME_CONVERT_OUT (path); 2733 #ifdef WIN32_NATIVE
2834 #if defined (WIN32_NATIVE) 2734 int fd;
2835 { 2735 int oflag;
2836 int fd; 2736 const Char_ASCII *mode_save = mode;
2837 int oflag; 2737
2838 const char * type_save = type; 2738 /* Force all file handles to be non-inheritable. This is necessary to
2839 2739 ensure child processes don't unwittingly inherit handles that might
2840 /* Force all file handles to be non-inheritable. This is necessary to 2740 prevent future file access. */
2841 ensure child processes don't unwittingly inherit handles that might 2741
2842 prevent future file access. */ 2742 if (mode[0] == 'r')
2843 2743 oflag = O_RDONLY;
2844 if (type[0] == 'r') 2744 else if (mode[0] == 'w' || mode[0] == 'a')
2845 oflag = O_RDONLY; 2745 oflag = O_WRONLY | O_CREAT | O_TRUNC;
2846 else if (type[0] == 'w' || type[0] == 'a') 2746 else
2847 oflag = O_WRONLY | O_CREAT | O_TRUNC; 2747 return NULL;
2848 else 2748
2849 return 0; 2749 /* Only do simplistic option parsing. */
2850 2750 while (*++mode)
2851 /* Only do simplistic option parsing. */ 2751 if (mode[0] == '+')
2852 while (*++type) 2752 {
2853 if (type[0] == '+') 2753 oflag &= ~(O_RDONLY | O_WRONLY);
2854 { 2754 oflag |= O_RDWR;
2855 oflag &= ~(O_RDONLY | O_WRONLY); 2755 }
2856 oflag |= O_RDWR; 2756 else if (mode[0] == 'b')
2857 } 2757 {
2858 else if (type[0] == 'b') 2758 oflag &= ~O_TEXT;
2859 { 2759 oflag |= O_BINARY;
2860 oflag &= ~O_TEXT; 2760 }
2861 oflag |= O_BINARY; 2761 else if (mode[0] == 't')
2862 } 2762 {
2863 else if (type[0] == 't') 2763 oflag &= ~O_BINARY;
2864 { 2764 oflag |= O_TEXT;
2865 oflag &= ~O_BINARY; 2765 }
2866 oflag |= O_TEXT; 2766 else break;
2867 } 2767
2868 else break; 2768 fd = underlying_open (path, oflag, 0644);
2869 2769 if (fd < 0)
2870 fd = open (path, oflag | _O_NOINHERIT, 0644); 2770 return NULL;
2871 if (fd < 0) 2771
2872 return NULL; 2772 return _fdopen (fd, mode_save);
2873
2874 return _fdopen (fd, type_save);
2875 }
2876 #elif defined (INTERRUPTIBLE_OPEN) 2773 #elif defined (INTERRUPTIBLE_OPEN)
2877 { 2774 {
2878 FILE *rtnval; 2775 FILE *rtnval;
2879 while (!(rtnval = fopen (path, type)) && (errno == EINTR)) 2776 while (!(rtnval = fopen (path, mode)) && (errno == EINTR))
2880 DO_NOTHING; 2777 DO_NOTHING;
2881 return rtnval; 2778 return rtnval;
2882 } 2779 }
2883 #else 2780 #else
2884 return fopen (path, type); 2781 return fopen (path, mode);
2885 #endif 2782 #endif /* defined (INTERRUPTIBLE_OPEN) */
2886 } 2783 }
2887 #endif /* ENCAPSULATE_FOPEN */ 2784
2888 2785 FILE *
2889 2786 qxe_fopen (const Intbyte *path, const Char_ASCII *mode)
2890 #ifdef ENCAPSULATE_FCLOSE 2787 {
2788 Extbyte *pathout;
2789 PATHNAME_CONVERT_OUT (path, pathout);
2790 return retry_fopen (pathout, mode);
2791 }
2792
2891 int 2793 int
2892 sys_fclose (FILE *stream) 2794 retry_fclose (FILE *stream)
2893 { 2795 {
2894 #ifdef INTERRUPTIBLE_CLOSE 2796 #ifdef INTERRUPTIBLE_CLOSE
2895 int rtnval; 2797 int rtnval;
2896 2798
2897 while ((rtnval = fclose (stream)) == EOF 2799 while ((rtnval = fclose (stream)) == EOF
2900 return rtnval; 2802 return rtnval;
2901 #else 2803 #else
2902 return fclose (stream); 2804 return fclose (stream);
2903 #endif 2805 #endif
2904 } 2806 }
2905 #endif /* ENCAPSULATE_FCLOSE */ 2807
2906
2907
2908 #ifdef ENCAPSULATE_FREAD
2909 size_t 2808 size_t
2910 sys_fread (void *ptr, size_t size, size_t nitem, FILE *stream) 2809 retry_fread (void *ptr, size_t size, size_t nitem, FILE *stream)
2911 { 2810 {
2912 #ifdef INTERRUPTIBLE_IO 2811 #ifdef INTERRUPTIBLE_IO
2913 size_t rtnval; 2812 size_t rtnval;
2914 size_t items_read = 0; 2813 size_t items_read = 0;
2915 char *b = (char *) ptr; 2814 char *b = (char *) ptr;
2931 return (items_read); 2830 return (items_read);
2932 #else 2831 #else
2933 return fread (ptr, size, nitem, stream); 2832 return fread (ptr, size, nitem, stream);
2934 #endif 2833 #endif
2935 } 2834 }
2936 #endif /* ENCAPSULATE_FREAD */ 2835
2937
2938
2939 #ifdef ENCAPSULATE_FWRITE
2940 size_t 2836 size_t
2941 sys_fwrite (const void *ptr, size_t size, size_t nitem, FILE *stream) 2837 retry_fwrite (const void *ptr, size_t size, size_t nitem, FILE *stream)
2942 { 2838 {
2943 #ifdef INTERRUPTIBLE_IO 2839 #ifdef INTERRUPTIBLE_IO
2944 size_t rtnval; 2840 size_t rtnval;
2945 size_t items_written = 0; 2841 size_t items_written = 0;
2946 const char *b = (const char *) ptr; 2842 const char *b = (const char *) ptr;
2962 return (items_written); 2858 return (items_written);
2963 #else 2859 #else
2964 return fwrite (ptr, size, nitem, stream); 2860 return fwrite (ptr, size, nitem, stream);
2965 #endif 2861 #endif
2966 } 2862 }
2967 #endif /* ENCAPSULATE_FWRITE */
2968
2969 2863
2970 /********************* directory calls *******************/ 2864 /********************* directory calls *******************/
2971 2865
2972 #ifdef ENCAPSULATE_CHDIR
2973 int 2866 int
2974 sys_chdir (const char *path) 2867 qxe_chdir (const Intbyte *path)
2975 { 2868 {
2976 PATHNAME_CONVERT_OUT (path); 2869 Extbyte *pathout;
2977 return chdir (path); 2870 PATHNAME_CONVERT_OUT (path, pathout);
2978 } 2871 #ifdef WIN32_NATIVE
2979 #endif /* ENCAPSULATE_CHDIR */ 2872 if (XEUNICODE_P)
2980 2873 return _wchdir ((const wchar_t *) pathout);
2981 2874 else
2982 #ifdef ENCAPSULATE_MKDIR 2875 return _chdir (pathout);
2876 #else
2877 return chdir (pathout);
2878 #endif
2879 }
2880
2983 int 2881 int
2984 sys_mkdir (const char *path, mode_t mode) 2882 qxe_mkdir (const Intbyte *path, mode_t mode)
2985 { 2883 {
2986 PATHNAME_CONVERT_OUT (path); 2884 Extbyte *pathout;
2885 PATHNAME_CONVERT_OUT (path, pathout);
2987 #ifdef WIN32_NATIVE 2886 #ifdef WIN32_NATIVE
2988 return mkdir (path); 2887 if (XEUNICODE_P)
2989 #else 2888 return _wmkdir ((const wchar_t *) pathout);
2990 return mkdir (path, mode); 2889 else
2991 #endif 2890 return _mkdir (pathout);
2992 } 2891 #else
2993 #endif /* ENCAPSULATE_MKDIR */ 2892 return mkdir (pathout, mode);
2994 2893 #endif
2995 2894 }
2996 #ifdef ENCAPSULATE_OPENDIR 2895
2997 DIR * 2896 DIR *
2998 sys_opendir (const char *filename) 2897 qxe_opendir (const Intbyte *filename)
2999 { 2898 {
2899 #ifdef WIN32_NATIVE
2900 return mswindows_opendir (filename);
2901 #else
3000 DIR *rtnval; 2902 DIR *rtnval;
3001 PATHNAME_CONVERT_OUT (filename); 2903 Extbyte *pathout;
3002 2904 PATHNAME_CONVERT_OUT (filename, pathout);
3003 while (!(rtnval = opendir (filename)) 2905
2906 while (!(rtnval = opendir (pathout))
3004 && (errno == EINTR)) 2907 && (errno == EINTR))
3005 ; 2908 ;
3006 return rtnval; 2909 return rtnval;
3007 } 2910 #endif /* WIN32_NATIVE */
3008 #endif /* ENCAPSULATE_OPENDIR */ 2911 }
3009 2912
3010
3011 #ifdef ENCAPSULATE_READDIR
3012 DIRENTRY * 2913 DIRENTRY *
3013 sys_readdir (DIR *dirp) 2914 qxe_readdir (DIR *dirp)
3014 { 2915 {
2916 #ifdef WIN32_NATIVE
2917 return mswindows_readdir (dirp);
2918 #else /* not WIN32_NATIVE */
3015 DIRENTRY *rtnval; 2919 DIRENTRY *rtnval;
3016 2920
3017 /* Apparently setting errno is necessary on some systems? 2921 /* Apparently setting errno is necessary on some systems?
3018 Maybe readdir() doesn't always set errno ?! */ 2922 Maybe readdir() doesn't always set errno ?! */
3019 while (!(errno = 0, rtnval = readdir (dirp)) 2923 while (!(errno = 0, rtnval = readdir (dirp))
3054 Dynarr_add (internal_DIRENTRY, '\0'); /* NUL-terminate */ 2958 Dynarr_add (internal_DIRENTRY, '\0'); /* NUL-terminate */
3055 return (DIRENTRY *) Dynarr_atp (internal_DIRENTRY, 0); 2959 return (DIRENTRY *) Dynarr_atp (internal_DIRENTRY, 0);
3056 } 2960 }
3057 } 2961 }
3058 #endif /* MULE */ 2962 #endif /* MULE */
3059 } 2963 #endif /* WIN32_NATIVE */
3060 #endif /* ENCAPSULATE_READDIR */ 2964 }
3061 2965
3062
3063 #ifdef ENCAPSULATE_CLOSEDIR
3064 int 2966 int
3065 sys_closedir (DIR *dirp) 2967 qxe_closedir (DIR *dirp)
3066 { 2968 {
2969 #ifdef WIN32_NATIVE
2970 return mswindows_closedir (dirp);
2971 #else /* not WIN32_NATIVE */
3067 int rtnval; 2972 int rtnval;
3068 2973
3069 while ((rtnval = closedir (dirp)) == -1 2974 while ((rtnval = closedir (dirp)) == -1
3070 && (errno == EINTR)) 2975 && (errno == EINTR))
3071 ; 2976 ;
3072 return rtnval; 2977 return rtnval;
3073 } 2978 #endif /* WIN32_NATIVE */
3074 #endif /* ENCAPSULATE_CLOSEDIR */ 2979 }
3075 2980
3076
3077 #ifdef ENCAPSULATE_RMDIR
3078 int 2981 int
3079 sys_rmdir (const char *path) 2982 qxe_rmdir (const Intbyte *path)
3080 { 2983 {
3081 PATHNAME_CONVERT_OUT (path); 2984 Extbyte *pathout;
3082 return rmdir (path); 2985 PATHNAME_CONVERT_OUT (path, pathout);
3083 } 2986 #ifdef WIN32_NATIVE
3084 #endif /* ENCAPSULATE_RMDIR */ 2987 if (XEUNICODE_P)
3085 2988 return _wrmdir ((const wchar_t *) pathout);
2989 else
2990 return _rmdir (pathout);
2991 #else
2992 return rmdir (pathout);
2993 #endif
2994 }
2995
2996 Intbyte *
2997 qxe_allocating_getcwd (void)
2998 {
2999 #ifdef HAVE_GETCWD
3000 Bytecount cwdsize = 1024;
3001 Extbyte *cwd = xnew_array (Extbyte, cwdsize);
3002
3003 /* Many getcwd()'s can take a NULL argument and malloc() the right amount
3004 of data, but this is non-standard. */
3005 while (1)
3006 {
3007 #ifdef WIN32_NATIVE
3008 Extbyte *ret;
3009
3010 if (XEUNICODE_P)
3011 ret = (Extbyte *) _wgetcwd ((wchar_t *) cwd,
3012 cwdsize / sizeof (wchar_t));
3013 else
3014 ret = _getcwd (cwd, cwdsize);
3015
3016 if (ret)
3017 {
3018 Intbyte *retin;
3019 TSTR_TO_C_STRING_MALLOC (ret, retin);
3020 xfree (cwd);
3021 return retin;
3022 }
3023 #else
3024 Extbyte *ret = getcwd (cwd, cwdsize);
3025 if (ret)
3026 {
3027 Intbyte *retin;
3028 EXTERNAL_TO_C_STRING_MALLOC (ret, retin, Qfile_name);
3029 xfree (cwd);
3030 return retin;
3031 }
3032 #endif /* WIN32_NATIVE */
3033
3034 if (errno == ERANGE)
3035 {
3036 cwdsize *= 2;
3037 XREALLOC_ARRAY (cwd, Extbyte, cwdsize);
3038 }
3039 else
3040 {
3041 xfree (cwd);
3042 return NULL;
3043 }
3044 }
3045 #else
3046 Extbyte chingame_limitos_arbitrarios[PATH_MAX];
3047 Intbyte *ret2;
3048
3049 if (!getwd (chingame_limitos_arbitrarios))
3050 return 0;
3051 EXTERNAL_TO_C_STRING_MALLOC (chingame_limitos_arbitrarios, ret2, Qfile_name);
3052 return ret2;
3053 #endif /* HAVE_GETCWD */
3054 }
3086 3055
3087 /***************** file-information calls ******************/ 3056 /***************** file-information calls ******************/
3088 3057
3089 #ifdef ENCAPSULATE_ACCESS
3090 int 3058 int
3091 sys_access (const char *path, int mode) 3059 qxe_access (const Intbyte *path, int mode)
3092 { 3060 {
3093 PATHNAME_CONVERT_OUT (path); 3061 #ifdef WIN32_NATIVE
3094 return access (path, mode); 3062 return mswindows_access (path, mode);
3095 } 3063 #else /* not WIN32_NATIVE */
3096 #endif /* ENCAPSULATE_ACCESS */ 3064 Extbyte *pathout;
3097 3065 PATHNAME_CONVERT_OUT (path, pathout);
3098 3066 return access (pathout, mode);
3099 #ifdef HAVE_EACCESS 3067 #endif /* WIN32_NATIVE */
3100 #ifdef ENCAPSULATE_EACCESS 3068 }
3069
3070 #if defined (HAVE_EACCESS)
3101 int 3071 int
3102 sys_eaccess (const char *path, int mode) 3072 qxe_eaccess (const Intbyte *path, int mode)
3103 { 3073 {
3104 PATHNAME_CONVERT_OUT (path); 3074 Extbyte *pathout;
3105 return eaccess (path, mode); 3075 PATHNAME_CONVERT_OUT (path, pathout);
3106 } 3076 return eaccess (pathout, mode);
3107 #endif /* ENCAPSULATE_EACCESS */ 3077 }
3108 #endif /* HAVE_EACCESS */ 3078 #endif /* defined (HAVE_EACCESS) */
3109 3079
3110
3111 #ifdef ENCAPSULATE_LSTAT
3112 int 3080 int
3113 sys_lstat (const char *path, struct stat *buf) 3081 qxe_lstat (const Intbyte *path, struct stat *buf)
3114 { 3082 {
3115 PATHNAME_CONVERT_OUT (path); 3083 /* if system does not have symbolic links, it does not have lstat.
3116 return lstat (path, buf); 3084 In that case, use ordinary stat instead. */
3117 } 3085 #ifndef S_IFLNK
3118 #endif /* ENCAPSULATE_LSTAT */ 3086 return qxe_stat (path, buf);
3119 3087 #else
3120 3088 Extbyte *pathout;
3121 #ifdef ENCAPSULATE_READLINK 3089 PATHNAME_CONVERT_OUT (path, pathout);
3090 return lstat (pathout, buf);
3091 #endif
3092 }
3093
3094 #if defined (HAVE_READLINK)
3122 int 3095 int
3123 sys_readlink (const char *path, char *buf, size_t bufsiz) 3096 qxe_readlink (const Intbyte *path, Intbyte *buf, size_t bufsiz)
3124 { 3097 {
3125 PATHNAME_CONVERT_OUT (path); 3098 int retval;
3126 /* #### currently we don't do conversions on the incoming data */ 3099 Extbyte *pathout;
3127 return readlink (path, buf, bufsiz); 3100
3128 } 3101 PATHNAME_CONVERT_OUT (path, pathout);
3129 #endif /* ENCAPSULATE_READLINK */ 3102 retval = readlink (pathout, (char *) buf, bufsiz);
3130 3103 if (retval < 0)
3131 #ifdef ENCAPSULATE_FSTAT 3104 return retval;
3105 {
3106 Intbyte *intbuf;
3107 Bytecount tamanho;
3108
3109 TO_INTERNAL_FORMAT (DATA, (buf, retval),
3110 ALLOCA, (intbuf, tamanho), Qfile_name);
3111 /* the man page says this function does not null-terminate */
3112 if (tamanho >= (Bytecount) bufsiz)
3113 tamanho = bufsiz;
3114 memcpy (buf, intbuf, tamanho);
3115 return tamanho;
3116 }
3117 }
3118 #endif /* defined (HAVE_READLINK) */
3119
3132 int 3120 int
3133 sys_fstat (int fd, struct stat *buf) 3121 qxe_fstat (int fd, struct stat *buf)
3134 { 3122 {
3135 #ifdef WIN32_NATIVE 3123 #ifdef WIN32_NATIVE
3136 return mswindows_fstat (fd, buf); 3124 return mswindows_fstat (fd, buf);
3137 #else 3125 #else
3138 return fstat (fd, buf); 3126 return fstat (fd, buf);
3139 #endif 3127 #endif /* WIN32_NATIVE */
3140 } 3128 }
3141 #endif /* ENCAPSULATE_FSTAT */
3142 3129
3143 int 3130 int
3144 xemacs_stat (const char *path, struct stat *buf) 3131 qxe_stat (const Intbyte *path, struct stat *buf)
3145 { 3132 {
3146 PATHNAME_CONVERT_OUT (path);
3147 #ifdef WIN32_NATIVE 3133 #ifdef WIN32_NATIVE
3148 return mswindows_stat (path, buf); 3134 return mswindows_stat (path, buf);
3149 #else 3135 #else /* not WIN32_NATIVE */
3150 return stat (path, buf); 3136 Extbyte *pathout;
3151 #endif 3137 PATHNAME_CONVERT_OUT (path, pathout);
3152 } 3138 return stat (pathout, buf);
3139 #endif /* WIN32_NATIVE */
3140 }
3141
3153 3142
3154 /****************** file-manipulation calls *****************/ 3143 /****************** file-manipulation calls *****************/
3155 3144
3156 #ifdef ENCAPSULATE_CHMOD
3157 int 3145 int
3158 sys_chmod (const char *path, mode_t mode) 3146 qxe_chmod (const Intbyte *path, mode_t mode)
3159 { 3147 {
3160 PATHNAME_CONVERT_OUT (path); 3148 Extbyte *pathout;
3161 return chmod (path, mode); 3149 PATHNAME_CONVERT_OUT (path, pathout);
3162 } 3150 #ifdef WIN32_NATIVE
3163 #endif /* ENCAPSULATE_CHMOD */ 3151 if (XEUNICODE_P)
3164 3152 return _wchmod ((const wchar_t *) pathout, mode);
3165 3153 else
3166 #ifdef ENCAPSULATE_CREAT 3154 return _chmod (pathout, mode);
3155 #else
3156 return chmod (pathout, mode);
3157 #endif
3158 }
3159
3160 #if defined (HAVE_LINK)
3167 int 3161 int
3168 sys_creat (const char *path, mode_t mode) 3162 qxe_link (const Intbyte *existing, const Intbyte *new)
3169 { 3163 {
3170 PATHNAME_CONVERT_OUT (path); 3164 #ifdef WIN32_NATIVE
3171 return creat (path, mode); 3165 return mswindows_link (existing, new);
3172 } 3166 #else /* not WIN32_NATIVE */
3173 #endif /* ENCAPSULATE_CREAT */ 3167 Extbyte *existingout, *newout;
3174 3168 PATHNAME_CONVERT_OUT (existing, existingout);
3175 3169 PATHNAME_CONVERT_OUT (new, newout);
3176 #ifdef ENCAPSULATE_LINK 3170 return link (existingout, newout);
3171 #endif /* WIN32_NATIVE */
3172 }
3173 #endif /* defined (HAVE_LINK) */
3174
3177 int 3175 int
3178 sys_link (const char *existing, const char *new) 3176 qxe_rename (const Intbyte *old, const Intbyte *new)
3179 { 3177 {
3180 PATHNAME_CONVERT_OUT (existing); 3178 #ifdef WIN32_NATIVE
3181 PATHNAME_CONVERT_OUT (new); 3179 return mswindows_rename (old, new);
3182 return link (existing, new); 3180 #else /* not WIN32_NATIVE */
3183 } 3181 Extbyte *oldout, *newout;
3184 #endif /* ENCAPSULATE_LINK */ 3182 PATHNAME_CONVERT_OUT (old, oldout);
3185 3183 PATHNAME_CONVERT_OUT (new, newout);
3186 3184 return rename (oldout, newout);
3187 #ifdef ENCAPSULATE_RENAME 3185 #endif /* WIN32_NATIVE */
3186 }
3187
3188 #if defined (HAVE_SYMLINK)
3188 int 3189 int
3189 sys_rename (const char *old, const char *new) 3190 qxe_symlink (const Intbyte *name1, const Intbyte *name2)
3190 { 3191 {
3191 PATHNAME_CONVERT_OUT (old); 3192 Extbyte *name1out, *name2out;
3192 PATHNAME_CONVERT_OUT (new); 3193 PATHNAME_CONVERT_OUT (name1, name1out);
3194 PATHNAME_CONVERT_OUT (name2, name2out);
3195 return symlink (name1out, name2out);
3196 }
3197 #endif /* defined (HAVE_SYMLINK) */
3198
3199 int
3200 qxe_unlink (const Intbyte *path)
3201 {
3193 #ifdef WIN32_NATIVE 3202 #ifdef WIN32_NATIVE
3194 /* Windows rename fails if NEW exists */ 3203 return mswindows_unlink (path);
3195 if (rename (old, new) == 0) 3204 #else /* not WIN32_NATIVE */
3196 return 0; 3205 Extbyte *pathout;
3197 if (errno != EEXIST) 3206 PATHNAME_CONVERT_OUT (path, pathout);
3198 return -1; 3207 return unlink (pathout);
3199 unlink (new);
3200 #endif /* WIN32_NATIVE */ 3208 #endif /* WIN32_NATIVE */
3201 return rename (old, new); 3209 }
3202 } 3210
3203 #endif /* ENCAPSULATE_RENAME */ 3211
3204 3212 /****************** process calls *****************/
3205 3213
3206 #ifdef ENCAPSULATE_SYMLINK
3207 int 3214 int
3208 sys_symlink (const char *name1, const char *name2) 3215 qxe_execve (const Intbyte *filename, Intbyte * const argv[],
3209 { 3216 Intbyte * const envp[])
3210 PATHNAME_CONVERT_OUT (name1); 3217 {
3211 PATHNAME_CONVERT_OUT (name2); 3218 int i, argc, envc;
3212 return symlink (name1, name2); 3219 Extbyte *pathext;
3213 } 3220 Extbyte **new_argv;
3214 #endif /* ENCAPSULATE_SYMLINK */ 3221 Extbyte **new_envp;
3215 3222
3216 3223 PATHNAME_CONVERT_OUT (filename, pathext);
3217 #ifdef ENCAPSULATE_UNLINK 3224
3218 int
3219 sys_unlink (const char *path)
3220 {
3221 PATHNAME_CONVERT_OUT (path);
3222 return unlink (path);
3223 }
3224 #endif /* ENCAPSULATE_UNLINK */
3225
3226
3227 #ifdef ENCAPSULATE_EXECVP
3228 int
3229 sys_execvp (const char *path, char * const * argv)
3230 {
3231 int i, argc;
3232 char ** new_argv;
3233
3234 PATHNAME_CONVERT_OUT (path);
3235 for (argc = 0; argv[argc]; argc++) 3225 for (argc = 0; argv[argc]; argc++)
3236 ; 3226 ;
3237 new_argv = alloca_array (char *, argc + 1); 3227 new_argv = alloca_array (Extbyte *, argc + 1);
3238 for (i = 0; i < argc; i++) 3228 for (i = 0; i < argc; i++)
3239 { 3229 C_STRING_TO_EXTERNAL (argv[i], new_argv[i], Qnative);
3240 new_argv[i] = argv[i];
3241 PATHNAME_CONVERT_OUT (new_argv[i]);
3242 }
3243 new_argv[argc] = NULL; 3230 new_argv[argc] = NULL;
3244 return execvp (path, new_argv); 3231
3245 } 3232 for (envc = 0; envp[envc]; envc++)
3246 #endif /* ENCAPSULATE_EXECVP */ 3233 ;
3234 new_envp = alloca_array (Extbyte *, envc + 1);
3235 for (i = 0; i < envc; i++)
3236 C_STRING_TO_EXTERNAL (envp[i], new_envp[i], Qnative);
3237 new_envp[envc] = NULL;
3238
3239 return execve (pathext, new_argv, new_envp);
3240 }
3241
3242 pid_t
3243 qxe_getpid (void)
3244 {
3245 #ifdef WIN32_NATIVE
3246 return abs (getpid ());
3247 #else
3248 return getpid ();
3249 #endif
3250 }
3251
3252
3253 /****************** passwd calls *****************/
3254
3255 struct passwd cached_pwd;
3256
3257 static struct passwd *
3258 copy_in_passwd (struct passwd *pwd)
3259 {
3260 if (!pwd)
3261 return NULL;
3262
3263 if (cached_pwd.pw_name)
3264 xfree (cached_pwd.pw_name);
3265 if (cached_pwd.pw_passwd)
3266 xfree (cached_pwd.pw_passwd);
3267 if (cached_pwd.pw_gecos)
3268 xfree (cached_pwd.pw_gecos);
3269 if (cached_pwd.pw_dir)
3270 xfree (cached_pwd.pw_dir);
3271 if (cached_pwd.pw_shell)
3272 xfree (cached_pwd.pw_shell);
3273
3274 cached_pwd = *pwd;
3275 if (cached_pwd.pw_name)
3276 TO_INTERNAL_FORMAT (C_STRING, cached_pwd.pw_name,
3277 C_STRING_MALLOC, cached_pwd.pw_name, Qnative);
3278 if (cached_pwd.pw_passwd)
3279 TO_INTERNAL_FORMAT (C_STRING, cached_pwd.pw_passwd,
3280 C_STRING_MALLOC, cached_pwd.pw_passwd, Qnative);
3281 if (cached_pwd.pw_gecos)
3282 TO_INTERNAL_FORMAT (C_STRING, cached_pwd.pw_gecos,
3283 C_STRING_MALLOC, cached_pwd.pw_gecos, Qnative);
3284 if (cached_pwd.pw_dir)
3285 TO_INTERNAL_FORMAT (C_STRING, cached_pwd.pw_dir,
3286 C_STRING_MALLOC, cached_pwd.pw_dir, Qfile_name);
3287 if (cached_pwd.pw_shell)
3288 TO_INTERNAL_FORMAT (C_STRING, cached_pwd.pw_shell,
3289 C_STRING_MALLOC, cached_pwd.pw_shell, Qfile_name);
3290 return &cached_pwd;
3291 }
3292
3293 struct passwd *
3294 qxe_getpwnam (const Intbyte *name)
3295 {
3296 #ifdef WIN32_NATIVE
3297 /* Synthetic versions are defined in nt.c and already do conversion. */
3298 return getpwnam (name);
3299 #else
3300 Extbyte *nameext;
3301 C_STRING_TO_EXTERNAL (name, nameext, Qnative);
3302
3303 return copy_in_passwd (getpwnam (nameext));
3304 #endif /* WIN32_NATIVE */
3305 }
3306
3307 struct passwd *
3308 qxe_getpwuid (uid_t uid)
3309 {
3310 #ifdef WIN32_NATIVE
3311 /* Synthetic versions are defined in nt.c and already do conversion. */
3312 return getpwuid (uid);
3313 #else
3314 return copy_in_passwd (getpwuid (uid));
3315 #endif /* WIN32_NATIVE */
3316 }
3317
3318 #ifndef WIN32_NATIVE
3319
3320 struct passwd *
3321 qxe_getpwent (void)
3322 {
3323 /* No WIN32_NATIVE version of this. */
3324 return copy_in_passwd (getpwent ());
3325 }
3326
3327 #endif /* not WIN32_NATIVE */
3328
3329 /****************** time calls *****************/
3330
3331 static Intbyte *ctime_static;
3332
3333 Intbyte *
3334 qxe_ctime (const time_t *t)
3335 {
3336 Extbyte *str = (Extbyte *) ctime (t);
3337 if (!str) /* can happen on MS Windows */
3338 return (Intbyte *) "Sun Jan 01 00:00:00 1970";
3339 if (ctime_static)
3340 xfree (ctime_static);
3341 EXTERNAL_TO_C_STRING_MALLOC (str, ctime_static, Qnative);
3342 return ctime_static;
3343 }
3247 3344
3248 3345
3249 /************************************************************************/ 3346 /************************************************************************/
3250 /* Emulations of missing system calls */ 3347 /* Emulations of missing system calls */
3251 /************************************************************************/ 3348 /************************************************************************/
3252 3349
3253 /***** (these are primarily required for USG, it seems) *****/ 3350 /***** (these are primarily required for USG, it seems) *****/
3254
3255 #ifndef HAVE_GETCWD
3256 char *
3257 getcwd (char *pathname, size_t size)
3258 {
3259 return getwd (pathname);
3260 }
3261 #endif /* emulate getcwd */
3262
3263
3264 #if 0 /* mrb */
3265 /*
3266 * Warning, this function may not duplicate BSD 4.2 action properly
3267 * under error conditions.
3268 */
3269
3270 #ifndef HAVE_GETWD
3271 char *
3272 getwd (char *pathname)
3273 {
3274 char *npath, *spath;
3275 #if !__STDC__ && !defined(STDC_HEADERS)
3276 extern char *getcwd ();
3277 #endif
3278
3279 spath = npath = getcwd ((char *) 0, MAXPATHLEN);
3280 if (spath == 0)
3281 return spath;
3282 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3283 up to first slash. Should be harmless on other systems. */
3284 while (*npath && *npath != '/')
3285 npath++;
3286 strcpy (pathname, npath);
3287 xfree (spath); /* getcwd uses malloc */
3288 return pathname;
3289 }
3290 #endif /* HAVE_GETWD */
3291 #endif /* 0 - mrb */
3292 3351
3293 /* 3352 /*
3294 * Emulate rename using unlink/link. Note that this is 3353 * Emulate rename using unlink/link. Note that this is
3295 * only partially correct. Also, doesn't enforce restriction 3354 * only partially correct. Also, doesn't enforce restriction
3296 * that files be of same type (regular->regular, dir->dir, etc). 3355 * that files be of same type (regular->regular, dir->dir, etc).
3297 */ 3356 */
3298 3357
3299 #ifndef HAVE_RENAME 3358 #ifndef HAVE_RENAME
3300 int 3359 int
3301 rename (const char *from, const char *to) 3360 rename (const Extbyte *from, const Extbyte *to)
3302 { 3361 {
3303 if (access (from, 0) == 0) 3362 if (access (from, 0) == 0)
3304 { 3363 {
3305 unlink (to); 3364 unlink (to);
3306 if (link (from, to) == 0) 3365 if (link (from, to) == 0)
3335 int 3394 int
3336 dup2 (int oldd, int newd) 3395 dup2 (int oldd, int newd)
3337 { 3396 {
3338 int fd, ret; 3397 int fd, ret;
3339 3398
3340 sys_close (newd); 3399 retry_close (newd);
3341 3400
3342 #ifdef F_DUPFD 3401 #ifdef F_DUPFD
3343 fd = fcntl (oldd, F_DUPFD, newd); 3402 fd = fcntl (oldd, F_DUPFD, newd);
3344 if (fd != newd) 3403 if (fd != newd)
3345 signal_ferror_with_frob (Qfile_error, lisp_strerror (errno), 3404 signal_ferror_with_frob (Qfile_error, lisp_strerror (errno),
3349 if (fd == -1) 3408 if (fd == -1)
3350 return -1; 3409 return -1;
3351 if (fd == new) 3410 if (fd == new)
3352 return new; 3411 return new;
3353 ret = dup2 (old, new); 3412 ret = dup2 (old, new);
3354 sys_close (fd); 3413 retry_close (fd);
3355 return ret; 3414 return ret;
3356 #endif /* F_DUPFD */ 3415 #endif /* F_DUPFD */
3357 } 3416 }
3358 3417
3359 #endif /* not HAVE_DUP2 */ 3418 #endif /* not HAVE_DUP2 */
3519 # endif /* RAND_MAX != 32767 */ 3578 # endif /* RAND_MAX != 32767 */
3520 # endif /* !HAVE_LRAND48 */ 3579 # endif /* !HAVE_LRAND48 */
3521 # endif /* !HAVE_RANDOM */ 3580 # endif /* !HAVE_RANDOM */
3522 #endif /* !RAND_BITS */ 3581 #endif /* !RAND_BITS */
3523 3582
3524 void seed_random (long arg);
3525 void 3583 void
3526 seed_random (long arg) 3584 seed_random (long arg)
3527 { 3585 {
3528 #ifdef HAVE_RANDOM 3586 #ifdef HAVE_RANDOM
3529 srandom ((unsigned int)arg); 3587 srandom ((unsigned int)arg);
3538 3596
3539 /* 3597 /*
3540 * Build a full Emacs-sized word out of whatever we've got. 3598 * Build a full Emacs-sized word out of whatever we've got.
3541 * This suffices even for a 64-bit architecture with a 15-bit rand. 3599 * This suffices even for a 64-bit architecture with a 15-bit rand.
3542 */ 3600 */
3543 long get_random (void);
3544 long 3601 long
3545 get_random (void) 3602 get_random (void)
3546 { 3603 {
3547 long val = random (); 3604 long val = random ();
3548 #if VALBITS > RAND_BITS 3605 #if VALBITS > RAND_BITS
3568 #if !defined (SYS_SIGLIST_DECLARED) && !defined (HAVE_SYS_SIGLIST) 3625 #if !defined (SYS_SIGLIST_DECLARED) && !defined (HAVE_SYS_SIGLIST)
3569 3626
3570 #if defined(WIN32_NATIVE) || defined(CYGWIN) 3627 #if defined(WIN32_NATIVE) || defined(CYGWIN)
3571 const char *sys_siglist[] = 3628 const char *sys_siglist[] =
3572 { 3629 {
3630 /* $$####begin-snarf */
3573 "bum signal!!", 3631 "bum signal!!",
3574 "hangup", 3632 "hangup",
3575 "interrupt", 3633 "interrupt",
3576 "quit", 3634 "quit",
3577 "illegal instruction", 3635 "illegal instruction",
3594 "background read attempted from control tty", 3652 "background read attempted from control tty",
3595 "background write attempted from control tty", 3653 "background write attempted from control tty",
3596 "input record available at control tty", 3654 "input record available at control tty",
3597 "exceeded CPU time limit", 3655 "exceeded CPU time limit",
3598 "exceeded file size limit" 3656 "exceeded file size limit"
3657 /* $$####end-snarf */
3599 }; 3658 };
3600 #endif 3659 #endif
3601 3660
3602 #ifdef USG 3661 #ifdef USG
3603 #ifdef AIX 3662 #ifdef AIX
3604 const char *sys_siglist[NSIG + 1] = 3663 const char *sys_siglist[NSIG + 1] =
3605 { 3664 {
3606 /* AIX has changed the signals a bit */ 3665 /* AIX has changed the signals a bit */
3607 DEFER_GETTEXT ("bogus signal"), /* 0 */ 3666 /* $$####begin-snarf */
3608 DEFER_GETTEXT ("hangup"), /* 1 SIGHUP */ 3667 "bogus signal", /* 0 */
3609 DEFER_GETTEXT ("interrupt"), /* 2 SIGINT */ 3668 "hangup", /* 1 SIGHUP */
3610 DEFER_GETTEXT ("quit"), /* 3 SIGQUIT */ 3669 "interrupt", /* 2 SIGINT */
3611 DEFER_GETTEXT ("illegal instruction"), /* 4 SIGILL */ 3670 "quit", /* 3 SIGQUIT */
3612 DEFER_GETTEXT ("trace trap"), /* 5 SIGTRAP */ 3671 "illegal instruction", /* 4 SIGILL */
3613 DEFER_GETTEXT ("IOT instruction"), /* 6 SIGIOT */ 3672 "trace trap", /* 5 SIGTRAP */
3614 DEFER_GETTEXT ("crash likely"), /* 7 SIGDANGER */ 3673 "IOT instruction", /* 6 SIGIOT */
3615 DEFER_GETTEXT ("floating point exception"), /* 8 SIGFPE */ 3674 "crash likely", /* 7 SIGDANGER */
3616 DEFER_GETTEXT ("kill"), /* 9 SIGKILL */ 3675 "floating point exception", /* 8 SIGFPE */
3617 DEFER_GETTEXT ("bus error"), /* 10 SIGBUS */ 3676 "kill", /* 9 SIGKILL */
3618 DEFER_GETTEXT ("segmentation violation"), /* 11 SIGSEGV */ 3677 "bus error", /* 10 SIGBUS */
3619 DEFER_GETTEXT ("bad argument to system call"), /* 12 SIGSYS */ 3678 "segmentation violation", /* 11 SIGSEGV */
3620 DEFER_GETTEXT ("write on a pipe with no one to read it"), /* 13 SIGPIPE */ 3679 "bad argument to system call", /* 12 SIGSYS */
3621 DEFER_GETTEXT ("alarm clock"), /* 14 SIGALRM */ 3680 "write on a pipe with no one to read it", /* 13 SIGPIPE */
3622 DEFER_GETTEXT ("software termination signum"), /* 15 SIGTERM */ 3681 "alarm clock", /* 14 SIGALRM */
3623 DEFER_GETTEXT ("user defined signal 1"), /* 16 SIGUSR1 */ 3682 "software termination signum", /* 15 SIGTERM */
3624 DEFER_GETTEXT ("user defined signal 2"), /* 17 SIGUSR2 */ 3683 "user defined signal 1", /* 16 SIGUSR1 */
3625 DEFER_GETTEXT ("death of a child"), /* 18 SIGCLD */ 3684 "user defined signal 2", /* 17 SIGUSR2 */
3626 DEFER_GETTEXT ("power-fail restart"), /* 19 SIGPWR */ 3685 "death of a child", /* 18 SIGCLD */
3627 DEFER_GETTEXT ("bogus signal"), /* 20 */ 3686 "power-fail restart", /* 19 SIGPWR */
3628 DEFER_GETTEXT ("bogus signal"), /* 21 */ 3687 "bogus signal", /* 20 */
3629 DEFER_GETTEXT ("bogus signal"), /* 22 */ 3688 "bogus signal", /* 21 */
3630 DEFER_GETTEXT ("bogus signal"), /* 23 */ 3689 "bogus signal", /* 22 */
3631 DEFER_GETTEXT ("bogus signal"), /* 24 */ 3690 "bogus signal", /* 23 */
3632 DEFER_GETTEXT ("LAN I/O interrupt"), /* 25 SIGAIO */ 3691 "bogus signal", /* 24 */
3633 DEFER_GETTEXT ("PTY I/O interrupt"), /* 26 SIGPTY */ 3692 "LAN I/O interrupt", /* 25 SIGAIO */
3634 DEFER_GETTEXT ("I/O intervention required"), /* 27 SIGIOINT */ 3693 "PTY I/O interrupt", /* 26 SIGPTY */
3694 "I/O intervention required", /* 27 SIGIOINT */
3635 #ifdef AIXHFT 3695 #ifdef AIXHFT
3636 DEFER_GETTEXT ("HFT grant"), /* 28 SIGGRANT */ 3696 "HFT grant", /* 28 SIGGRANT */
3637 DEFER_GETTEXT ("HFT retract"), /* 29 SIGRETRACT */ 3697 "HFT retract", /* 29 SIGRETRACT */
3638 DEFER_GETTEXT ("HFT sound done"), /* 30 SIGSOUND */ 3698 "HFT sound done", /* 30 SIGSOUND */
3639 DEFER_GETTEXT ("HFT input ready"), /* 31 SIGMSG */ 3699 "HFT input ready", /* 31 SIGMSG */
3640 #endif 3700 #endif
3701 /* $$####end-snarf */
3641 0 3702 0
3642 }; 3703 };
3643 #else /* USG, not AIX */ 3704 #else /* USG, not AIX */
3644 const char *sys_siglist[NSIG + 1] = 3705 const char *sys_siglist[NSIG + 1] =
3645 { 3706 {
3646 DEFER_GETTEXT ("bogus signal"), /* 0 */ 3707 /* $$####begin-snarf */
3647 DEFER_GETTEXT ("hangup"), /* 1 SIGHUP */ 3708 "bogus signal", /* 0 */
3648 DEFER_GETTEXT ("interrupt"), /* 2 SIGINT */ 3709 "hangup", /* 1 SIGHUP */
3649 DEFER_GETTEXT ("quit"), /* 3 SIGQUIT */ 3710 "interrupt", /* 2 SIGINT */
3650 DEFER_GETTEXT ("illegal instruction"), /* 4 SIGILL */ 3711 "quit", /* 3 SIGQUIT */
3651 DEFER_GETTEXT ("trace trap"), /* 5 SIGTRAP */ 3712 "illegal instruction", /* 4 SIGILL */
3652 DEFER_GETTEXT ("IOT instruction"), /* 6 SIGIOT */ 3713 "trace trap", /* 5 SIGTRAP */
3653 DEFER_GETTEXT ("EMT instruction"), /* 7 SIGEMT */ 3714 "IOT instruction", /* 6 SIGIOT */
3654 DEFER_GETTEXT ("floating point exception"), /* 8 SIGFPE */ 3715 "EMT instruction", /* 7 SIGEMT */
3655 DEFER_GETTEXT ("kill"), /* 9 SIGKILL */ 3716 "floating point exception", /* 8 SIGFPE */
3656 DEFER_GETTEXT ("bus error"), /* 10 SIGBUS */ 3717 "kill", /* 9 SIGKILL */
3657 DEFER_GETTEXT ("segmentation violation"), /* 11 SIGSEGV */ 3718 "bus error", /* 10 SIGBUS */
3658 DEFER_GETTEXT ("bad argument to system call"), /* 12 SIGSYS */ 3719 "segmentation violation", /* 11 SIGSEGV */
3659 DEFER_GETTEXT ("write on a pipe with no one to read it"), /* 13 SIGPIPE */ 3720 "bad argument to system call", /* 12 SIGSYS */
3660 DEFER_GETTEXT ("alarm clock"), /* 14 SIGALRM */ 3721 "write on a pipe with no one to read it", /* 13 SIGPIPE */
3661 DEFER_GETTEXT ("software termination signum"), /* 15 SIGTERM */ 3722 "alarm clock", /* 14 SIGALRM */
3662 DEFER_GETTEXT ("user defined signal 1"), /* 16 SIGUSR1 */ 3723 "software termination signum", /* 15 SIGTERM */
3663 DEFER_GETTEXT ("user defined signal 2"), /* 17 SIGUSR2 */ 3724 "user defined signal 1", /* 16 SIGUSR1 */
3664 DEFER_GETTEXT ("death of a child"), /* 18 SIGCLD */ 3725 "user defined signal 2", /* 17 SIGUSR2 */
3665 DEFER_GETTEXT ("power-fail restart"), /* 19 SIGPWR */ 3726 "death of a child", /* 18 SIGCLD */
3727 "power-fail restart", /* 19 SIGPWR */
3666 #ifdef sun 3728 #ifdef sun
3667 DEFER_GETTEXT ("window size changed"), /* 20 SIGWINCH */ 3729 "window size changed", /* 20 SIGWINCH */
3668 DEFER_GETTEXT ("urgent socket condition"), /* 21 SIGURG */ 3730 "urgent socket condition", /* 21 SIGURG */
3669 DEFER_GETTEXT ("pollable event occurred"), /* 22 SIGPOLL */ 3731 "pollable event occurred", /* 22 SIGPOLL */
3670 DEFER_GETTEXT ("stop (cannot be caught or ignored)"), /* 23 SIGSTOP */ 3732 "stop (cannot be caught or ignored)", /* 23 SIGSTOP */
3671 DEFER_GETTEXT ("user stop requested from tty"), /* 24 SIGTSTP */ 3733 "user stop requested from tty", /* 24 SIGTSTP */
3672 DEFER_GETTEXT ("stopped process has been continued"), /* 25 SIGCONT */ 3734 "stopped process has been continued", /* 25 SIGCONT */
3673 DEFER_GETTEXT ("background tty read attempted"), /* 26 SIGTTIN */ 3735 "background tty read attempted", /* 26 SIGTTIN */
3674 DEFER_GETTEXT ("background tty write attempted"), /* 27 SIGTTOU */ 3736 "background tty write attempted", /* 27 SIGTTOU */
3675 DEFER_GETTEXT ("virtual timer expired"), /* 28 SIGVTALRM */ 3737 "virtual timer expired", /* 28 SIGVTALRM */
3676 DEFER_GETTEXT ("profiling timer expired"), /* 29 SIGPROF */ 3738 "profiling timer expired", /* 29 SIGPROF */
3677 DEFER_GETTEXT ("exceeded cpu limit"), /* 30 SIGXCPU */ 3739 "exceeded cpu limit", /* 30 SIGXCPU */
3678 DEFER_GETTEXT ("exceeded file size limit"), /* 31 SIGXFSZ */ 3740 "exceeded file size limit", /* 31 SIGXFSZ */
3679 DEFER_GETTEXT ("process's lwps are blocked"), /* 32 SIGWAITING */ 3741 "process's lwps are blocked", /* 32 SIGWAITING */
3680 DEFER_GETTEXT ("special signal used by thread library"), /* 33 SIGLWP */ 3742 "special signal used by thread library", /* 33 SIGLWP */
3681 #ifdef SIGFREEZE 3743 #ifdef SIGFREEZE
3682 DEFER_GETTEXT ("special signal used by CPR"), /* 34 SIGFREEZE */ 3744 "special signal used by CPR", /* 34 SIGFREEZE */
3683 #endif 3745 #endif
3684 #ifdef SIGTHAW 3746 #ifdef SIGTHAW
3685 DEFER_GETTEXT ("special signal used by CPR"), /* 35 SIGTHAW */ 3747 "special signal used by CPR", /* 35 SIGTHAW */
3686 #endif 3748 #endif
3687 #endif /* sun */ 3749 #endif /* sun */
3750 /* $$####end-snarf */
3688 0 3751 0
3689 }; 3752 };
3690 #endif /* not AIX */ 3753 #endif /* not AIX */
3691 #endif /* USG */ 3754 #endif /* USG */
3692 #ifdef DGUX 3755 #ifdef DGUX
3693 const char *sys_siglist[NSIG + 1] = 3756 const char *sys_siglist[NSIG + 1] =
3694 { 3757 {
3695 DEFER_GETTEXT ("null signal"), /* 0 SIGNULL */ 3758 /* $$####begin-snarf */
3696 DEFER_GETTEXT ("hangup"), /* 1 SIGHUP */ 3759 "null signal", /* 0 SIGNULL */
3697 DEFER_GETTEXT ("interrupt"), /* 2 SIGINT */ 3760 "hangup", /* 1 SIGHUP */
3698 DEFER_GETTEXT ("quit"), /* 3 SIGQUIT */ 3761 "interrupt", /* 2 SIGINT */
3699 DEFER_GETTEXT ("illegal instruction"), /* 4 SIGILL */ 3762 "quit", /* 3 SIGQUIT */
3700 DEFER_GETTEXT ("trace trap"), /* 5 SIGTRAP */ 3763 "illegal instruction", /* 4 SIGILL */
3701 DEFER_GETTEXT ("abort termination"), /* 6 SIGABRT */ 3764 "trace trap", /* 5 SIGTRAP */
3702 DEFER_GETTEXT ("SIGEMT"), /* 7 SIGEMT */ 3765 "abort termination", /* 6 SIGABRT */
3703 DEFER_GETTEXT ("floating point exception"), /* 8 SIGFPE */ 3766 "SIGEMT", /* 7 SIGEMT */
3704 DEFER_GETTEXT ("kill"), /* 9 SIGKILL */ 3767 "floating point exception", /* 8 SIGFPE */
3705 DEFER_GETTEXT ("bus error"), /* 10 SIGBUS */ 3768 "kill", /* 9 SIGKILL */
3706 DEFER_GETTEXT ("segmentation violation"), /* 11 SIGSEGV */ 3769 "bus error", /* 10 SIGBUS */
3707 DEFER_GETTEXT ("bad argument to system call"), /* 12 SIGSYS */ 3770 "segmentation violation", /* 11 SIGSEGV */
3708 DEFER_GETTEXT ("write on a pipe with no reader"), /* 13 SIGPIPE */ 3771 "bad argument to system call", /* 12 SIGSYS */
3709 DEFER_GETTEXT ("alarm clock"), /* 14 SIGALRM */ 3772 "write on a pipe with no reader", /* 13 SIGPIPE */
3710 DEFER_GETTEXT ("software termination signal"), /* 15 SIGTERM */ 3773 "alarm clock", /* 14 SIGALRM */
3711 DEFER_GETTEXT ("user defined signal 1"), /* 16 SIGUSR1 */ 3774 "software termination signal", /* 15 SIGTERM */
3712 DEFER_GETTEXT ("user defined signal 2"), /* 17 SIGUSR2 */ 3775 "user defined signal 1", /* 16 SIGUSR1 */
3713 DEFER_GETTEXT ("child stopped or terminated"), /* 18 SIGCLD */ 3776 "user defined signal 2", /* 17 SIGUSR2 */
3714 DEFER_GETTEXT ("power-fail restart"), /* 19 SIGPWR */ 3777 "child stopped or terminated", /* 18 SIGCLD */
3715 DEFER_GETTEXT ("window size changed"), /* 20 SIGWINCH */ 3778 "power-fail restart", /* 19 SIGPWR */
3716 DEFER_GETTEXT ("undefined"), /* 21 */ 3779 "window size changed", /* 20 SIGWINCH */
3717 DEFER_GETTEXT ("pollable event occurred"), /* 22 SIGPOLL */ 3780 "undefined", /* 21 */
3718 DEFER_GETTEXT ("sendable stop signal not from tty"), /* 23 SIGSTOP */ 3781 "pollable event occurred", /* 22 SIGPOLL */
3719 DEFER_GETTEXT ("stop signal from tty"), /* 24 SIGSTP */ 3782 "sendable stop signal not from tty", /* 23 SIGSTOP */
3720 DEFER_GETTEXT ("continue a stopped process"), /* 25 SIGCONT */ 3783 "stop signal from tty", /* 24 SIGSTP */
3721 DEFER_GETTEXT ("attempted background tty read"), /* 26 SIGTTIN */ 3784 "continue a stopped process", /* 25 SIGCONT */
3722 DEFER_GETTEXT ("attempted background tty write"), /* 27 SIGTTOU */ 3785 "attempted background tty read", /* 26 SIGTTIN */
3723 DEFER_GETTEXT ("undefined"), /* 28 */ 3786 "attempted background tty write", /* 27 SIGTTOU */
3724 DEFER_GETTEXT ("undefined"), /* 29 */ 3787 "undefined", /* 28 */
3725 DEFER_GETTEXT ("undefined"), /* 30 */ 3788 "undefined", /* 29 */
3726 DEFER_GETTEXT ("undefined"), /* 31 */ 3789 "undefined", /* 30 */
3727 DEFER_GETTEXT ("undefined"), /* 32 */ 3790 "undefined", /* 31 */
3728 DEFER_GETTEXT ("socket (TCP/IP) urgent data arrival"), /* 33 SIGURG */ 3791 "undefined", /* 32 */
3729 DEFER_GETTEXT ("I/O is possible"), /* 34 SIGIO */ 3792 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
3730 DEFER_GETTEXT ("exceeded cpu time limit"), /* 35 SIGXCPU */ 3793 "I/O is possible", /* 34 SIGIO */
3731 DEFER_GETTEXT ("exceeded file size limit"), /* 36 SIGXFSZ */ 3794 "exceeded cpu time limit", /* 35 SIGXCPU */
3732 DEFER_GETTEXT ("virtual time alarm"), /* 37 SIGVTALRM */ 3795 "exceeded file size limit", /* 36 SIGXFSZ */
3733 DEFER_GETTEXT ("profiling time alarm"), /* 38 SIGPROF */ 3796 "virtual time alarm", /* 37 SIGVTALRM */
3734 DEFER_GETTEXT ("undefined"), /* 39 */ 3797 "profiling time alarm", /* 38 SIGPROF */
3735 DEFER_GETTEXT ("file record locks revoked"), /* 40 SIGLOST */ 3798 "undefined", /* 39 */
3736 DEFER_GETTEXT ("undefined"), /* 41 */ 3799 "file record locks revoked", /* 40 SIGLOST */
3737 DEFER_GETTEXT ("undefined"), /* 42 */ 3800 "undefined", /* 41 */
3738 DEFER_GETTEXT ("undefined"), /* 43 */ 3801 "undefined", /* 42 */
3739 DEFER_GETTEXT ("undefined"), /* 44 */ 3802 "undefined", /* 43 */
3740 DEFER_GETTEXT ("undefined"), /* 45 */ 3803 "undefined", /* 44 */
3741 DEFER_GETTEXT ("undefined"), /* 46 */ 3804 "undefined", /* 45 */
3742 DEFER_GETTEXT ("undefined"), /* 47 */ 3805 "undefined", /* 46 */
3743 DEFER_GETTEXT ("undefined"), /* 48 */ 3806 "undefined", /* 47 */
3744 DEFER_GETTEXT ("undefined"), /* 49 */ 3807 "undefined", /* 48 */
3745 DEFER_GETTEXT ("undefined"), /* 50 */ 3808 "undefined", /* 49 */
3746 DEFER_GETTEXT ("undefined"), /* 51 */ 3809 "undefined", /* 50 */
3747 DEFER_GETTEXT ("undefined"), /* 52 */ 3810 "undefined", /* 51 */
3748 DEFER_GETTEXT ("undefined"), /* 53 */ 3811 "undefined", /* 52 */
3749 DEFER_GETTEXT ("undefined"), /* 54 */ 3812 "undefined", /* 53 */
3750 DEFER_GETTEXT ("undefined"), /* 55 */ 3813 "undefined", /* 54 */
3751 DEFER_GETTEXT ("undefined"), /* 56 */ 3814 "undefined", /* 55 */
3752 DEFER_GETTEXT ("undefined"), /* 57 */ 3815 "undefined", /* 56 */
3753 DEFER_GETTEXT ("undefined"), /* 58 */ 3816 "undefined", /* 57 */
3754 DEFER_GETTEXT ("undefined"), /* 59 */ 3817 "undefined", /* 58 */
3755 DEFER_GETTEXT ("undefined"), /* 60 */ 3818 "undefined", /* 59 */
3756 DEFER_GETTEXT ("undefined"), /* 61 */ 3819 "undefined", /* 60 */
3757 DEFER_GETTEXT ("undefined"), /* 62 */ 3820 "undefined", /* 61 */
3758 DEFER_GETTEXT ("undefined"), /* 63 */ 3821 "undefined", /* 62 */
3759 DEFER_GETTEXT ("notification message in mess. queue"), /* 64 SIGDGNOTIFY */ 3822 "undefined", /* 63 */
3823 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
3824 /* $$####end-snarf */
3760 0 3825 0
3761 }; 3826 };
3762 #endif /* DGUX */ 3827 #endif /* DGUX */
3763 3828
3764 #endif /* ! SYS_SIGLIST_DECLARED && ! HAVE_SYS_SIGLIST */ 3829 #endif /* ! SYS_SIGLIST_DECLARED && ! HAVE_SYS_SIGLIST */
3776 int 3841 int
3777 closedir (DIR *dirp) /* stream from opendir */ 3842 closedir (DIR *dirp) /* stream from opendir */
3778 { 3843 {
3779 int rtnval; 3844 int rtnval;
3780 3845
3781 rtnval = sys_close (dirp->dd_fd); 3846 rtnval = retry_close (dirp->dd_fd);
3782 3847
3783 /* Some systems (like Solaris) allocate the buffer and the DIR all 3848 /* Some systems (like Solaris) allocate the buffer and the DIR all
3784 in one block. Why in the world are we freeing this ourselves 3849 in one block. Why in the world are we freeing this ourselves
3785 anyway? */ 3850 anyway? */
3786 #if ! (defined (sun) && defined (USG5_4)) 3851 #if ! (defined (sun) && defined (USG5_4))
3799 { 3864 {
3800 DIR *dirp; /* -> malloc'ed storage */ 3865 DIR *dirp; /* -> malloc'ed storage */
3801 int fd; /* file descriptor for read */ 3866 int fd; /* file descriptor for read */
3802 struct stat sbuf; /* result of fstat */ 3867 struct stat sbuf; /* result of fstat */
3803 3868
3804 fd = sys_open (filename, O_RDONLY); 3869 fd = open (filename, O_RDONLY);
3805 if (fd < 0) 3870 if (fd < 0)
3806 return 0; 3871 return 0;
3807 3872
3808 if (fstat (fd, &sbuf) < 0 3873 if (fstat (fd, &sbuf) < 0
3809 || (sbuf.st_mode & S_IFMT) != S_IFDIR 3874 || (sbuf.st_mode & S_IFMT) != S_IFDIR
3810 || (dirp = (DIR *) malloc (sizeof (DIR))) == 0) 3875 || (dirp = (DIR *) malloc (sizeof (DIR))) == 0)
3811 { 3876 {
3812 sys_close (fd); 3877 retry_close (fd);
3813 return 0; /* bad luck today */ 3878 return 0; /* bad luck today */
3814 } 3879 }
3815 3880
3816 dirp->dd_fd = fd; 3881 dirp->dd_fd = fd;
3817 dirp->dd_loc = dirp->dd_size = 0; /* refill needed */ 3882 dirp->dd_loc = dirp->dd_size = 0; /* refill needed */
3820 } 3885 }
3821 3886
3822 void 3887 void
3823 closedir (DIR *dirp) /* stream from opendir */ 3888 closedir (DIR *dirp) /* stream from opendir */
3824 { 3889 {
3825 sys_close (dirp->dd_fd); 3890 retry_close (dirp->dd_fd);
3826 xfree (dirp); 3891 xfree (dirp);
3827 } 3892 }
3828 3893
3829 3894
3830 #define DIRSIZ 14 3895 #define DIRSIZ 14
3846 { 3911 {
3847 if (dirp->dd_loc >= dirp->dd_size) 3912 if (dirp->dd_loc >= dirp->dd_size)
3848 dirp->dd_loc = dirp->dd_size = 0; 3913 dirp->dd_loc = dirp->dd_size = 0;
3849 3914
3850 if (dirp->dd_size == 0 /* refill buffer */ 3915 if (dirp->dd_size == 0 /* refill buffer */
3851 && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0) 3916 && (dirp->dd_size =
3917 retry_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3852 return 0; 3918 return 0;
3853 3919
3854 dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc]; 3920 dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
3855 dirp->dd_loc += sizeof (struct olddir); 3921 dirp->dd_loc += sizeof (struct olddir);
3856 3922
3928 * ####, this won't suffice to set SUID, SGID, etc. on this 3994 * ####, this won't suffice to set SUID, SGID, etc. on this
3929 * directory. Does anybody care? 3995 * directory. Does anybody care?
3930 */ 3996 */
3931 status = umask (0); /* Get current umask */ 3997 status = umask (0); /* Get current umask */
3932 status = umask (status | (0777 & ~dmode)); /* Set for mkdir */ 3998 status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
3933 fd = sys_open ("/dev/null", O_RDWR); 3999 fd = open ("/dev/null", O_RDWR);
3934 if (fd >= 0) 4000 if (fd >= 0)
3935 { 4001 {
3936 if (fd != STDIN_FILENO) dup2 (fd, STDIN_FILENO); 4002 if (fd != STDIN_FILENO) dup2 (fd, STDIN_FILENO);
3937 if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO); 4003 if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
3938 if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO); 4004 if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);
3974 4040
3975 case -1: /* Error in fork() */ 4041 case -1: /* Error in fork() */
3976 return (-1); /* Errno is set already */ 4042 return (-1); /* Errno is set already */
3977 4043
3978 case 0: /* Child process */ 4044 case 0: /* Child process */
3979 fd = sys_open("/dev/null", O_RDWR); 4045 fd = open ("/dev/null", O_RDWR);
3980 if (fd >= 0) 4046 if (fd >= 0)
3981 { 4047 {
3982 if (fd != STDIN_FILENO) dup2 (fd, STDIN_FILENO); 4048 if (fd != STDIN_FILENO) dup2 (fd, STDIN_FILENO);
3983 if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO); 4049 if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
3984 if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO); 4050 if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);