1 /* -*-C-*-
2 
3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts
6     Institute of Technology
7 
8 This file is part of MIT/GNU Scheme.
9 
10 MIT/GNU Scheme is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or (at
13 your option) any later version.
14 
15 MIT/GNU Scheme is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with MIT/GNU Scheme; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23 USA.
24 
25 */
26 
27 /* Unix system include file */
28 
29 #ifndef SCM_UX_H
30 #define SCM_UX_H
31 
32 #define SYSTEM_NAME "unix"
33 
34 #ifdef __386BSD__
35 #  define SYSTEM_VARIANT "386BSD"
36 #endif
37 
38 #ifdef _AIX
39 #  define SYSTEM_VARIANT "AIX"
40 #endif
41 
42 #ifdef apollo
43 #  define SYSTEM_VARIANT "Domain"
44 #endif
45 
46 #ifdef __APPLE__
47 #  define SYSTEM_VARIANT "OS X"
48 #endif
49 
50 #ifdef __bsdi__			/* works on bsdi 3.0 */
51 #  define SYSTEM_VARIANT "BSDI BSD/OS"
52 #endif
53 
54 #ifdef __FreeBSD__
55 #  define SYSTEM_VARIANT "FreeBSD"
56 #endif
57 
58 #ifdef __DragonFly__
59 #  define SYSTEM_VARIANT "DragonFlyBSD"
60 #endif
61 
62 #if defined(__hpux) || defined(hpux)
63 #  define SYSTEM_VARIANT "HP/UX"
64 #endif
65 
66 #if defined(_IRIX) || defined(_IRIX4) || defined(_IRIX6)
67 #  define SYSTEM_VARIANT "Irix"
68 #endif
69 
70 #ifdef __linux__
71 #  define SYSTEM_VARIANT "GNU/Linux"
72 #endif
73 
74 #if defined(__netbsd__) || defined(__NetBSD__)
75 #  define SYSTEM_VARIANT "NetBSD"
76 #  include <sys/param.h>
77 #  if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 200000000
78 #    define HAVE_SIGACTION_SIGINFO_SIGNALS
79 #  endif
80 #endif
81 
82 #ifdef _NEXTOS
83 #  define SYSTEM_VARIANT "NeXT"
84 #endif
85 
86 #ifdef __OpenBSD__
87 #  define SYSTEM_VARIANT "OpenBSD"
88 #endif
89 
90 #ifdef __osf__
91 #  define SYSTEM_VARIANT "OSF"
92 #endif
93 
94 #ifdef _PIXEL
95 #  define SYSTEM_VARIANT "Pixel"
96 #endif
97 
98 #if defined(__sparc) && defined(__svr4__)
99 #  define SYSTEM_VARIANT "Solaris"
100 #endif
101 
102 #if defined(_SUNOS) || defined(_SUNOS3) || defined(_SUNOS4)
103 #  define SYSTEM_VARIANT "SunOS"
104 #endif
105 
106 #ifdef _ULTRIX
107 #  define SYSTEM_VARIANT "Ultrix"
108 #endif
109 
110 #ifndef SYSTEM_VARIANT
111 #  define SYSTEM_VARIANT "unknown"
112 #endif
113 
114 #include "config.h"
115 
116 #include <errno.h>
117 #include <grp.h>
118 #include <pwd.h>
119 #include <signal.h>
120 #include <sys/param.h>
121 #include <sys/stat.h>
122 #include <sys/times.h>
123 #include <sys/types.h>
124 
125 #ifdef HAVE_UNISTD_H
126 #  include <unistd.h>
127 #endif
128 
129 #ifdef HAVE_SYS_MMAN_H
130 #  include <sys/mman.h>
131 #endif
132 
133 /* On Mac OS X/i386, we instruct the linker to reserve all the usable
134    low virtual address space for us, so we can safely use
135    mmap(MAP_FIXED) to map the heap.  */
136 #if ((defined (__APPLE__)) && (defined (__IA32__)))
137 #  define USE_MAP_FIXED 1
138 #endif
139 
140 /* GNU C library defines environ if __USE_GNU is defined.  */
141 #ifndef __USE_GNU
142   extern char ** environ;
143 #endif
144 
145 #ifdef HAVE_SYS_FILE_H
146 #  include <sys/file.h>
147 #endif
148 
149 #ifdef HAVE_SYS_IOCTL_H
150 #  include <sys/ioctl.h>
151 #else
152    extern int ioctl (int, unsigned long, ...);
153 #endif
154 
155 #ifdef HAVE_FCNTL_H
156 #  include <fcntl.h>
157 #else
158    extern int open (const char *, int, ...);
159 #endif
160 
161 #ifdef HAVE_SYS_WAIT_H
162 #  include <sys/wait.h>
163 #else
164 #  ifndef WIFEXITED
165 #    define WIFEXITED(_X) (((_X) & 0x00FF) == 0)
166 #  endif
167 #  ifndef WIFSTOPPED
168 #    define WIFSTOPPED(_X) (((_X) & 0x00FF) == 0x007F)
169 #  endif
170 #  ifndef WIFSIGNALED
171 #    define WIFSIGNALED(_X)						\
172        ((((_X) & 0x00FF) != 0) && (((_X) & 0x00FF) != 0x007F))
173 #  endif
174 #  ifndef WEXITSTATUS
175 #    define WEXITSTATUS(_X) (((_X) & 0xFF00) >> 8)
176 #  endif
177 #  ifndef WTERMSIG
178 #    define WTERMSIG(_X) ((_X) & 0x007F)
179 #  endif
180 #  ifndef WSTOPSIG
181 #    define WSTOPSIG(_X) (((_X) & 0xFF00) >> 8)
182 #  endif
183    extern pid_t wait (int *);
184 #  ifdef HAVE_WAITPID
185      extern pid_t waitpid (pid_t, int *, int);
186 #  endif
187 #  ifdef HAVE_WAIT3
188      extern pid_t wait3 (int *, int, struct rusage *);
189 #  endif
190 #endif
191 
192 #ifndef WUNTRACED
193 #  define WUNTRACED 0
194 #endif
195 
196 #ifdef HAVE_DIRENT_H
197 #  include <dirent.h>
198 #  define NAMLEN(_D) (strlen ((_D) -> d_name))
199 #else
200 #  define dirent direct
201 #  define NAMLEN(_D) (strlen ((_D) -> d_namlen))
202 #  ifdef HAVE_SYS_NDIR_H
203 #    include <sys/ndir.h>
204 #  endif
205 #  ifdef HAVE_SYS_DIR_H
206 #    include <sys/dir.h>
207 #  endif
208 #  ifdef HAVE_NDIR_H
209 #    include <ndir.h>
210 #  endif
211 #endif
212 
213 #ifdef TIME_WITH_SYS_TIME
214 #  include <sys/time.h>
215 #  include <time.h>
216 #else
217 #  ifdef HAVE_SYS_TIME_H
218 #    include <sys/time.h>
219 #  else
220 #    include <time.h>
221 #  endif
222 #endif
223 
224 #ifdef HAVE_SYS_TIMEX_H
225 #  include <sys/timex.h>
226 #endif
227 
228 /* This detects both the NTP system calls found in BSD systems (NetBSD,
229    FreeBSD) and the NTP system calls found in Linux systems.  What is
230    found on other systems, I don't know.  We use this to get at the
231    system's record of the UTC - TAI offset.  */
232 
233 #ifdef HAVE_NTP_GETTIME
234 #ifdef HAVE_STRUCT_NTPTIMEVAL
235 #ifdef HAVE_NTPTIMEVAL_TAI
236 #ifdef HAVE_NTPTIMEVAL_TIME_TV_NSEC
237 #  define HAVE_BSD_NTP
238 #endif
239 #endif
240 #endif
241 #endif
242 
243 #ifdef HAVE_NTP_ADJTIME
244 #ifdef HAVE_STRUCT_TIMEX
245 #ifdef HAVE_TIMEX_TAI
246 #ifdef HAVE_TIMEX_TIME_TV_USEC
247 #  define HAVE_LINUX_NTP
248 #endif
249 #endif
250 #endif
251 #endif
252 
253 #ifdef HAVE_UTIME_H
254 #  include <utime.h>
255 #else
256    /* It's really there. */
257    struct utimbuf
258    {
259      time_t actime;
260      time_t modtime;
261    };
262    extern int utime (const char *, struct utimbuf *);
263 #endif
264 
265 #ifdef HAVE_TERMIOS_H
266 #  include <termios.h>
267 #else
268 #  ifdef HAVE_TERMIO_H
269 #    include <termio.h>
270 #  else
271 #    ifdef HAVE_SGTTY_H
272 #      include <sgtty.h>
273 #    endif
274 #  endif
275 #endif
276 
277 #ifdef HAVE_POLL_H
278 #  include <poll.h>
279 #endif
280 
281 #if defined(HAVE_SOCKET) && defined(HAVE_GETHOSTBYNAME) && defined(HAVE_GETHOSTNAME)
282 #  define HAVE_SOCKETS
283 #  include <sys/socket.h>
284 #  include <netinet/in.h>
285 #  include <netdb.h>
286 #  ifdef HAVE_SYS_UN_H
287 #    include <sys/un.h>
288 #    ifdef AF_UNIX
289 #      define HAVE_UNIX_SOCKETS
290 #    endif
291 #  endif
292 #endif
293 
294 #ifdef HAVE_SYS_PTYIO_H
295 #include <sys/ptyio.h>
296 #endif
297 
298 #ifdef HAVE_BSDTTY_H
299 #include <bsdtty.h>
300 #endif
301 
302 #ifdef HAVE_STROPTS_H
303 #include <stropts.h>
304 #endif
305 
306 #ifdef HAVE_UTIL_H
307 #  include <util.h>
308 #endif
309 
310 #include "intext.h"
311 #include "dstack.h"
312 #include "osscheme.h"
313 #include "syscall.h"
314 
315 typedef RETSIGTYPE Tsignal_handler_result;
316 
317 #ifdef _POSIX_REALTIME_SIGNALS
318 #  define HAVE_SIGACTION_SIGINFO_SIGNALS
319 #endif
320 
321 #ifdef HAVE_SIGACTION_SIGINFO_SIGNALS
322    typedef void (*Tsignal_handler) (int, siginfo_t *, void *);
323 #else
324    typedef RETSIGTYPE (*Tsignal_handler) (int);
325 #endif
326 
327 #ifdef VOID_SIGNAL_HANDLERS
328 #  define SIGNAL_HANDLER_RETURN() return
329 #else
330 #  define SIGNAL_HANDLER_RETURN() return (0)
331 #endif
332 
333 /* Crufty, but it will work here. */
334 #ifndef ENOSYS
335 #  define ENOSYS 0
336 #endif
337 
338 #ifndef SIG_ERR
339 #  define SIG_ERR ((Tsignal_handler) (-1))
340 #endif
341 
342 #if !defined(SIGCHLD) && defined(SIGCLD)
343 #  define SIGCHLD SIGCLD
344 #endif
345 #if !defined(SIGABRT) && defined(SIGIOT)
346 #  define SIGABRT SIGIOT
347 #endif
348 
349 /* Provide null defaults for all the signals we're likely to use so we
350    aren't continually testing to see if they're defined. */
351 
352 #ifndef SIGLOST
353 #  define SIGLOST 0
354 #endif
355 #ifndef SIGWINCH
356 #  define SIGWINCH 0
357 #endif
358 #ifndef SIGWINDOW
359 #  define SIGWINDOW 0
360 #endif
361 #ifndef SIGXCPU
362 #  define SIGXCPU 0
363 #endif
364 #ifndef SIGXFSZ
365 #  define SIGXFSZ 0
366 #endif
367 #ifndef SIGURG
368 #  define SIGURG 0
369 #endif
370 #ifndef SIGIO
371 #  define SIGIO 0
372 #endif
373 #ifndef SIGUSR1
374 #  define SIGUSR1 0
375 #endif
376 #ifndef SIGUSR2
377 #  define SIGUSR2 0
378 #endif
379 #ifndef SIGVTALRM
380 #  define SIGVTALRM 0
381 #endif
382 #ifndef SIGABRT
383 #  define SIGABRT 0
384 #endif
385 #ifndef SIGPWR
386 #  define SIGPWR 0
387 #endif
388 #ifndef SIGPROF
389 #  define SIGPROF 0
390 #endif
391 #ifndef SIGSTOP
392 #  define SIGSTOP 0
393 #endif
394 #ifndef SIGTSTP
395 #  define SIGTSTP 0
396 #endif
397 #ifndef SIGCONT
398 #  define SIGCONT 0
399 #endif
400 #ifndef SIGCHLD
401 #  define SIGCHLD 0
402 #endif
403 #ifndef SIGTTIN
404 #  define SIGTTIN 0
405 #endif
406 #ifndef SIGTTOU
407 #  define SIGTTOU 0
408 #endif
409 #ifndef SIGBUS
410 #  define SIGBUS 0
411 #endif
412 #ifndef SIGEMT
413 #  define SIGEMT 0
414 #endif
415 #ifndef SIGSYS
416 #  define SIGSYS 0
417 #endif
418 
419 /* constants for access() */
420 #ifndef R_OK
421 #  define R_OK 4
422 #  define W_OK 2
423 #  define X_OK 1
424 #  define F_OK 0
425 #endif
426 
427 #ifndef MAXPATHLEN
428 #  define MAXPATHLEN 1024
429 #endif
430 
431 #ifdef HAVE_C_BACKSLASH_A
432 #  define ALERT_CHAR '\a'
433 #  define ALERT_STRING "\a"
434 #else
435 #  define ALERT_CHAR '\007'
436 #  define ALERT_STRING "\007"
437 #endif
438 
439 #ifndef STDIN_FILENO
440 #  define STDIN_FILENO 0
441 #  define STDOUT_FILENO 1
442 #  define STDERR_FILENO 2
443 #endif
444 
445 /* constants for open() and fcntl() */
446 #ifndef O_RDONLY
447 #  define O_RDONLY 0
448 #  define O_WRONLY 1
449 #  define O_RDWR 2
450 #endif
451 
452 /* mode bit definitions for open(), creat(), and chmod() */
453 #ifndef S_IRWXU
454 #  define S_IRWXU 0700
455 #  define S_IRWXG 0070
456 #  define S_IRWXO 0007
457 #endif
458 
459 #ifndef S_IRUSR
460 #  define S_IRUSR 0400
461 #  define S_IWUSR 0200
462 #  define S_IXUSR 0100
463 #  define S_IRGRP 0040
464 #  define S_IWGRP 0020
465 #  define S_IXGRP 0010
466 #  define S_IROTH 0004
467 #  define S_IWOTH 0002
468 #  define S_IXOTH 0001
469 #endif
470 
471 #define MODE_REG (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
472 #define MODE_DIR (MODE_REG | S_IXUSR | S_IXGRP | S_IXOTH)
473 
474 /* constants for lseek() */
475 #ifndef SEEK_SET
476 #  define SEEK_SET 0
477 #  define SEEK_CUR 1
478 #  define SEEK_END 2
479 #endif
480 
481 #ifdef HAVE_GETLOGIN
482 #  ifndef HAVE_UNISTD_H
483      extern char * getlogin (void);
484 #  endif
485 #endif
486 
487 #ifndef STDC_HEADERS
488 #  ifndef HAVE_MALLOC_H
489      extern void * malloc (size_t);
490      extern void * realloc (void *, size_t);
491 #  endif
492    extern char * getenv (const char *);
493 #endif
494 
495 #define UX_abort abort
496 #define UX_accept accept
497 #define UX_access access
498 #define UX_alarm alarm
499 #define UX_bind bind
500 #define UX_chdir chdir
501 #define UX_chmod chmod
502 #define UX_clock_gettime clock_gettime
503 #define UX_close close
504 #define UX_connect connect
505 #define UX_ctime ctime
506 #define UX_dup dup
507 #define UX_fcntl fcntl
508 #define UX_fdatasync fdatasync
509 #define UX_free free
510 #define UX_fstat fstat
511 #define UX_fstatfs fstatfs
512 #define UX_fsync fsync
513 #define UX_fsync_range fsync_range
514 #define UX_ftruncate ftruncate
515 #define UX_getegid getegid
516 #define UX_getenv getenv
517 #define UX_geteuid geteuid
518 #define UX_getgid getgid
519 #define UX_getgrgid getgrgid
520 #define UX_gethostbyname gethostbyname
521 #define UX_gethostname gethostname
522 #define UX_getlogin getlogin
523 #define UX_getpid getpid
524 #define UX_getpwnam getpwnam
525 #define UX_getpwuid getpwuid
526 #define UX_getservbyname getservbyname
527 #define UX_gettimeofday gettimeofday
528 #define UX_getuid getuid
529 #define UX_gmtime gmtime
530 #define UX_ioctl ioctl
531 #define UX_link link
532 #define UX_listen listen
533 #define UX_localtime localtime
534 #define UX_lseek lseek
535 #define UX_malloc malloc
536 #define UX_mknod mknod
537 #define UX_mktime mktime
538 #define UX_ntp_adjtime ntp_adjtime
539 #define UX_ntp_gettime ntp_gettime
540 #define UX_open open
541 #define UX_pause pause
542 #define UX_pipe pipe
543 #define UX_poll poll
544 #define UX_pselect pselect
545 #define UX_read read
546 #define UX_readlink readlink
547 #define UX_realloc realloc
548 #define UX_rmdir rmdir
549 #define UX_select select
550 #define UX_setitimer setitimer
551 #define UX_signal signal
552 #define UX_sleep sleep
553 #define UX_socket socket
554 #define UX_stat stat
555 #define UX_statfs statfs
556 #define UX_symlink symlink
557 #define UX_sync_file_range sync_file_range
558 #define UX_system system
559 #define UX_time time
560 #define UX_times times
561 #define UX_truncate truncate
562 #define UX_unlink unlink
563 #define UX_utime utime
564 #define UX_vfork vfork
565 #define UX_wait wait
566 #define UX_write write
567 
568 #ifdef HAVE_SYMLINK
569 #define UX_lstat lstat
570 #else
571 #define UX_lstat stat
572 #endif
573 
574 #ifdef HAVE_DUP2
575 #  define UX_dup2 dup2
576 #else
577 #  ifdef HAVE_FCNTL
578    extern int UX_dup2 (int, int);
579 #  define EMULATE_DUP2
580 #  define HAVE_DUP2
581 #  endif
582 #endif
583 
584 #ifdef HAVE_GETCWD
585 #  define UX_getcwd getcwd
586 #else
587    extern char * UX_getcwd (char *, size_t);
588 #  define EMULATE_GETCWD
589 #  define HAVE_GETCWD
590 #endif
591 
592 #ifdef HAVE_MKDIR
593 #  define UX_mkdir mkdir
594 #else
595    extern int UX_mkdir (const char *, mode_t);
596 #  define EMULATE_MKDIR
597 #  define HAVE_MKDIR
598 #endif
599 
600 #ifdef HAVE_RENAME
601 #  define UX_rename rename
602 #else
603    extern int UX_rename (const char *, const char *);
604 #  define EMULATE_RENAME
605 #  define HAVE_RENAME
606 #endif
607 
608 #ifdef HAVE_WAITPID
609 #  define UX_waitpid waitpid
610 #else
611 #  ifdef HAVE_WAIT3
612    extern int UX_waitpid (pid_t, int *, int);
613 #  define EMULATE_WAITPID
614 #  define HAVE_WAITPID
615 #  endif
616 #endif
617 
618 #ifdef HAVE_CTERMID
619 #  define UX_ctermid ctermid
620 #else
621    extern char * UX_ctermid (char * s);
622 #  define EMULATE_CTERMID
623 #endif
624 
625 #ifdef HAVE_KILL
626 #  define UX_kill kill
627 #else
628    extern int UX_kill (pid_t pid, int sig);
629 #  define EMULATE_KILL
630 #endif
631 
632 #ifdef HAVE_GETPAGESIZE
633 #  define UX_getpagesize getpagesize
634 #else
635    extern unsigned long UX_getpagesize (void);
636 #  define EMULATE_GETPAGESIZE
637 #endif
638 
639 #ifdef HAVE_CLOSEFROM
640 #  define UX_closefrom closefrom
641 #else
642    extern int UX_closefrom (int);
643 #  define EMULATE_CLOSEFROM
644 #endif
645 
646 /* poll is somewhat busted on Mac OSX 10.4 (Tiger), so use select.  */
647 #ifdef __APPLE__
648 #  undef HAVE_POLL
649 #endif
650 
651 #ifdef HAVE_POLL
652 #  ifndef INFTIM
653 #    define INFTIM (-1)
654 #  endif
655 #else
656 #  ifdef FD_SET
657 #    define SELECT_TYPE fd_set
658 #  else
659 #    define SELECT_TYPE int
660 #    define FD_SETSIZE ((sizeof (int)) * CHAR_BIT)
661 #    define FD_SET(n, p) ((*(p)) |= (1 << (n)))
662 #    define FD_CLR(n, p) ((*(p)) &= ~(1 << (n)))
663 #    define FD_ISSET(n, p) (((*(p)) & (1 << (n))) != 0)
664 #    define FD_ZERO(p) ((*(p)) = 0)
665 #  endif
666 #endif
667 
668 /* ppoll is Linux's newer name for what was called pollts on BSD.  */
669 
670 #ifdef HAVE_PPOLL
671 #  define UX_ppoll ppoll
672 #else
673 #  ifdef HAVE_POLLTS
674 #    define HAVE_PPOLL
675 #    define UX_ppoll pollts
676 #  endif
677 #endif
678 
679 #ifdef _POSIX_VERSION
680 #  define ERRNO_NONBLOCK EAGAIN
681 #  define FCNTL_NONBLOCK O_NONBLOCK
682 #else
683 #  ifdef EWOULDBLOCK
684 #    define ERRNO_NONBLOCK EWOULDBLOCK
685 #    define FCNTL_NONBLOCK FNDELAY
686 #  else
687 #    define AMBIGUOUS_NONBLOCK
688 #    ifdef EAGAIN
689 #      define ERRNO_NONBLOCK EAGAIN
690 #    endif
691 #    define FCNTL_NONBLOCK O_NDELAY
692 #  endif
693 #endif
694 
695 #if defined(HAVE_GRANTPT) && defined(HAVE_STROPTS_H) && !defined(__osf__) && !defined(__linux__)
696    /* Must push various STREAMS modules onto the slave side of a PTY
697       when it is opened.  */
698 #  define SLAVE_PTY_P(filename) ((strncmp ((filename), "/dev/pts/", 9)) == 0)
699    extern int UX_setup_slave_pty (int);
700 #  define SETUP_SLAVE_PTY UX_setup_slave_pty
701 #endif
702 
703 #ifndef TIOCSIGSEND
704 #  ifdef TIOCSIGNAL
705 #    define TIOCSIGSEND TIOCSIGNAL
706 #  else
707 #    ifdef TIOCSIG
708 #      define TIOCSIGSEND TIOCSIG
709 #    endif
710 #  endif
711 #endif
712 
713 #ifdef HAVE_TERMIOS_H
714 
715 typedef struct
716 {
717   struct termios tio;
718 #ifdef HAVE_STRUCT_LTCHARS
719   struct ltchars ltc;
720 #endif
721 } Ttty_state;
722 
723 #define UX_tcflush tcflush
724 #define UX_tcdrain tcdrain
725 #define UX_tcgetattr tcgetattr
726 #define UX_tcsetattr tcsetattr
727 
728 #else /* not HAVE_TERMIOS_H */
729 
730 extern int UX_tcdrain (int);
731 extern int UX_tcflush (int, int);
732 /* These values chosen to match the ioctl TCFLSH argument for termio. */
733 #define TCIFLUSH 0
734 #define TCOFLUSH 1
735 #define TCIOFLUSH 2
736 
737 #ifdef HAVE_TERMIO_H
738 
739 typedef struct
740 {
741   struct termio tio;
742 #ifdef HAVE_STRUCT_LTCHARS
743   struct ltchars ltc;
744 #endif
745 } Ttty_state;
746 
747 #else /* not HAVE_TERMIO_H */
748 #ifdef HAVE_SGTTY_H
749 
750 typedef struct
751 {
752   struct sgttyb sg;
753   struct tchars tc;
754 #ifdef HAVE_STRUCT_LTCHARS
755   struct ltchars ltc;
756 #endif
757   int lmode;
758 } Ttty_state;
759 
760 #endif /* not HAVE_SGTTY_H */
761 #endif /* not HAVE_TERMIO_H */
762 #endif /* not HAVE_TERMIOS_H */
763 
764 extern int UX_terminal_get_state (int, Ttty_state *);
765 extern int UX_terminal_set_state (int, Ttty_state *);
766 
767 #ifdef _POSIX_VERSION
768 #  define UX_getpgrp getpgrp
769 #  define UX_setsid setsid
770 #  define UX_setpgid setpgid
771 #  define UX_tcgetpgrp tcgetpgrp
772 #  define UX_tcsetpgrp tcsetpgrp
773 #else
774 #  if defined(HAVE_GETPGRP) && defined(HAVE_SETPGRP)
775 #    ifdef GETPGRP_VOID
776 #      define UX_getpgrp getpgrp
777 #    else
778        extern pid_t UX_getpgrp (void);
779 #      define EMULATE_GETPGRP
780 #    endif
781 #    ifdef SETPGRP_VOID
782 #      define UX_setsid setpgrp
783 #    else
784 	 extern pid_t UX_setsid (void);
785 #	 define EMULATE_SETSID
786 #    endif
787 #    ifdef HAVE_SETPGRP2
788 #      define UX_setpgid setpgrp2
789 #    else
790 #      ifdef SETPGRP_VOID
791 	 extern int UX_setpgid (pid_t, pid_t);
792 #	 define EMULATE_SETPGID
793 #      else
794 #	define UX_setpgid setpgrp
795 #      endif
796 #    endif
797 #  endif
798    extern pid_t UX_tcgetpgrp (int);
799 #  define EMULATE_TCGETPGRP
800    extern int UX_tcsetpgrp (int, pid_t);
801 #  define EMULATE_TCSETPGRP
802 #endif
803 
804 #ifdef __APPLE__
805    /* In Darwin, setsid doesn't work in vforked processes, so force
806       the use of fork instead. */
807 #  undef UX_vfork
808 #  define UX_vfork fork
809    /* Also, although OS X binds the symbol fdatasync in the C library,
810       there's no header file or man page, and the system call appears
811       to have a different argument structure.  */
812 #  undef HAVE_FDATASYNC
813 #  undef UX_fdatasync
814 #endif
815 
816 #ifdef HAVE_SIGACTION
817 
818 #define UX_sigemptyset sigemptyset
819 #define UX_sigfillset sigfillset
820 #define UX_sigaddset sigaddset
821 #define UX_sigdelset sigdelset
822 #define UX_sigismember sigismember
823 #define UX_sigaction sigaction
824 #define UX_sigsuspend sigsuspend
825 #define UX_sigprocmask sigprocmask
826 #define HAVE_POSIX_SIGNALS
827 
828 #else /* not HAVE_SIGACTION */
829 
830 typedef long sigset_t;
831 extern int UX_sigemptyset (sigset_t *);
832 extern int UX_sigfillset (sigset_t *);
833 extern int UX_sigaddset (sigset_t *, int);
834 extern int UX_sigdelset (sigset_t *, int);
835 extern int UX_sigismember (const sigset_t *, int);
836 
837 #ifdef HAVE_SIGVEC
838 #  define UX_sigvec sigvec
839 #else
840 #  ifdef HAVE_SIGVECTOR
841 #    define UX_sigvec sigvector
842 #    define HAVE_SIGVEC
843 #  endif
844 #endif
845 
846 #ifdef HAVE_SIGVEC
847 
848 struct sigaction
849 {
850   Tsignal_handler sa_handler;
851   sigset_t sa_mask;
852   int sa_flags;
853 };
854 
855 extern int UX_sigaction (int, const struct sigaction *, struct sigaction *);
856 extern int UX_sigprocmask (int, const sigset_t *, sigset_t *);
857 extern int UX_sigsuspend (const sigset_t *);
858 #define SIG_BLOCK 0
859 #define SIG_UNBLOCK 1
860 #define SIG_SETMASK 2
861 
862 #define HAVE_POSIX_SIGNALS
863 
864 #else /* not HAVE_SIGVEC */
865 #ifdef HAVE_SIGHOLD
866 
867 #define UX_sigset sigset
868 #define UX_sighold sighold
869 #define UX_sigrelse sigrelse
870 
871 #endif /* HAVE_SIGHOLD */
872 #endif /* HAVE_SIGVEC */
873 #endif /* HAVE_SIGACTION */
874 
875 #ifdef _POSIX_VERSION
876 
877 #  ifndef HAVE_FPATHCONF
878      extern long fpathconf (int, int);
879 #    define EMULATE_FPATHCONF
880 #  endif
881 
882 #  ifndef HAVE_SYSCONF
883      extern long sysconf (int);
884 #    define EMULATE_SYSCONF
885 #  endif
886 
887    extern cc_t UX_PC_VDISABLE (int fildes);
888    extern clock_t UX_SC_CLK_TCK (void);
889 #  define UX_SC_OPEN_MAX() ((size_t) (sysconf (_SC_OPEN_MAX)))
890 
891 #  ifdef _POSIX_JOB_CONTROL
892 #    define UX_SC_JOB_CONTROL() 1
893 #  else
894 #    define UX_SC_JOB_CONTROL() ((sysconf (_SC_JOB_CONTROL)) >= 0)
895 #  endif
896 
897 #else /* not _POSIX_VERSION */
898 
899 #  define UX_PC_VDISABLE(fildes) '\377'
900 
901 #  ifdef OPEN_MAX
902 #    define UX_SC_OPEN_MAX() OPEN_MAX
903 #  else
904 #    ifdef _NFILE
905 #      define UX_SC_OPEN_MAX() _NFILE
906 #    else
907 #      define UX_SC_OPEN_MAX() 16
908 #    endif
909 #  endif
910 
911 #  ifdef CLK_TCK
912 #    define UX_SC_CLK_TCK() CLK_TCK
913 #  else
914 #    ifdef HZ
915 #      define UX_SC_CLK_TCK() HZ
916 #    else
917 #      define UX_SC_CLK_TCK() 60
918 #    endif
919 #  endif
920 
921 #  ifdef TIOCGPGRP
922 #    define UX_SC_JOB_CONTROL() 1
923 #  else
924 #    define UX_SC_JOB_CONTROL() 0
925 #  endif
926 
927 #endif /* not _POSIX_VERSION */
928 
929 extern void UX_prim_check_errno (enum syscall_names name);
930 extern void UX_prim_check_fd_errno (enum syscall_names name);
931 extern bool UX_out_of_files_p;
932 
933 #define STD_VOID_SYSTEM_CALL(name, expression)	\
934   do {						\
935     while ((expression) < 0)			\
936       UX_prim_check_errno (name);		\
937   } while (0)
938 
939 #define STD_UINT_SYSTEM_CALL(name, result, expression)	\
940   do {							\
941     while (((result) = (expression)) < 0)		\
942       UX_prim_check_errno (name);			\
943   } while (0)
944 
945 #define STD_PTR_SYSTEM_CALL(name, result, expression)	\
946   do {							\
947     while (((result) = (expression)) == 0)		\
948       UX_prim_check_errno (name);			\
949   } while (0)
950 
951 #define STD_FD_SYSTEM_CALL(name, result, expression)	\
952   do {							\
953     while (((result) = (expression)) < 0)		\
954       UX_prim_check_fd_errno (name);			\
955     UX_out_of_files_p = false;				\
956   } while (0)
957 
958 #define STD_FD_VOID_SYSTEM_CALL(name, expression)	\
959   do {							\
960     while ((expression) < 0)				\
961       UX_prim_check_fd_errno (name);			\
962     UX_out_of_files_p = false;				\
963   } while (0)
964 
965 #endif /* SCM_UX_H */
966