Mercurial > hg > xemacs-beta
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); |