home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / unix.d < prev    next >
Encoding:
Text File  |  1994-12-29  |  28.9 KB  |  779 lines

  1. # Include-File fⁿr UNIX-Version von CLISP
  2. # Bruno Haible 29.12.1994
  3.  
  4.  
  5. # Konstanten fⁿr Steuerzeichen:
  6.  
  7. #define BEL  7              # Ton ausgeben
  8. # define NL  10             # New line, siehe LISPBIBL.D
  9. #define RUBOUT 127          # Rubout = Delete
  10. #define CRLFstring  "\n"    # C-String, der BS-Newline enthΣlt
  11.  
  12. #define stdin_handle   0  # File-Handle von Standard-Input
  13. #define stdout_handle  1  # File-Handle von Standard-Output
  14.  
  15. # Deklaration von Typen von Ein-/Ausgabe-Parametern von Betriebssystemfunktionen
  16.   #ifdef STDC_HEADERS
  17.     #include <stdlib.h>
  18.   #endif
  19.   #ifdef HAVE_UNISTD_H
  20.     #include <sys/types.h>
  21.     #include <unistd.h>
  22.   #endif
  23.  
  24. # Tabelle der System-Fehlermeldungen
  25.   #include <errno.h>
  26.   extern int errno; # letzter Fehlercode
  27.   extern int sys_nerr; # Anzahl der Betriebssystem-Fehlermeldungen
  28.   extern SYS_ERRLIST_CONST char* SYS_ERRLIST_CONST sys_errlist[]; # Betriebssystem-Fehlermeldungen
  29.   # siehe PERROR(3)
  30. # wird verwendet von ERROR, SPVW, STREAM, PATHNAME
  31.  
  32. # Bereitstellen des Arbeitsspeichers
  33.   #ifdef HAVE_GETPAGESIZE
  34.     extern RETGETPAGESIZETYPE getpagesize (void); # siehe GETPAGESIZE(2)
  35.   #endif
  36.   #ifndef malloc
  37.     extern RETMALLOCTYPE malloc (MALLOC_SIZE_T size); # siehe MALLOC(3V)
  38.   #endif
  39.   #ifndef free
  40.     extern RETFREETYPE free (RETMALLOCTYPE ptr); # siehe MALLOC(3V)
  41.   #endif
  42.   #ifndef realloc
  43.     extern RETMALLOCTYPE realloc (RETMALLOCTYPE ptr, MALLOC_SIZE_T size); # siehe REALLOC(3)
  44.   #endif
  45.   #ifdef UNIX_NEXTSTEP
  46.     # Ignoriere den Inhalt von libposix.a, da er nicht dokumentiert ist:
  47.     #undef HAVE_MMAP
  48.     #undef HAVE_MUNMAP
  49.     #undef MMAP_ADDR_T
  50.     #undef MMAP_SIZE_T
  51.     #undef RETMMAPTYPE
  52.   #endif
  53.   #ifdef HAVE_MMAP
  54.     #include <sys/types.h>
  55.     #include <sys/mman.h>
  56.     #ifdef UNIX_CONVEX
  57.       #define mmap fixed_mmap  # Unter UNIX_CONVEX ist das Interface von mmap() kaputt.
  58.       #define HAVE_WORKING_MPROTECT  # Das eigene mprotect() in unixaux.d reicht aus.
  59.     #endif
  60.     #if defined(HAVE_MMAP_ANONYMOUS) && !defined(HAVE_MMAP_ANON)
  61.       # HP-UX verwendet MAP_ANONYMOUS statt MAP_ANON.
  62.       #define MAP_ANON MAP_ANONYMOUS
  63.       #define HAVE_MMAP_ANON
  64.     #endif
  65.     #if defined(UNIX_SUNOS4) || defined(UNIX_SUNOS5)
  66.       # Fⁿr SINGLEMAP_MEMORY:
  67.         #if defined(HAVE_MMAP_DEVZERO_SUN4_29) && defined(SUN4_29) && !defined(HAVE_MMAP_DEVZERO)
  68.           # Unter Annahme der SUN4_29-Typcodeverteilung ist
  69.           # HAVE_MMAP_DEVZERO_SUN4_29 ein hinreichender Ersatz fⁿr HAVE_MMAP_DEVZERO.
  70.           #define HAVE_MMAP_DEVZERO
  71.         #endif
  72.     #endif
  73.     #ifdef UNIX_SUNOS4
  74.       # NB: Unter UNIX_SUNOS4 ist nicht HAVE_MMAP_ANON, nur HAVE_MMAP_DEVZERO
  75.       # definiert. Ersteres, weil es MAP_ANON nicht gibt; letzteres, weil
  76.       # das Testprogramm Adressen bis 0x4000000 belegt (SUN4_29 aber nur
  77.       # Adressen bis 0x2000000 verkraftet - daher der spezielle Test
  78.       # HAVE_MMAP_DEVZERO_SUN4_29). Au▀erdem besteht ein Limit von 20 MB
  79.       # mmap()-Speicher (danach kommt ENOMEM).
  80.       # Wir k÷nnen wahlweise MULTIMAP_MEMORY oder SINGLEMAP_MEMORY verwenden.
  81.       # Fⁿr MULTIMAP_MEMORY:
  82.         #include <sys/vfs.h>
  83.         extern int fstatfs (int fd, struct statfs * buf); # siehe STATFS(2)
  84.     #endif
  85.     #ifdef UNIX_SUNOS5
  86.       # NB: Unter UNIX_SUNOS5 sollte HAVE_MMAP_DEVZERO definiert sein.
  87.       # Dabei gibt es allerdings ein Limit von 25 MB mmap()-Speicher.
  88.       # Da die Shared-Memory-Facility von UNIX_SUNOS5 sich weigert,
  89.       # Speicher an Adressen >= 0x06000000 oder mehr als 6 Mal zu attachen,
  90.       # mⁿssen wir SINGLEMAP_MEMORY verwenden.
  91.     #endif
  92.   #endif
  93.   #ifdef HAVE_MACH_VM # Funktionen vm_allocate(), task_self(), ... vorhanden
  94.     # Die Header-Files von UNIX_NEXTSTEP mⁿssen ja unbeschreiblich aussehen...
  95.     #include <sys/resource.h>
  96.     #undef local
  97.     #include <mach/mach_interface.h>
  98.     #ifdef UNIX_NEXTSTEP
  99.       #include <mach/mach_init.h>
  100.     #endif
  101.     #ifdef UNIX_OSF
  102.       #include <mach_init.h>
  103.     #endif
  104.     # include <mach/mach.h>
  105.     #include <mach/mach_traps.h> # fⁿr map_fd()
  106.     #include <mach/machine/vm_param.h>
  107.     #define local static
  108.     # Damit kann man mmap(), munmap() und mprotect() selber schreiben. Siehe spvw.d.
  109.     #define HAVE_MMAP
  110.     #define HAVE_MUNMAP
  111.     #define HAVE_WORKING_MPROTECT
  112.     #define MMAP_ADDR_T  vm_address_t
  113.     #define MMAP_SIZE_T  vm_size_t
  114.     #define RETMMAPTYPE  MMAP_ADDR_T
  115.     #define MPROTECT_CONST
  116.     #define PROT_NONE  0
  117.     #define PROT_READ  VM_PROT_READ
  118.     #define PROT_WRITE VM_PROT_WRITE
  119.     #define PROT_EXEC  VM_PROT_EXECUTE
  120.   #endif
  121.   #ifdef HAVE_MMAP
  122.     extern RETMMAPTYPE mmap (MMAP_ADDR_T addr, MMAP_SIZE_T len, int prot, int flags, int fd, off_t off); # siehe MMAP(2)
  123.   #endif
  124.   #ifdef HAVE_MUNMAP
  125.     extern int munmap (MMAP_ADDR_T addr, MMAP_SIZE_T len); # siehe MUNMAP(2)
  126.   #endif
  127.   #ifdef HAVE_WORKING_MPROTECT
  128.     extern int mprotect (MPROTECT_CONST MMAP_ADDR_T addr, MMAP_SIZE_T len, int prot); # siehe MPROTECT(2)
  129.     # M÷gliche Werte von prot: PROT_NONE, PROT_READ, PROT_READ_WRITE.
  130.     #define PROT_READ_WRITE  (PROT_READ | PROT_WRITE)
  131.   #endif
  132.   #ifdef HAVE_SHM
  133.     #include <sys/types.h>
  134.     #include <sys/ipc.h>
  135.     #include <sys/shm.h>
  136.     #ifdef HAVE_SYS_SYSMACROS_H
  137.       #include <sys/sysmacros.h>
  138.     #endif
  139.     #ifdef UNIX_HPUX
  140.       #include <sys/vmmac.h> # fⁿr SHMLBA
  141.     #endif
  142.     #ifdef UNIX_AUX
  143.       #include <sys/mmu.h> # fⁿr SHMLBA
  144.     #endif
  145.     #ifdef UNIX_LINUX
  146.       #if !(SHMLBA==4096) # Linux 0.99.12 is broken
  147.         #undef SHMLBA
  148.         #undef SHMMAX
  149.         #define SHMLBA 0x1000
  150.         #define SHMMAX 0x400000
  151.       #endif
  152.     #endif
  153.     #if defined(UNIX_SUNOS4) || defined(UNIX_SUNOS5)
  154.       #define SHMMAX  0x100000 # maximale Shared-Memory-Segment-Gr÷▀e = 1 MB
  155.     #endif
  156.     #ifndef SHMMAX
  157.       #define SHMMAX  0xFFFFFFFFUL # maximale Shared-Memory-Segment-Gr÷▀e wird als unendlich angenommen
  158.     #endif
  159.     extern int shmget (key_t key, SHMGET_SIZE_T size, int shmflg); # siehe SHMGET(2)
  160.     extern RETSHMATTYPE shmat (int shmid, SHMAT_CONST RETSHMATTYPE shmaddr, int shmflg); # siehe SHMOP(2)
  161.     extern int shmdt (SHMAT_CONST RETSHMATTYPE shmaddr); # siehe SHMOP(2)
  162.     #ifdef SHMCTL_DOTS
  163.       extern int shmctl (int shmid, int cmd, ...); # siehe SHMCTL(2)
  164.     #else
  165.       extern int shmctl (int shmid, int cmd, struct shmid_ds * buf); # siehe SHMCTL(2)
  166.     #endif
  167.   #endif
  168. # wird verwendet von SPVW, STREAM
  169.  
  170. # Steuerung der Pagingverhaltens
  171.   #ifdef HAVE_VADVISE
  172.     #include <sys/vadvise.h> # Steuercodes
  173.     extern void vadvise (int param); # Paging-System steuern # siehe VADVISE(2)
  174.   #endif
  175.   # madvise() verwenden??
  176. # wird verwendet von SPVW
  177.  
  178. # Normales Programmende
  179.   nonreturning_function(extern, _exit, (int status)); # siehe EXIT(2V)
  180. # wird verwendet von SPVW, PATHNAME, STREAM
  181.  
  182. # Sofortiger Programmabbruch, Sprung in den Debugger
  183.   extern ABORT_VOLATILE RETABORTTYPE abort (void); # siehe ABORT(3)
  184. # wird verwendet von SPVW, DEBUG, EVAL, IO
  185.  
  186. # Signalbehandlung
  187.   #include <signal.h>
  188.   # Ein Signal-Handler ist eine Funktion ohne Ergebnis.
  189.   typedef RETSIGTYPE (*signal_handler) ();
  190.   extern signal_handler signal (int sig, signal_handler handler); # siehe SIGNAL(3V)
  191.   # Ein Signal blockieren und wieder freigeben:
  192.   #if defined(SIGNALBLOCK_POSIX)
  193.     extern int sigprocmask (int how, SIGPROCMASK_CONST sigset_t* set, sigset_t* oset); # siehe SIGPROCMASK(2V)
  194.     #ifndef sigemptyset # UNIX_LINUX definiert dies manchmal als Macro
  195.       extern int sigemptyset (sigset_t* set); # siehe SIGSETOPS(3V)
  196.     #endif
  197.     #ifndef sigaddset # UNIX_LINUX definiert dies manchmal als Macro
  198.       extern int sigaddset (sigset_t* set, int signo); # siehe SIGSETOPS(3V)
  199.     #endif
  200.     #define signalblock_on(sig)  \
  201.       { var sigset_t sigblock_mask;                                 \
  202.         sigemptyset(&sigblock_mask); sigaddset(&sigblock_mask,sig); \
  203.         sigprocmask(SIG_BLOCK,&sigblock_mask,NULL);
  204.     #define signalblock_off(sig)  \
  205.         sigprocmask(SIG_UNBLOCK,&sigblock_mask,NULL); \
  206.       }
  207.   #elif defined(SIGNALBLOCK_SYSV)
  208.     extern int sighold (int sig);
  209.     extern int sigrelse (int sig);
  210.     #define signalblock_on(sig)  sighold(sig);
  211.     #define signalblock_off(sig)  sigrelse(sig);
  212.   #elif defined(SIGNALBLOCK_BSD)
  213.     extern int sigblock (int mask); # siehe SIGBLOCK(2)
  214.     extern int sigsetmask (int mask); # siehe SIGSETMASK(2)
  215.     #define signalblock_on(sig)  \
  216.       { var int old_sigblock_mask = sigblock(sigmask(sig));
  217.     #define signalblock_off(sig)  \
  218.         sigsetmask(old_sigblock_mask); \
  219.       }
  220.   #else
  221.     #error "Wie blockiert man Signale?"
  222.   #endif
  223.   # Ein Signal erst eine bestimmte Zeit spΣter ausliefern:
  224.   # extern {unsigned|} int alarm ({unsigned|} int seconds); # siehe ALARM(3V)
  225.   #if !defined(HAVE_UALARM) && defined(HAVE_SETITIMER)
  226.     #define NEED_OWN_UALARM # mit setitimer() kann man ualarm() selber schreiben
  227.     #include <sys/time.h>
  228.     extern int setitimer (int which, SETITIMER_CONST struct itimerval * ivalue, struct itimerval * ovalue); # siehe SETITIMER(2)
  229.     #define HAVE_UALARM
  230.   #endif
  231.   #ifdef HAVE_UALARM
  232.     extern unsigned int ualarm (unsigned int value, unsigned int interval); # siehe UALARM(3)
  233.   #endif
  234.   # Die Ankunft eines Signals quittieren (aus dem Signal-Handler heraus):
  235.   #ifdef SIGNAL_NEED_REINSTALL # UNIX_SYSV || UNIX_LINUX || ...
  236.     #define signal_acknowledge(sig,handler)  nowarn signal(sig,handler) # Handler bleibt weiter aktiv
  237.   #else # Signalverwaltung nach BSD hat das nicht n÷tig
  238.     #define signal_acknowledge(sig,handler)
  239.   #endif
  240.   # Das Signal, das man bekommt, wenn ein Tochterproze▀ beendet wird: SIGCLD
  241.   #if defined(SIGCHLD) && !defined(SIGCLD)
  242.     #define SIGCLD  SIGCHLD
  243.   #endif
  244.   # Das Verhalten von Signalen bei System-Calls beeinflussen:
  245.   # flag=0: Nach Signal sig laufen System-Calls weiter.
  246.   # flag=1: Durch Signal sig werden System-Calls abgebrochen, mit errno=EINTR.
  247.   #ifdef EINTR
  248.     extern int siginterrupt (int sig, int flag); # siehe SIGINTERRUPT(3V)
  249.     #define SIGNAL(sig,handler)  nowarn signal(sig,handler), siginterrupt(sig,0)
  250.     #ifndef HAVE_SIGINTERRUPT
  251.       # mit sigaction() oder sigvec() kann man siginterrupt() selber schreiben
  252.       #define NEED_OWN_SIGINTERRUPT
  253.     #endif
  254.   #else
  255.     #define siginterrupt(sig,flag)
  256.     #define SIGNAL(sig,handler)  nowarn signal(sig,handler)
  257.   #endif
  258.   # Zur Behebung von SIGSEGV-Signalen nach Schreibzugriff auf
  259.   # schreibgeschⁿtzte Bereiche. Siehe unix/sigsegv.c.
  260.   # Obacht: Hans-J. Boehm <boehm@parc.xerox.com> sagt, da▀ Schreibzugriffe
  261.   # aus Betriebssystem-Aufrufen heraus (z.B. read()) auf vielen Systemen
  262.   # wider Erwarten kein Signal ausl÷sen. (Unter Linux funktioniert's.)
  263.   #ifndef SPVW_MIXED_BLOCKS
  264.   # Wir haben das Glⁿck, mit read() nur in den C-Stack und in Strings zu
  265.   # schreiben, nicht jedoch in eventuell mprotect-geschⁿtzte Bereiche.
  266.   #endif
  267.   #if defined(I80Z86) && defined(UNIX_LINUX)
  268.     #define FAULT_HANDLER_ARGLIST  sig, more
  269.     #define FAULT_HANDLER_ARGDECL  int sig; unsigned long more;
  270.     #define FAULT_ADDRESS  ((unsigned long *) &more) [21]
  271.     #define WP_SIGNAL  FAULT_HANDLER(SIGSEGV)
  272.     #define CAN_HANDLE_WP_FAULT
  273.   #endif
  274.   #if defined(UNIX_SUNOS4)
  275.     #define FAULT_HANDLER_ARGLIST  sig, code, scp, addr
  276.     #define FAULT_HANDLER_ARGDECL  int sig; int code; void* scp; char* addr;
  277.     #define FAULT_ADDRESS  addr
  278.     #define WP_SIGNAL  FAULT_HANDLER(SIGSEGV) FAULT_HANDLER(SIGBUS)
  279.     #define CAN_HANDLE_WP_FAULT
  280.   #endif
  281.   #if defined(UNIX_SUNOS5)
  282.     #include <siginfo.h>
  283.     #define FAULT_HANDLER_ARGLIST  sig, sip, ucp
  284.     #define FAULT_HANDLER_ARGDECL  int sig; siginfo_t* sip; void* ucp;
  285.     #define FAULT_ADDRESS  sip->si_addr
  286.     #define FAULT_ADDRESS_FROM_SIGINFO
  287.     #define WP_SIGNAL  FAULT_HANDLER(SIGSEGV)
  288.     #define CAN_HANDLE_WP_FAULT
  289.   #endif
  290.   #if defined(UNIX_IRIX5)
  291.     #define FAULT_HANDLER_ARGLIST  sig, code, scp
  292.     #define FAULT_HANDLER_ARGDECL  int sig; int code; struct sigcontext *scp;
  293.     #define FAULT_ADDRESS  scp->sc_badvaddr
  294.     #define WP_SIGNAL  FAULT_HANDLER(SIGSEGV)
  295.     #define CAN_HANDLE_WP_FAULT
  296.   #endif
  297.   #if defined(UNIX_OSF)
  298.     #define FAULT_HANDLER_ARGLIST  sig, code, scp
  299.     #define FAULT_HANDLER_ARGDECL  int sig; int code; struct sigcontext *scp;
  300.     #define FAULT_ADDRESS  scp->sc_traparg_a0
  301.     #define WP_SIGNAL  FAULT_HANDLER(SIGSEGV)
  302.     #define CAN_HANDLE_WP_FAULT
  303.   #endif
  304.   #if defined(UNIX_AIX)
  305.     #define FAULT_HANDLER_ARGLIST  sig, code, scp
  306.     #define FAULT_HANDLER_ARGDECL  int sig; int code; struct sigcontext *scp;
  307.     #define FAULT_ADDRESS  scp->sc_jmpbuf.jmp_context.o_vaddr
  308.     #define WP_SIGNAL  FAULT_HANDLER(SIGSEGV)
  309.     #define CAN_HANDLE_WP_FAULT
  310.   #endif
  311.   #if defined(UNIX_NEXTSTEP)
  312.     #define CAN_HANDLE_WP_FAULT
  313.   #endif
  314. # wird verwendet von SPVW
  315.  
  316. # Environment-Variablen abfragen:
  317.   extern char* getenv (GETENV_CONST char* name); # siehe GETENV(3V)
  318. # wird verwendet von PATHNAME, SPVW, MISC
  319.  
  320. # Home-Directory eines Benutzers holen:
  321.   #include <pwd.h>
  322.   extern struct passwd * getpwnam (GETPWNAM_CONST char* name); # siehe GETPWENT(3V)
  323.   extern struct passwd * getpwuid (GETPWUID_UID_T uid); # siehe GETPWENT(3V)
  324.   extern uid_t getuid (void); # siehe GETUID(2V)
  325.   extern uid_t user_uid; # Real User ID des laufenden Prozesses
  326.   #ifdef UNIX_LINUX # fⁿr GRAPHICS_SWITCH
  327.     extern uid_t geteuid (void); # siehe GETUID(2V)
  328.     extern int setreuid (uid_t uid, uid_t euid); # siehe SETREUID(2)
  329.   #endif
  330.   extern char* getlogin (void); # siehe GETLOGIN(3V)
  331. # wird verwendet von PATHNAME, SPVW
  332.  
  333. # Working Directory setzen:
  334.   extern int chdir (CHDIR_CONST char* path); # siehe CHDIR(2V)
  335. # wird verwendet von PATHNAME
  336.  
  337. # Working Directory abfragen:
  338.   #include <sys/param.h>
  339.   # Maximale PfadlΣnge (incl. Nullbyte am Schlu▀), die von getwd geliefert wird:
  340.   #ifndef MAXPATHLEN
  341.     #define MAXPATHLEN  1024  # siehe <sys/param.h>
  342.   #endif
  343.   #ifndef HAVE_GETWD
  344.     extern char* getcwd (char* buf, GETCWD_SIZE_T bufsize);
  345.     #define getwd(buf)  getcwd(buf,MAXPATHLEN)
  346.   #else
  347.     extern char* getwd (char* pathname); # siehe GETWD(3)
  348.   #endif
  349. # wird verwendet von PATHNAME
  350.  
  351. # Maximalzahl symbolischer Links, die nacheinander aufgel÷st werden:
  352.   #ifndef MAXSYMLINKS
  353.     #define MAXSYMLINKS  8  # siehe <sys/param.h>
  354.   #endif
  355. # wird verwendet von PATHNAME
  356.  
  357. # Aufl÷sen symbolischer Links in Pfadnamen:
  358.   #ifdef HAVE_READLINK
  359.     extern int readlink (READLINK_CONST char* path, READLINK_BUF_T buf, READLINK_SIZE_T bufsiz); # siehe READLINK(2)
  360.   #endif
  361. # wird verwendet von PATHNAME
  362.  
  363. # Information zu einem File erfragen:
  364.   #include <sys/types.h>
  365.   #include <sys/stat.h>
  366.   #ifdef STAT_MACROS_BROKEN
  367.     #undef S_ISDIR
  368.     #undef S_ISLNK
  369.     #undef S_ISREG
  370.   #endif
  371.   extern int stat (STAT_CONST char* path, struct stat * buf); # siehe STAT(2V)
  372.   #ifdef HAVE_LSTAT
  373.     extern int lstat (LSTAT_CONST char* path, struct stat * buf); # siehe STAT(2V)
  374.   #else
  375.     #define lstat stat
  376.     #define S_ISLNK(m)  FALSE
  377.   #endif
  378.   extern int fstat (int fd, struct stat * buf); # siehe STAT(2V)
  379.   #ifndef S_ISDIR
  380.     #define S_ISDIR(m)  (((m)&S_IFMT) == S_IFDIR)
  381.   #endif
  382.   #ifndef S_ISLNK
  383.     #define S_ISLNK(m)  (((m)&S_IFMT) == S_IFLNK)
  384.   #endif
  385.   #ifndef S_ISREG
  386.     #define S_ISREG(m)  (((m)&S_IFMT) == S_IFREG)
  387.   #endif
  388. # wird verwendet von PATHNAME, STREAM, SPVW
  389.  
  390. # File l÷schen:
  391.   extern int unlink (UNLINK_CONST char* path); # siehe UNLINK(2V)
  392. # wird verwendet von PATHNAME, UNIXAUX
  393.  
  394. # File umbenennen:
  395.   #ifdef HAVE_RENAME
  396.     extern int rename (RENAME_CONST char* oldpath, RENAME_CONST char* newpath); # siehe RENAME(2V)
  397.   #else
  398.     extern int link (char* oldpath, char* newpath);
  399.     extern int access (char* path, int mode);
  400.     # Emuliere rename() in unixaux.d:
  401.     #define NEED_OWN_RENAME
  402.     extern int rename (char* oldpath, char* newpath); # siehe unixaux.d
  403.   #endif
  404. # wird verwendet von PATHNAME, UNIXAUX
  405.  
  406. # Directory-Suche:
  407.   #if defined(DIRENT) || defined(_POSIX_VERSION)
  408.     #include <dirent.h>
  409.     #define SDIRENT  struct dirent
  410.   #else
  411.     #ifdef SYSNDIR
  412.       #include <sys/ndir.h>
  413.     #else
  414.       #ifdef SYSDIR
  415.         #include <sys/dir.h>
  416.       #else
  417.         #ifdef NDIR
  418.           #include <ndir.h>
  419.         #else
  420.           #include <dir.h>
  421.         #endif
  422.       #endif
  423.     #endif
  424.     #define SDIRENT  struct direct
  425.   #endif
  426.   extern DIR* opendir (OPENDIR_CONST char* dirname); # siehe DIRECTORY(3V)
  427.   extern SDIRENT* readdir (DIR* dirp); # siehe DIRECTORY(3V)
  428.   #ifdef VOID_CLOSEDIR
  429.     extern void closedir (DIR* dirp); # siehe DIRECTORY(3V)
  430.     #define CLOSEDIR(dirp)  (closedir(dirp),0)
  431.   #else
  432.     extern int closedir (DIR* dirp); # siehe DIRECTORY(3V)
  433.     #define CLOSEDIR  closedir
  434.   #endif
  435. # wird verwendet von PATHNAME
  436.  
  437. # Directory anlegen:
  438.   extern int mkdir (MKDIR_CONST char* path, MODE_T mode); # siehe MKDIR(2V)
  439. # wird verwendet von PATHNAME
  440.  
  441. # Directory l÷schen:
  442.   extern int rmdir (RMDIR_CONST char* path); # siehe RMDIR(2V)
  443. # wird verwendet von PATHNAME
  444.  
  445. # Arbeiten mit offenen Files:
  446.   #include <sys/types.h>
  447.   # include <unistd.h> # siehe oben
  448.   #include <fcntl.h>
  449.   #ifdef NEED_SYS_FILE_H
  450.     #include <sys/file.h>
  451.   #endif
  452.   #ifdef OPEN_DOTS
  453.     extern int open (OPEN_CONST char* path, int flags, ...); # siehe OPEN(2V)
  454.   #else
  455.     extern int open (OPEN_CONST char* path, int flags, MODE_T mode); # siehe OPEN(2V)
  456.   #endif
  457.   #define my_open_mask  0644
  458.   #define Handle  uintW  # Typ eines File-Deskriptors
  459.   extern off_t lseek (int fd, off_t offset, int whence); # siehe LSEEK(2V)
  460.   #ifndef SEEK_SET # wg. UNIX_NEXTSTEP
  461.     # Positionierungsmodi, vgl. <unistd.h> :
  462.     #define SEEK_SET  0
  463.     #define SEEK_CUR  1
  464.     #define SEEK_END  2
  465.   #endif
  466.   extern RETRWTYPE read (int fd, RW_BUF_T buf, RW_SIZE_T nbyte); # siehe READ(2V)
  467.   extern RETRWTYPE write (int fd, WRITE_CONST RW_BUF_T buf, RW_SIZE_T nbyte); # siehe WRITE(2V)
  468.   extern int close (int fd); # siehe CLOSE(2V)
  469.   #ifdef HAVE_FSYNC
  470.     extern int fsync (int fd); # siehe FSYNC(2)
  471.   #endif
  472.   #if !defined(HAVE_SELECT) && defined(HAVE_POLL) && !defined(UNIX_COHERENT)
  473.     #define NEED_OWN_SELECT # mit poll() kann man select() selber schreiben
  474.                             # (aber Coherent386 poll() liefert immer EINVAL !)
  475.     #include <poll.h>
  476.     extern int poll (struct pollfd * fds, unsigned long nfds, int timeout);
  477.     #ifndef _EMUL_SYS_TIME_H
  478.       #define _EMUL_SYS_TIME_H
  479.       struct timeval { long tv_sec; long tv_usec; };
  480.       struct timezone { int tz_minuteswest; int tz_dsttime; };
  481.     #endif
  482.     #define SELECT_WIDTH_T int
  483.     #define SELECT_SET_T fd_set
  484.     #define SELECT_CONST
  485.     #define HAVE_SELECT # siehe unixaux.d
  486.   #endif
  487.   #ifdef HAVE_SELECT
  488.     #ifndef _EMUL_SYS_TIME_H
  489.       #include <sys/time.h>
  490.     #endif
  491.     #ifdef HAVE_SYS_SELECT_H
  492.       #include <sys/select.h>
  493.     #endif
  494.     #ifndef FD_SETSIZE
  495.       # Definition des Typs fd_set, vgl. <sys/types.h> :
  496.       #ifdef UNIX_HPUX # dort ist fd_set bereits definiert, aber FD_SETSIZE nicht
  497.         #define fd_set  my_fd_set
  498.       #endif
  499.       #define FD_SETSIZE  256  # Maximalzahl von File-Deskriptoren
  500.       typedef int  fd_mask;  # eine Bitgruppe
  501.       #define NFDBITS  (sizeof(fd_mask) * 8)  # Anzahl Bits in einer Bitgruppe
  502.       typedef struct fd_set { fd_mask fds_bits[ceiling(FD_SETSIZE,NFDBITS)]; }
  503.               fd_set;
  504.       #define FD_SET(n,p)  ((p)->fds_bits[(n)/NFDBITS] |= bit((n)%NFDBITS))
  505.       #define FD_CLR(n,p)  ((p)->fds_bits[(n)/NFDBITS] &= ~bit((n)%NFDBITS))
  506.       #define FD_ISSET(n,p)  ((p)->fds_bits[(n)/NFDBITS] & bit((n)%NFDBITS))
  507.       #define FD_ZERO(p)  bzero((char*)(p),sizeof(*(p)))
  508.       #ifdef HAVE_MEMSET
  509.         #include <string.h>
  510.         extern void* memset (void* ptr, int c, size_t len); # siehe MEMORY(3)
  511.         #define bzero(ptr,len)  memset(ptr,0,len)
  512.       #else
  513.         extern void bzero (void* ptr, int len); # siehe BZERO(3)
  514.       #endif
  515.     #endif
  516.     extern int select (SELECT_WIDTH_T width, SELECT_SET_T* readfds,
  517.                        SELECT_SET_T* writefds, SELECT_SET_T* exceptfds,
  518.                        SELECT_CONST struct timeval * timeout); # siehe SELECT(2)
  519.   #endif
  520.   #ifdef EINTR
  521.     # Wrapper um die System-Aufrufe, die EINTR abfangen und behandeln:
  522.     extern int nonintr_open (OPEN_CONST char* path, int flags, MODE_T mode);
  523.     extern int nonintr_close (int fd);
  524.     #define OPEN nonintr_open
  525.     #define CLOSE nonintr_close
  526.   #else
  527.     #define OPEN open
  528.     #define CLOSE close
  529.   #endif
  530.   # Wrapper um die System-Aufrufe, die Teilergebnisse und evtl. EINTR behandeln:
  531.   extern RETRWTYPE full_read (int fd, char* buf, RW_SIZE_T nbyte);
  532.   extern RETRWTYPE full_write (int fd, WRITE_CONST char* buf, RW_SIZE_T nbyte);
  533. # wird verwendet von STREAM, PATHNAME, SPVW, MISC, UNIXAUX
  534.  
  535. # Terminal-Abfragen, Abfragen der Fenster-Gr÷▀e:
  536.   extern int isatty (int fd); # siehe TTYNAME(3V)
  537.   #if 0
  538.     extern char* ttyname (int fd); # siehe TTYNAME(3V)
  539.   #endif
  540.   #ifdef IOCTL_DOTS
  541.     extern int ioctl (int fd, IOCTL_REQUEST_T request, ...); # siehe IOCTL(2)
  542.   #else
  543.     extern int ioctl (int fd, IOCTL_REQUEST_T request, CADDR_T arg); # siehe IOCTL(2)
  544.     #ifdef ANSI
  545.       # 3. Argument stets zum Typ CADDR_T casten:
  546.       #define ioctl(fd,request,arg)  (ioctl)(fd,request,(CADDR_T)(arg))
  547.     #endif
  548.   #endif
  549.   #if defined(HAVE_TERMIOS_H) && defined(HAVE_TCGETATTR) && defined(HAVE_TCSAFLUSH)
  550.     #define UNIX_TERM_TERMIOS
  551.     #include <termios.h> # siehe TERMIOS(3V)
  552.     #ifndef tcgetattr
  553.       extern int tcgetattr (int fd, struct termios * tp);
  554.     #endif
  555.     #ifndef tcsetattr
  556.       extern int tcsetattr (/* int fd, int optional_actions, [const] struct termios * tp */);
  557.     #endif
  558.     #ifndef tcdrain
  559.       extern int tcdrain (int fd); # siehe TERMIOS(3V)
  560.     #endif
  561.     #ifndef tcflush
  562.       extern int tcflush (int fd, int flag); # siehe TERMIOS(3V)
  563.     #endif
  564.     #define TCSETATTR tcsetattr
  565.     #define TCDRAIN tcdrain
  566.     #define TCFLUSH tcflush
  567.     #ifndef NCCS
  568.       #define NCCS  sizeof(((struct termios *)0)->c_cc)
  569.     #endif
  570.   #elif defined(HAVE_SYS_TERMIO_H) || defined(HAVE_TERMIO_H)
  571.     #define UNIX_TERM_TERMIO
  572.     #if defined(HAVE_SYS_TERMIO_H)
  573.       #include <sys/termio.h> # siehe TERMIO(4)
  574.     #elif defined(HAVE_TERMIO_H)
  575.       #include <termio.h>
  576.     #endif
  577.     #ifndef NCCS
  578.       #define NCCS  sizeof(((struct termio *)0)->c_cc)
  579.     #endif
  580.   #elif defined(HAVE_SGTTY_H)
  581.     # kompatibel zu V7 oder 4BSD, ioctls der Form TIOC....
  582.     #define UNIX_TERM_SGTTY
  583.     #include <sgtty.h>
  584.     #include <sys/ioctl.h> # siehe TTY(4)
  585.   #endif
  586.   #if defined(NEED_SYS_FILIO_H)
  587.     #include <sys/filio.h>
  588.   #elif defined(NEED_SYS_IOCTL_H)
  589.     #include <sys/ioctl.h>
  590.   #endif
  591.   #ifndef HAVE_SELECT
  592.     # include <fcntl.h> # siehe oben
  593.     #ifdef FCNTL_DOTS
  594.       extern int fcntl (int fd, int cmd, ...); # siehe FCNTL(2V)
  595.     #else
  596.       extern int fcntl (int fd, int cmd, int arg); # siehe FCNTL(2V)
  597.     #endif
  598.   #endif
  599.   #if (defined(UNIX_TERM_TERMIOS) || defined(UNIX_TERM_TERMIO)) && !(defined(TCIFLUSH) && defined(TCOFLUSH))
  600.     #define TCIFLUSH 0
  601.     #define TCOFLUSH 1
  602.   #endif
  603.   extern int tgetent (char* bp, char* name); # siehe TERMCAP(3X)
  604.   extern int tgetnum (char* id); # siehe TERMCAP(3X)
  605.   extern int tgetflag (char* id); # siehe TERMCAP(3X)
  606.   extern char* tgetstr (char* id, char** area); # siehe TERMCAP(3X)
  607.   #ifdef EINTR
  608.     # Wrapper um die System-Aufrufe, die EINTR abfangen und behandeln:
  609.     extern int nonintr_ioctl (int fd, IOCTL_REQUEST_T request, CADDR_T arg);
  610.     #undef ioctl
  611.     #ifdef ANSI
  612.       #define ioctl(fd,request,arg)  nonintr_ioctl(fd,request,(CADDR_T)(arg))
  613.     #else
  614.       #define ioctl nonintr_ioctl
  615.     #endif
  616.     #ifdef UNIX_TERM_TERMIOS
  617.       extern int nonintr_tcsetattr (int fd, int optional_actions, struct termios * tp);
  618.       extern int nonintr_tcdrain (int fd); # siehe TERMIOS(3V)
  619.       extern int nonintr_tcflush (int fd, int flag); # siehe TERMIOS(3V)
  620.       #undef TCSETATTR
  621.       #define TCSETATTR nonintr_tcsetattr
  622.       #undef TCDRAIN
  623.       #define TCDRAIN nonintr_tcdrain
  624.       #undef TCFLUSH
  625.       #define TCFLUSH nonintr_tcflush
  626.     #endif
  627.   #endif
  628. # wird verwendet von SPVW, STREAM
  629.  
  630. # Datum/Uhrzeit verarbeiten:
  631.   #ifdef TM_IN_SYS_TIME
  632.     #include <sys/time.h>
  633.   #else
  634.     #include <time.h>
  635.   #endif
  636.   extern time_t time (time_t* clock); # siehe TIME(3V)
  637.   extern struct tm * localtime (LOCALTIME_CONST time_t* clock); # siehe CTIME(3V)
  638.   extern struct tm * gmtime (LOCALTIME_CONST time_t* clock); # siehe CTIME(3V)
  639. # wird verwendet von SPVW, MISC
  640.  
  641. # Datum/Uhrzeit abfragen:
  642.   #if defined(HAVE_GETTIMEOFDAY)
  643.     #include <sys/time.h>
  644.     #ifdef GETTIMEOFDAY_DOTS
  645.       extern int gettimeofday (struct timeval * tp, ...); # siehe GETTIMEOFDAY(2)
  646.     #else
  647.       extern int gettimeofday (struct timeval * tp, struct timezone * tzp); # siehe GETTIMEOFDAY(2)
  648.     #endif
  649.   #elif defined(HAVE_FTIME)
  650.     #include <sys/timeb.h>
  651.     extern int ftime (struct timeb * tp); # siehe TIME(3V)
  652.     # Emuliere gettimeofday() in unixaux.d:
  653.     #define NEED_OWN_GETTIMEOFDAY
  654.     #ifndef _EMUL_SYS_TIME_H
  655.       #define _EMUL_SYS_TIME_H
  656.       struct timeval { long tv_sec; long tv_usec; };
  657.       struct timezone { int tz_minuteswest; int tz_dsttime; };
  658.     #endif
  659.     extern int gettimeofday (struct timeval * tp, struct timezone * tzp); # siehe unixaux.d
  660.   #elif defined(HAVE_TIMES_CLOCK)
  661.     #include <time.h> # fⁿr CLK_TCK n÷tig
  662.     #ifndef CLK_TCK
  663.       #include <sys/time.h> # fⁿr CLK_TCK n÷tig, unter UNIX_SYSV_PTX
  664.     #endif
  665.     #include <sys/times.h>
  666.     extern CLOCK_T times (struct tms * buffer); # siehe TIMES(3V)
  667.     extern time_t time (time_t* tloc); # siehe TIME(3V)
  668.   #else
  669.     #error "Cannot access real time with finer resolution than 1 second."
  670.   #endif
  671. # wird verwendet von SPVW, MISC
  672.  
  673. # vom Proze▀ verbrauchte Zeit erfragen:
  674.   #if defined(HAVE_GETRUSAGE)
  675.     #include <sys/types.h>
  676.     #include <sys/time.h>
  677.     #include <sys/resource.h>
  678.     extern int getrusage (int who, struct rusage * rusage); # siehe GETRUSAGE(2)
  679.     # Prototyp wertlos, da 'struct rusage' /= 'struct rusage' - verkorxtes ANSI!
  680.   #elif defined(HAVE_SYS_TIMES_H)
  681.     #include <sys/types.h>
  682.     #include <sys/param.h> # definiert HZ, Ma▀einheit ist 1/HZ Sekunden
  683.     #include <sys/times.h>
  684.     extern CLOCK_T times (struct tms * buffer); # siehe TIMES(3V)
  685.   #endif
  686.   # Alternative:
  687.   # #include <??>
  688.   # extern ?? vtimes (struct vtimes * par_vm, struct vtimes * ch_vm); # siehe VTIMES(3C)
  689. # wird verwendet von SPVW
  690.  
  691. # Eine bestimmte Zeit Pause machen:
  692.   extern unsigned int sleep (unsigned int seconds); # siehe SLEEP(3V)
  693.   #ifdef HAVE_USLEEP
  694.     # extern {int|void} usleep (unsigned int useconds); # siehe USLEEP(3)
  695.   #endif
  696. # wird verwendet von MISC
  697.  
  698. # Programme aufrufen:
  699.   #define SHELL  "/bin/sh"  # Name der fⁿr Kommandos benutzten Shell
  700.   extern int pipe (int fd[2]); # siehe PIPE(2V)
  701.   #ifdef HAVE_VFORK_H
  702.     #include <vfork.h>
  703.   #endif
  704.   extern RETVFORKTYPE vfork (void); # siehe VFORK(2)
  705.   extern int dup2 (int fd1, int fd2); # siehe DUP(2V)
  706.   #if defined(HAVE_SETPGID)
  707.     extern pid_t getpid (void); # siehe GETPID(2V)
  708.     extern int setpgid (pid_t pid, pid_t pgid); # siehe SETPGID(2V), SETSID(2V), TERMIO(4)
  709.     #define SETSID()  { register pid_t pid = getpid(); setpgid(pid,pid); }
  710.   #elif defined(HAVE_SETSID)
  711.     extern pid_t setsid (void); # siehe SETSID(2V), TERMIO(4)
  712.     #define SETSID()  setsid()
  713.   #else
  714.     #define SETSID()
  715.   #endif
  716.   extern int execv (EXECV_CONST char* path, EXECV1_CONST char* EXECV2_CONST argv[]); # siehe EXECL(3V)
  717.   #ifdef EXECL_DOTS
  718.     extern int execl (EXECV_CONST char* path, EXECL_CONST char* arg, ...); # siehe EXECL(3V)
  719.   #else
  720.     extern int execl (EXECV_CONST char* path, EXECL_CONST char* arg0, EXECL_CONST char* arg1, EXECL_CONST char* arg2, EXECL_CONST char* arg3); # siehe EXECL(3V)
  721.   #endif
  722.   #ifdef EXECL_DOTS
  723.     extern int execlp (EXECV_CONST char* path, EXECL_CONST char* arg, ...); # siehe EXECL(3V)
  724.   #else
  725.     extern int execlp (EXECV_CONST char* path, EXECL_CONST char* arg0, EXECL_CONST char* arg1, EXECL_CONST char* arg2, EXECL_CONST char* arg3); # siehe EXECL(3V)
  726.   #endif
  727.   # NB: Im Zeitraum zwischen vfork() und execv()/execl()/execlp() darf der
  728.   # Child-Proze▀ nur auf Daten im Stack und konstante Daten zugreifen.
  729.   # Denn der Parent-Proze▀ lΣuft in dieser Zeit schon weiter und kann dabei
  730.   # Daten in STACK, malloc()-Bereich, Lisp-Daten-Bereich usw. modifizieren.
  731.   #ifdef HAVE_WAITPID
  732.     #include <sys/wait.h>
  733.     extern pid_t waitpid (PID_T pid, int* statusp, int options); # siehe WAIT(2V)
  734.   #else
  735.     #ifdef HAVE_SYS_WAIT_H
  736.       #include <sys/wait.h>
  737.     #endif
  738.     #ifndef UNIX_NEXTSTEP # NeXTstep 3.1 ohne _POSIX_VERSION deklariert:  extern int wait (union wait);
  739.       extern int wait (int* statusp); # siehe WAIT(2V)
  740.     #endif
  741.     #define PID_T  int
  742.   #endif
  743.   extern int wait2 (PID_T pid); # siehe unixaux.d
  744. # wird verwendet von STREAM, PATHNAME, SPVW, UNIXAUX
  745.  
  746. # Zufallszahlen besorgen:
  747.   #ifndef rand # Manche definieren rand() als Macro...
  748.     extern int rand (void); # siehe RAND(3V)
  749.   #endif
  750.   extern pid_t getpid (void); # siehe GETPID(2V)
  751. # wird verwendet von LISPARIT
  752.  
  753. # MACHINE-TYPE und MACHINE-VERSION und evtl. MACHINE-INSTANCE bestimmen:
  754.   #ifdef HAVE_SYS_UTSNAME_H
  755.     #include <sys/utsname.h>
  756.     extern int uname (struct utsname * buf); # siehe UNAME(2V)
  757.   #endif
  758. # wird verwendet von MISC
  759.  
  760. # MACHINE-INSTANCE bestimmen:
  761.   #ifdef HAVE_GETHOSTNAME
  762.     extern int gethostname (char* name, GETHOSTNAME_SIZE_T namelen); # siehe GETHOSTNAME(2)
  763.   #endif
  764.   #ifdef HAVE_GETHOSTBYNAME
  765.     #include <sys/types.h>
  766.     #ifdef HAVE_NETDB_H
  767.       #include <sys/socket.h>
  768.       #include <netdb.h>
  769.     #else
  770.       #include <sun/netdb.h>
  771.     #endif
  772.     extern struct hostent * gethostbyname (GETHOSTBYNAME_CONST char* name); # siehe GETHOSTENT(3)
  773.   #endif
  774.   #ifndef MAXHOSTNAMELEN
  775.     #define MAXHOSTNAMELEN 64 # siehe <sys/param.h>
  776.   #endif
  777. # wird verwendet von MISC
  778.  
  779.