XEmacs 21.2.28 "Hermes".
[chise/xemacs-chise.git.1] / src / sysdep.c
1 /* Interfaces to system-dependent kernel and library entries.
2    Copyright (C) 1985-1988, 1992-1995 Free Software Foundation, Inc.
3    Copyright (C) 1995 Tinker Systems.
4
5 This file is part of XEmacs.
6
7 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 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 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 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: FSF 19.30 except for some Windows-NT crap. */
23
24 /* Substantially cleaned up by Ben Wing, Dec. 1994 / Jan. 1995. */
25
26 /* In this file, open, read and write refer to the system calls,
27    not our sugared interfaces sys_open, sys_read and sys_write.
28  */
29
30 #define DONT_ENCAPSULATE
31
32 #include <config.h>
33
34 #ifdef WINDOWSNT
35 #include <direct.h>
36 #ifdef __MINGW32__
37 #include <mingw32/process.h>
38 #else
39 /* <process.h> should not conflict with "process.h", as per ANSI definition.
40    This is not true with visual c though. The trick below works with
41    VC4.2b, 5.0 and 6.0. It assumes that VC is installed in a kind of
42    standard way, so include path ends with /include.
43
44    Unfortunately, this must go before lisp.h, since process.h defines abort()
45    which will conflict with the macro defined in lisp.h
46 */
47 #include <../include/process.h>
48 #endif /* __MINGW32__ */
49 #endif /* WINDOWSNT */
50
51 #include "lisp.h"
52
53 #include <stdlib.h>
54
55 /* ------------------------------- */
56 /*          basic includes         */
57 /* ------------------------------- */
58
59 #ifdef HAVE_TTY
60 #include "console-tty.h"
61 #else
62 #include "syssignal.h"
63 #include "systty.h"
64 #endif /* HAVE_TTY */
65
66 #include "console-stream.h"
67
68 #include "buffer.h"
69 #include "events.h"
70 #include "frame.h"
71 #include "redisplay.h"
72 #include "process.h"
73 #include "sysdep.h"
74 #include "window.h"
75
76 #include <setjmp.h>
77 #ifdef HAVE_LIBGEN_H            /* Must come before sysfile.h */
78 #include <libgen.h>
79 #endif
80 #include "sysfile.h"
81 #include "syswait.h"
82 #include "sysdir.h"
83 #include "systime.h"
84 #if defined(WINDOWSNT) || defined(__CYGWIN32__)
85 #include "syssignal.h"
86 #endif
87 #ifndef WINDOWSNT
88 #include <sys/times.h>
89 #endif
90
91 #ifdef WINDOWSNT
92 #include <sys/utime.h>
93 #include "ntheap.h"
94 #endif
95
96 /* ------------------------------- */
97 /*         TTY definitions         */
98 /* ------------------------------- */
99
100 #ifdef USG
101 #include <sys/utsname.h>
102 #if defined (TIOCGWINSZ) || defined (ISC4_0)
103 #ifdef NEED_SIOCTL
104 #include <sys/sioctl.h>
105 #endif
106 #ifdef NEED_PTEM_H
107 #include <sys/stream.h>
108 #include <sys/ptem.h>
109 #endif
110 #endif /* TIOCGWINSZ or ISC4_0 */
111 #endif /* USG */
112
113 #ifdef HAVE_SYS_STROPTS_H
114 #include <sys/stropts.h>
115 #endif /* HAVE_SYS_STROPTS_H */
116
117 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits.  */
118 #ifndef LPASS8
119 #define LPASS8 0
120 #endif
121
122 #ifndef HAVE_H_ERRNO
123 int h_errno;
124 #endif
125
126 #ifdef HAVE_TTY
127
128 static int baud_convert[] =
129 #ifdef BAUD_CONVERT
130   BAUD_CONVERT;
131 #else
132   {
133     0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
134     1800, 2400, 4800, 9600, 19200, 38400
135   };
136 #endif
137
138 #endif
139
140 #ifdef AIXHFT
141 static void hft_init (struct console *c);
142 static void hft_reset (struct console *c);
143 #include <sys/termio.h>
144 #endif
145
146 /* ------------------------------- */
147 /*          miscellaneous          */
148 /* ------------------------------- */
149
150 #ifndef HAVE_UTIMES
151 #ifndef HAVE_STRUCT_UTIMBUF
152 /* We want to use utime rather than utimes, but we couldn't find the
153    structure declaration.  We'll use the traditional one.  */
154 struct utimbuf
155 {
156   long actime;
157   long modtime;
158 };
159 #endif
160 #endif
161
162 \f
163 /************************************************************************/
164 /*                         subprocess control                           */
165 /************************************************************************/
166
167 #ifdef HAVE_TTY
168
169 #ifdef SIGTSTP
170
171 /* Arrange for character C to be read as the next input from
172    the terminal.  */
173 void
174 stuff_char (struct console *con, int c)
175 {
176   int input_fd;
177
178   assert (CONSOLE_TTY_P (con));
179   input_fd = CONSOLE_TTY_DATA (con)->infd;
180 /* Should perhaps error if in batch mode */
181 #ifdef TIOCSTI
182   ioctl (input_fd, TIOCSTI, &c);
183 #else /* no TIOCSTI */
184   error ("Cannot stuff terminal input characters in this version of Unix.");
185 #endif /* no TIOCSTI */
186 }
187
188 #endif /* SIGTSTP */
189
190 #endif /* HAVE_TTY */
191
192 void
193 set_exclusive_use (int fd)
194 {
195 #ifdef FIOCLEX
196   ioctl (fd, FIOCLEX, 0);
197 #endif
198   /* Ok to do nothing if this feature does not exist */
199 }
200
201 void
202 set_descriptor_non_blocking (int fd)
203 {
204 /* Stride people say it's a mystery why this is needed
205    as well as the O_NDELAY, but that it fails without this.  */
206   /* For AIX: Apparently need this for non-blocking reads on sockets.
207      It seems that O_NONBLOCK applies only to FIFOs?  From
208      lowry@watson.ibm.com (Andy Lowry). */
209   /* #### Should this be conditionalized on FIONBIO? */
210 #if defined (STRIDE) || (defined (pfa) && defined (HAVE_PTYS)) || defined (AIX)
211   {
212     int one = 1;
213     ioctl (fd, FIONBIO, &one);
214   }
215 #endif
216
217 #ifdef F_SETFL
218   fcntl (fd, F_SETFL, O_NONBLOCK);
219 #endif
220 }
221
222 #if defined (NO_SUBPROCESSES)
223
224 #ifdef BSD
225 void
226 wait_without_blocking (void)
227 {
228   wait3 (0, WNOHANG | WUNTRACED, 0);
229   synch_process_alive = 0;
230 }
231 #endif /* BSD */
232
233 #endif /* NO_SUBPROCESSES */
234
235
236 #ifdef WINDOWSNT
237 void wait_for_termination (HANDLE pHandle)
238 #else
239 void wait_for_termination (int pid)
240 #endif
241 {
242   /* #### With the new improved SIGCHLD handling stuff, there is much
243      less danger of race conditions and some of the comments below
244      don't apply.  This should be updated. */
245
246 #if defined (NO_SUBPROCESSES)
247   while (1)
248     {
249       /* No need to be tricky like below; we can just call wait(). */
250       /* #### should figure out how to write a wait_allowing_quit().
251          Since hardly any systems don't have subprocess support,
252          however, there doesn't seem to be much point. */
253       if (wait (0) == pid)
254         return;
255     }
256 #elif defined (HAVE_WAITPID)
257   /* Note that, whenever any subprocess terminates (asynch. or synch.),
258      the SIGCHLD handler will be called and it will call wait().  Thus
259      we cannot just call wait() ourselves, and we can't block SIGCHLD
260      and then call wait(), because then if an asynch.  process dies
261      while we're waiting for our synch. process, Emacs will never
262      notice that the asynch. process died.
263
264      So, the general approach we take is to repeatedly block until a
265      signal arrives, and then check if our process died using kill
266      (pid, 0).  (We could also check the value of `synch_process_alive',
267      since the SIGCHLD handler will reset that and we know that we're
268      only being called on synchronous processes, but this approach is
269      safer.  I don't trust the proper delivery of SIGCHLD.
270
271      Note also that we cannot use any form of waitpid().  A loop with
272      WNOHANG will chew up CPU time; better to use sleep().  A loop
273      without WNOWAIT will screw up the SIGCHLD handler (actually this
274      is not true, if you duplicate the exit-status-reaping code; see
275      below).  A loop with WNOWAIT will result in a race condition if
276      the process terminates between the process-status check and the
277      call to waitpid(). */
278
279   /* Formerly, immediate_quit was set around this function call, but
280      that could lead to problems if the QUIT happened when SIGCHLD was
281      blocked -- it would remain blocked.  Yet another reason why
282      immediate_quit is a bad idea.  In any case, there is no reason to
283      resort to this because either the SIGIO or the SIGALRM will stop
284      the block in EMACS_WAIT_FOR_SIGNAL(). */
285
286   /* Apparently there are bugs on some systems with the second method
287      used below (the EMACS_BLOCK_SIGNAL method), whereby zombie
288      processes get left around.  It appears in those cases that the
289      SIGCHLD handler is never getting invoked.  It's not clear whether
290      this is an Emacs bug or a kernel bug or both: on HPUX this
291      problem is observed only with XEmacs, but under Solaris 2.4 all
292      sorts of different programs have problems with zombies.  The
293      method we use here does not require a working SIGCHLD (but will
294      not break if it is working), and should be safe. */
295   /*
296      We use waitpid(), contrary to the remarks above.  There is no
297      race condition, because the three situations when sigchld_handler
298      is invoked should be handled OK:
299
300      - handler invoked before waitpid(): In this case, subprocess
301        status will be set by sigchld_handler.  waitpid() here will
302        return -1 with errno set to ECHILD, which is a valid exit
303        condition.
304
305      - handler invoked during waitpid(): as above, except that errno
306        here will be set to EINTR.  This will cause waitpid() to be
307        called again, and this time it will exit with ECHILD.
308
309      - handler invoked after waitpid(): The following code will reap
310        the subprocess. In the handler, wait() will return -1 because
311        there is no child to reap, and the handler will exit without
312        modifying child subprocess status.  */
313   int ret, status;
314
315   /* Because the SIGCHLD handler can potentially reap the synchronous
316      subprocess, we should take care of that.  */
317
318   /* Will stay in the do loop as long as:
319      1. Process is alive
320      2. Ctrl-G is not pressed */
321   do
322     {
323       QUIT;
324       ret = waitpid (pid, &status, 0);
325       /* waitpid returns 0 if the process is still alive. */
326     }
327   while (ret == 0 || (ret == -1 && errno == EINTR));
328
329   if (ret == pid) /* Success */
330     /* Set synch process globals.  This is can also happen
331        in sigchld_handler, and that code is duplicated. */
332     {
333       synch_process_alive = 0;
334       if (WIFEXITED (status))
335         synch_process_retcode = WEXITSTATUS (status);
336       else if (WIFSIGNALED (status))
337         synch_process_death = signal_name (WTERMSIG (status));
338     }
339   /* On exiting the loop, ret will be -1, with errno set to ECHILD if
340      the child has already been reaped, e.g. in the signal handler.  */
341
342   /* Otherwise, we've had some error condition here.
343      Per POSIX, the only other possibilities are:
344      - EFAULT (bus error accessing arg 2) or
345      - EINVAL (incorrect arguments),
346      which are both program bugs.
347
348      Since implementations may add their own error indicators on top,
349      we ignore it by default.  */
350 #elif defined (WINDOWSNT)
351   int ret = 0, status = 0;
352   if (pHandle == NULL)
353     {
354       warn_when_safe (Qprocess, Qwarning, "Cannot wait for unknown process to terminate");
355       return;
356     }
357   do
358     {
359       QUIT;
360       ret = WaitForSingleObject(pHandle, 100);
361     }
362   while (ret == WAIT_TIMEOUT);
363   if (ret == WAIT_FAILED)
364     {
365       warn_when_safe (Qprocess, Qwarning, "waiting for process failed");
366     }
367   if (ret == WAIT_ABANDONED)
368     {
369       warn_when_safe (Qprocess, Qwarning,
370                       "process to wait for has been abandoned");
371     }
372   if (ret == WAIT_OBJECT_0)
373     {
374       ret = GetExitCodeProcess(pHandle, &status);
375       if (ret)
376         {
377           synch_process_alive = 0;
378           synch_process_retcode = status;
379         }
380       else
381         {
382           /* GetExitCodeProcess() didn't return a valid exit status,
383              nothing to do.  APA */
384           warn_when_safe (Qprocess, Qwarning,
385                           "failure to obtain process exit value");
386         }
387     }
388   if (pHandle != NULL && !CloseHandle(pHandle))
389     {
390       warn_when_safe (Qprocess, Qwarning,
391                       "failure to close unknown process");
392     }
393 #elif defined (EMACS_BLOCK_SIGNAL) && !defined (BROKEN_WAIT_FOR_SIGNAL) && defined (SIGCHLD)
394   while (1)
395     {
396       static int wait_debugging = 0; /* Set nonzero to make following
397                            function work under dbx (at least for bsd).  */
398       QUIT;
399       if (wait_debugging)
400         return;
401
402       EMACS_BLOCK_SIGNAL (SIGCHLD);
403       /* Block SIGCHLD from happening during this check,
404          to avoid race conditions. */
405       if (kill (pid, 0) < 0)
406         {
407           EMACS_UNBLOCK_SIGNAL (SIGCHLD);
408           return;
409         }
410       else
411         /* WARNING: Whatever this macro does *must* not allow SIGCHLD
412            to happen between the time that it's reenabled and when we
413            begin to block.  Otherwise we may end up blocking for a
414            signal that has already arrived and isn't coming again.
415            Can you say "race condition"?
416
417            I assume that the system calls sigpause() or sigsuspend()
418            to provide this atomicness.  If you're getting hangs in
419            sigpause()/sigsuspend(), then your OS doesn't implement
420            this properly (this applies under hpux9, for example).
421            Try defining BROKEN_WAIT_FOR_SIGNAL. */
422         EMACS_WAIT_FOR_SIGNAL (SIGCHLD);
423     }
424 #else /* not HAVE_WAITPID and not WINDOWSNT and (not EMACS_BLOCK_SIGNAL or BROKEN_WAIT_FOR_SIGNAL) */
425   /* This approach is kind of cheesy but is guaranteed(?!) to work
426      for all systems. */
427   while (1)
428     {
429       QUIT;
430       if (kill (pid, 0) < 0)
431         return;
432       emacs_sleep (1);
433     }
434 #endif /* OS features */
435 }
436
437
438 #if !defined (NO_SUBPROCESSES)
439
440 /*
441  *      flush any pending output
442  *      (may flush input as well; it does not matter the way we use it)
443  */
444
445 void
446 flush_pending_output (int channel)
447 {
448 #ifdef HAVE_TERMIOS
449   /* If we try this, we get hit with SIGTTIN, because
450      the child's tty belongs to the child's pgrp. */
451 #elif defined (TCFLSH)
452   ioctl (channel, TCFLSH, 1);
453 #elif defined (TIOCFLUSH)
454   int zero = 0;
455   /* 3rd arg should be ignored
456      but some 4.2 kernels actually want the address of an int
457      and nonzero means something different.  */
458   ioctl (channel, TIOCFLUSH, &zero);
459 #endif
460 }
461
462 #ifndef WINDOWSNT
463 /*  Set up the terminal at the other end of a pseudo-terminal that
464     we will be controlling an inferior through.
465     It should not echo or do line-editing, since that is done
466     in Emacs.  No padding needed for insertion into an Emacs buffer.  */
467
468 void
469 child_setup_tty (int out)
470 {
471   struct emacs_tty s;
472   emacs_get_tty (out, &s);
473
474 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
475   assert (isatty(out));
476   s.main.c_oflag |= OPOST;      /* Enable output postprocessing */
477   s.main.c_oflag &= ~ONLCR;     /* Disable map of NL to CR-NL on output */
478 #ifdef NLDLY
479   s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
480                                 /* No output delays */
481 #endif
482   s.main.c_lflag &= ~ECHO;      /* Disable echo */
483   s.main.c_lflag |= ISIG;       /* Enable signals */
484 #ifdef IUCLC
485   s.main.c_iflag &= ~IUCLC;     /* Disable downcasing on input.  */
486 #endif
487 #ifdef OLCUC
488   s.main.c_oflag &= ~OLCUC;     /* Disable upcasing on output.  */
489 #endif
490   s.main.c_oflag &= ~TAB3;      /* Disable tab expansion */
491 #if defined (CSIZE) && defined (CS8)
492   s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
493 #endif
494 #ifdef ISTRIP
495   s.main.c_iflag &= ~ISTRIP;    /* Don't strip 8th bit on input */
496 #endif
497 #if 0
498   /* Unnecessary as long as ICANON is set */
499   s.main.c_cc[VMIN]  = 1;       /* minimum number of characters to accept  */
500   s.main.c_cc[VTIME] = 0;       /* wait forever for at least 1 character  */
501 #endif /* 0 */
502
503   s.main.c_lflag |= ICANON;     /* Enable erase/kill and eof processing */
504   s.main.c_cc[VEOF] = 04;       /* ensure that EOF is Control-D */
505   s.main.c_cc[VERASE] = _POSIX_VDISABLE; /* disable erase processing */
506   s.main.c_cc[VKILL]  = _POSIX_VDISABLE; /* disable kill processing */
507
508 #ifdef HPUX
509   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
510 #endif /* HPUX */
511
512 #ifdef AIX
513 #ifndef IBMR2AIX
514   /* AIX enhanced edit loses NULs, so disable it. */
515   s.main.c_line = 0;
516   s.main.c_iflag &= ~ASCEDIT;
517 #endif /* IBMR2AIX */
518   /* Also, PTY overloads NUL and BREAK.
519      don't ignore break, but don't signal either, so it looks like NUL.
520      This really serves a purpose only if running in an XTERM window
521      or via TELNET or the like, but does no harm elsewhere.  */
522   s.main.c_iflag &= ~IGNBRK;
523   s.main.c_iflag &= ~BRKINT;
524 #endif /* AIX */
525 #ifdef SIGNALS_VIA_CHARACTERS
526   /* TTY `special characters' are used in process_send_signal
527      so set them here to something useful.  */
528   s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
529   s.main.c_cc[VINTR] = 'C' &037; /* Control-C */
530   s.main.c_cc[VSUSP] = 'Z' &037; /* Control-Z */
531 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
532   /* TTY `special characters' work better as signals, so disable
533      character forms */
534   s.main.c_cc[VQUIT] = _POSIX_VDISABLE;
535   s.main.c_cc[VINTR] = _POSIX_VDISABLE;
536   s.main.c_cc[VSUSP] = _POSIX_VDISABLE;
537   s.main.c_lflag &= ~ISIG;
538 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
539   s.main.c_cc[VEOL] = _POSIX_VDISABLE;
540 #if defined (CBAUD)
541   /* <mdiers> #### This is not portable. ###
542      POSIX does not specify CBAUD, and 4.4BSD does not have it.
543      Instead, POSIX suggests to use cfset{i,o}speed().
544      [cf. D. Lewine, POSIX Programmer's Guide, Chapter 8: Terminal
545      I/O, O'Reilly 1991] */
546   s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
547 #else
548   /* <mdiers> What to do upon failure? Just ignoring rc is probably
549      not acceptable, is it? */
550   if (cfsetispeed (&s.main, B9600) == -1) /* ignore */;
551   if (cfsetospeed (&s.main, B9600) == -1) /* ignore */;
552 #endif /* defined (CBAUD) */
553
554 #else /* not HAVE_TERMIO */
555
556   s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
557                        | CBREAK | TANDEM);
558   s.main.sg_flags |= LPASS8;
559   s.main.sg_erase = 0377;
560   s.main.sg_kill  = 0377;
561   s.lmode = LLITOUT | s.lmode;        /* Don't strip 8th bit */
562
563 #endif /* not HAVE_TERMIO */
564   emacs_set_tty (out, &s, 0);
565
566 #ifdef RTU
567   {
568     int zero = 0;
569     ioctl (out, FIOASYNC, &zero);
570   }
571 #endif /* RTU */
572 }
573 #endif /* WINDOWSNT */
574
575 #endif /* not NO_SUBPROCESSES */
576
577 \f
578 #if !defined (SIGTSTP) && !defined (USG_JOBCTRL)
579
580 #if defined(__STDC__) || defined(_MSC_VER)
581 #define SIG_PARAM_TYPE int
582 #else
583 #define SIG_PARAM_TYPE
584 #endif
585
586 /* Record a signal code and the handler for it.  */
587 struct save_signal
588 {
589   int code;
590   SIGTYPE (*handler) (SIG_PARAM_TYPE);
591 };
592
593 static void
594 save_signal_handlers (struct save_signal *saved_handlers)
595 {
596   while (saved_handlers->code)
597     {
598       saved_handlers->handler
599         = (SIGTYPE (*) (SIG_PARAM_TYPE)) signal (saved_handlers->code, SIG_IGN);
600       saved_handlers++;
601     }
602 }
603
604 static void
605 restore_signal_handlers (struct save_signal *saved_handlers)
606 {
607   while (saved_handlers->code)
608     {
609       signal (saved_handlers->code, saved_handlers->handler);
610       saved_handlers++;
611     }
612 }
613
614 #ifdef WINDOWSNT
615 pid_t
616 sys_getpid (void)
617 {
618   return abs (getpid ());
619 }
620 #endif /* WINDOWSNT */
621
622 /* Fork a subshell.  */
623 static void
624 sys_subshell (void)
625 {
626 #ifdef WINDOWSNT
627   HANDLE pid;
628 #else
629   int pid;
630 #endif
631   struct save_signal saved_handlers[5];
632   Lisp_Object dir;
633   unsigned char *str = 0;
634   int len;
635   struct gcpro gcpro1;
636
637   saved_handlers[0].code = SIGINT;
638   saved_handlers[1].code = SIGQUIT;
639   saved_handlers[2].code = SIGTERM;
640 #ifdef SIGIO
641   saved_handlers[3].code = SIGIO;
642   saved_handlers[4].code = 0;
643 #else
644   saved_handlers[3].code = 0;
645 #endif
646
647   /* Mentioning current_buffer->buffer would mean including buffer.h,
648      which somehow wedges the hp compiler.  So instead...  */
649
650   if (NILP (Fboundp (Qdefault_directory)))
651     goto xyzzy;
652   dir = Fsymbol_value (Qdefault_directory);
653   if (!STRINGP (dir))
654     goto xyzzy;
655
656   GCPRO1 (dir);
657   dir = Funhandled_file_name_directory (dir);
658   dir = expand_and_dir_to_file (dir, Qnil);
659   UNGCPRO;
660   str = (unsigned char *) alloca (XSTRING_LENGTH (dir) + 2);
661   len = XSTRING_LENGTH (dir);
662   memcpy (str, XSTRING_DATA (dir), len);
663   /* #### Unix specific */
664   if (str[len - 1] != '/') str[len++] = '/';
665   str[len] = 0;
666  xyzzy:
667
668 #ifdef WINDOWSNT
669   pid = NULL;
670 #else /* not WINDOWSNT */
671
672   pid = fork ();
673
674   if (pid == -1)
675     error ("Can't spawn subshell");
676   if (pid == 0)
677
678 #endif /* not WINDOWSNT */
679   {
680       char *sh = 0;
681
682       if (sh == 0)
683         sh = (char *) egetenv ("SHELL");
684       if (sh == 0)
685         sh = "sh";
686
687     /* Use our buffer's default directory for the subshell.  */
688     if (str)
689       sys_chdir (str);
690
691 #if !defined (NO_SUBPROCESSES) && !defined (WINDOWSNT)
692     close_process_descs ();     /* Close Emacs's pipes/ptys */
693 #endif
694
695 #ifdef SET_EMACS_PRIORITY
696     if (emacs_priority != 0)
697       nice (-emacs_priority);   /* Give the new shell the default priority */
698 #endif
699
700 #ifdef WINDOWSNT
701       /* Waits for process completion */
702       pid = _spawnlp (_P_WAIT, sh, sh, NULL);
703       if (pid == NULL)
704         write (1, "Can't execute subshell", 22);
705
706 #else   /* not WINDOWSNT */
707     execlp (sh, sh, 0);
708     write (1, "Can't execute subshell", 22);
709     _exit (1);
710 #endif /* not WINDOWSNT */
711   }
712
713   save_signal_handlers (saved_handlers);
714   synch_process_alive = 1;
715   wait_for_termination (pid);
716   restore_signal_handlers (saved_handlers);
717 }
718
719 #endif /* !defined (SIGTSTP) && !defined (USG_JOBCTRL) */
720
721
722 \f
723 /* Suspend the Emacs process; give terminal to its superior.  */
724 void
725 sys_suspend (void)
726 {
727 #if defined (SIGTSTP)
728   {
729     int pgrp = EMACS_GET_PROCESS_GROUP ();
730     EMACS_KILLPG (pgrp, SIGTSTP);
731   }
732
733 #elif defined (USG_JOBCTRL)
734   /* If you don't know what this is don't mess with it */
735   ptrace (0, 0, 0, 0);          /* set for ptrace - caught by csh */
736   kill (getpid (), SIGQUIT);
737
738 #else /* No SIGTSTP or USG_JOBCTRL */
739
740   /* On a system where suspending is not implemented,
741      instead fork a subshell and let it talk directly to the terminal
742      while we wait.  */
743   sys_subshell ();
744
745 #endif
746 }
747
748 /* Suspend a process if possible; give terminal to its superior.  */
749 void
750 sys_suspend_process (int process)
751 {
752     /* I don't doubt that it is possible to suspend processes on
753      * VMS machines or thost that use USG_JOBCTRL,
754      * but I don't know how to do it, so...
755      */
756 #if defined (SIGTSTP)
757     kill(process, SIGTSTP);
758 #endif
759 }
760 \f
761
762 /* Given FD, obtain pty buffer size. When no luck, a good guess is made,
763    so that the function works even fd is not a pty. */
764
765 int
766 get_pty_max_bytes (int fd)
767 {
768   int pty_max_bytes;
769
770 #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON)
771   pty_max_bytes = fpathconf (fd, _PC_MAX_CANON);
772   if (pty_max_bytes < 0)
773 #endif
774     pty_max_bytes = 250;
775
776   /* Deduct one, to leave space for the eof.  */
777   pty_max_bytes--;
778
779   return pty_max_bytes;
780 }
781
782 /* Figure out the eof character for the FD. */
783
784 Bufbyte
785 get_eof_char (int fd)
786 {
787   CONST Bufbyte ctrl_d = (Bufbyte) '\004';
788
789   if (!isatty (fd))
790     return ctrl_d;
791 #ifdef HAVE_TERMIOS
792   {
793     struct termios t;
794     tcgetattr (fd, &t);
795 #if 0
796     /* What is the following line designed to do??? -mrb */
797     if (strlen ((CONST char *) t.c_cc) < (unsigned int) (VEOF + 1))
798       return ctrl_d;
799     else
800       return (Bufbyte) t.c_cc[VEOF];
801 #endif
802     return t.c_cc[VEOF] == _POSIX_VDISABLE ? ctrl_d : (Bufbyte) t.c_cc[VEOF];
803   }
804 #else /* ! HAVE_TERMIOS */
805   /* On Berkeley descendants, the following IOCTL's retrieve the
806     current control characters.  */
807 #if defined (TIOCGETC)
808   {
809     struct tchars c;
810     ioctl (fd, TIOCGETC, &c);
811     return (Bufbyte) c.t_eofc;
812   }
813 #else /* ! defined (TIOCGLTC) && defined (TIOCGETC) */
814   /* On SYSV descendants, the TCGETA ioctl retrieves the current control
815      characters.  */
816 #ifdef TCGETA
817   {
818     struct termio t;
819     ioctl (fd, TCGETA, &t);
820     if (strlen ((CONST char *) t.c_cc) < (unsigned int) (VINTR + 1))
821       return ctrl_d;
822     else
823       return (Bufbyte) t.c_cc[VINTR];
824   }
825 #else /* ! defined (TCGETA) */
826   /* Rather than complain, we'll just guess ^D, which is what
827    * earlier emacsen always used. */
828   return ctrl_d;
829 #endif /* ! defined (TCGETA) */
830 #endif /* ! defined (TIOCGETC) */
831 #endif /* ! defined (HAVE_TERMIOS) */
832 }
833
834 /* Set the logical window size associated with descriptor FD
835    to HEIGHT and WIDTH.  This is used mainly with ptys.  */
836
837 int
838 set_window_size (int fd, int height, int width)
839 {
840 #ifdef TIOCSWINSZ
841
842   /* BSD-style.  */
843   struct winsize size;
844   size.ws_row = height;
845   size.ws_col = width;
846
847   if (ioctl (fd, TIOCSWINSZ, &size) == -1)
848     return 0; /* error */
849   else
850     return 1;
851
852 #elif defined (TIOCSSIZE)
853
854   /* SunOS - style.  */
855   struct ttysize size;
856   size.ts_lines = height;
857   size.ts_cols = width;
858
859   if (ioctl (fd, TIOCGSIZE, &size) == -1)
860     return 0;
861   else
862     return 1;
863 #else
864   return -1;
865 #endif
866 }
867
868 #ifdef HAVE_PTYS
869
870 /* Set up the proper status flags for use of a pty.  */
871
872 void
873 setup_pty (int fd)
874 {
875   /* I'm told that TOICREMOTE does not mean control chars
876      "can't be sent" but rather that they don't have
877      input-editing or signaling effects.
878      That should be good, because we have other ways
879      to do those things in Emacs.
880      However, telnet mode seems not to work on 4.2.
881      So TIOCREMOTE is turned off now. */
882
883   /* Under hp-ux, if TIOCREMOTE is turned on, some calls
884      will hang.  In particular, the "timeout" feature (which
885      causes a read to return if there is no data available)
886      does this.  Also it is known that telnet mode will hang
887      in such a way that Emacs must be stopped (perhaps this
888      is the same problem).
889
890      If TIOCREMOTE is turned off, then there is a bug in
891      hp-ux which sometimes loses data.  Apparently the
892      code which blocks the master process when the internal
893      buffer fills up does not work.  Other than this,
894      though, everything else seems to work fine.
895
896      Since the latter lossage is more benign, we may as well
897      lose that way.  -- cph */
898 #if defined (FIONBIO) && defined (SYSV_PTYS)
899   {
900     int on = 1;
901     ioctl (fd, FIONBIO, &on);
902   }
903 #endif
904 #ifdef IBMRTAIX
905   /* On AIX, the parent gets SIGHUP when a pty attached child dies.  So, we */
906   /* ignore SIGHUP once we've started a child on a pty.  Note that this may */
907   /* cause EMACS not to die when it should, i.e., when its own controlling  */
908   /* tty goes away.  I've complained to the AIX developers, and they may    */
909   /* change this behavior, but I'm not going to hold my breath.             */
910   signal (SIGHUP, SIG_IGN);
911 #endif
912 #ifdef TIOCPKT
913   /* In some systems (Linux through 2.0.0, at least), packet mode doesn't
914      get cleared when a pty is closed, so we need to clear it here.
915      Linux pre2.0.13 contained an attempted fix for this (from Ted Ts'o,
916      tytso@mit.edu), but apparently it messed up rlogind and telnetd, so he
917      removed the fix in pre2.0.14.     - dkindred@cs.cmu.edu
918    */
919   {
920     int off = 0;
921     ioctl (fd, TIOCPKT, (char *)&off);
922   }
923 #endif
924 }
925 #endif /* HAVE_PTYS */
926
927 \f
928 /************************************************************************/
929 /*                            TTY control                               */
930 /************************************************************************/
931
932 /* ------------------------------------------------------ */
933 /*                     get baud rate                      */
934 /* ------------------------------------------------------ */
935
936 /* It really makes more sense for the baud-rate to be console-specific
937    and not device-specific, but it's (at least potentially) used for output
938    decisions. */
939
940 void
941 init_baud_rate (struct device *d)
942 {
943   struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
944   if (DEVICE_WIN_P (d) || DEVICE_STREAM_P (d))
945     {
946       DEVICE_BAUD_RATE (d) = 38400;
947       return;
948     }
949
950 #ifdef HAVE_TTY
951   assert (DEVICE_TTY_P (d));
952   {
953     int input_fd = CONSOLE_TTY_DATA (con)->infd;
954 #if defined (WINDOWSNT)
955     DEVICE_TTY_DATA (d)->ospeed = 15;
956 #elif defined (HAVE_TERMIOS)
957     struct termios sg;
958
959     sg.c_cflag = B9600;
960     tcgetattr (input_fd, &sg);
961     DEVICE_TTY_DATA (d)->ospeed = cfgetospeed (&sg);
962 # if defined (USE_GETOBAUD) && defined (getobaud)
963     /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
964     if (DEVICE_TTY_DATA (d)->ospeed == 0)
965       DEVICE_TTY_DATA (d)->ospeed = getobaud (sg.c_cflag);
966 # endif
967 #elif defined (HAVE_TERMIO)
968     struct termio sg;
969
970     sg.c_cflag = B9600;
971 # ifdef HAVE_TCATTR
972     tcgetattr (input_fd, &sg);
973 # else
974     ioctl (input_fd, TCGETA, &sg);
975 # endif
976     DEVICE_TTY_DATA (d)->ospeed = sg.c_cflag & CBAUD;
977 #else /* neither TERMIOS nor TERMIO */
978     struct sgttyb sg;
979
980     sg.sg_ospeed = B9600;
981     if (ioctl (input_fd, TIOCGETP, &sg) < 0)
982       abort ();
983     DEVICE_TTY_DATA (d)->ospeed = sg.sg_ospeed;
984 #endif
985   }
986
987   DEVICE_BAUD_RATE (d) =
988     (DEVICE_TTY_DATA (d)->ospeed < countof (baud_convert)
989      ? baud_convert[DEVICE_TTY_DATA (d)->ospeed]
990      : 9600);
991
992   if (DEVICE_BAUD_RATE (d) == 0)
993     DEVICE_BAUD_RATE (d) = 1200;
994 #endif /* HAVE_TTY */
995 }
996
997 \f
998 /* ------------------------------------------------------ */
999 /*                       SIGIO control                    */
1000 /* ------------------------------------------------------ */
1001
1002 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
1003
1004 static void
1005 init_sigio_on_device (struct device *d)
1006 {
1007   int filedesc = DEVICE_INFD (d);
1008
1009 #if defined (FIOSSAIOOWN)
1010   { /* HPUX stuff */
1011     int owner = getpid ();
1012     int ioctl_status;
1013     if (DEVICE_TTY_P (d))
1014         {
1015           ioctl_status = ioctl (filedesc, FIOGSAIOOWN,
1016                                 &DEVICE_OLD_FCNTL_OWNER (d));
1017           ioctl_status = ioctl (filedesc, FIOSSAIOOWN, &owner);
1018         }
1019 #ifdef HAVE_WINDOW_SYSTEM
1020     else if (!DEVICE_STREAM_P (d))
1021       {
1022         ioctl_status = ioctl (filedesc, SIOCGPGRP,
1023                               &DEVICE_OLD_FCNTL_OWNER (d));
1024         ioctl_status = ioctl (filedesc, SIOCSPGRP, &owner);
1025       }
1026 #endif
1027   }
1028 #elif defined (F_SETOWN) && !defined (F_SETOWN_BUG)
1029   DEVICE_OLD_FCNTL_OWNER (d) = fcntl (filedesc, F_GETOWN, 0);
1030 # ifdef F_SETOWN_SOCK_NEG
1031   /* stdin is a socket here */
1032   fcntl (filedesc, F_SETOWN, -getpid ());
1033 # else
1034   fcntl (filedesc, F_SETOWN, getpid ());
1035 # endif
1036 #endif
1037 }
1038
1039 static void
1040 reset_sigio_on_device (struct device *d)
1041 {
1042   int filedesc = DEVICE_INFD (d);
1043
1044 #if defined (FIOSSAIOOWN)
1045   { /* HPUX stuff */
1046     int ioctl_status;
1047     if (DEVICE_TTY_P (d))
1048       {
1049         ioctl_status = ioctl (filedesc, FIOSSAIOOWN,
1050                               &DEVICE_OLD_FCNTL_OWNER (d));
1051       }
1052 #ifdef HAVE_WINDOW_SYSTEM
1053     else if (!DEVICE_STREAM_P (d))
1054       {
1055         ioctl_status = ioctl (filedesc, SIOCSPGRP,
1056                               &DEVICE_OLD_FCNTL_OWNER (d));
1057       }
1058 #endif
1059   }
1060 #elif defined (F_SETOWN) && !defined (F_SETOWN_BUG)
1061   fcntl (filedesc, F_SETOWN, DEVICE_OLD_FCNTL_OWNER (d));
1062 #endif
1063 }
1064
1065 static void
1066 request_sigio_on_device (struct device *d)
1067 {
1068   int filedesc = DEVICE_INFD (d);
1069
1070 #if defined (I_SETSIG) && !defined(HPUX10) && !defined(LINUX)
1071   {
1072     int events=0;
1073     ioctl (filedesc, I_GETSIG, &events);
1074     ioctl (filedesc, I_SETSIG, events | S_INPUT);
1075   }
1076 #elif defined (FASYNC)
1077   fcntl (filedesc, F_SETFL, fcntl (filedesc, F_GETFL, 0) | FASYNC);
1078 #elif defined (FIOSSAIOSTAT)
1079   {
1080       /* DG: Changed for HP-UX. HP-UX uses different IOCTLs for
1081          sockets and other devices for some bizarre reason. We guess
1082          that an X device is a socket, and tty devices aren't. We then
1083          use the following crud to do the appropriate thing. */
1084     int on = 1;
1085     int ioctl_status;           /* ####DG: check if IOCTL succeeds here. */
1086
1087     if (DEVICE_TTY_P (d))
1088       {
1089         ioctl_status = ioctl (filedesc, FIOSSAIOSTAT, &on);
1090       }
1091 #ifdef HAVE_WINDOW_SYSTEM
1092     else if (!DEVICE_STREAM_P (d))
1093       {
1094         ioctl_status = ioctl (filedesc, FIOASYNC, &on);
1095       }
1096 #endif
1097   }
1098 #elif defined (FIOASYNC)
1099   {
1100     int on = 1;
1101     ioctl (filedesc, FIOASYNC, &on);
1102   }
1103 #endif
1104
1105 #if defined (_CX_UX) /* #### Is this crap necessary? */
1106   EMACS_UNBLOCK_SIGNAL (SIGIO);
1107 #endif
1108 }
1109
1110 static void
1111 unrequest_sigio_on_device (struct device *d)
1112 {
1113   int filedesc = DEVICE_INFD (d);
1114
1115 #if defined (I_SETSIG) && !defined(HPUX10)
1116   {
1117     int events=0;
1118     ioctl (filedesc, I_GETSIG, &events);
1119     ioctl (filedesc, I_SETSIG, events & ~S_INPUT);
1120   }
1121 #elif defined (FASYNC)
1122   fcntl (filedesc, F_SETFL, fcntl (filedesc, F_GETFL, 0) & ~FASYNC);
1123 #elif defined (FIOSSAIOSTAT)
1124   {
1125       /* DG: Changed for HP-UX. HP-UX uses different IOCTLs for
1126          sockets and other devices for some bizarre reason. We guess
1127          that an X device is a socket, and tty devices aren't. We then
1128          use the following crud to do the appropriate thing. */
1129
1130     int off = 0;
1131     int ioctl_status;
1132
1133     /* See comment for request_sigio_on_device */
1134
1135     if (DEVICE_TTY_P (d))
1136       {
1137         ioctl_status = ioctl (filedesc, FIOSSAIOSTAT, &off);
1138       }
1139     else
1140       {
1141         ioctl_status = ioctl (filedesc, FIOASYNC, &off);
1142       }
1143   }
1144 #elif defined (FIOASYNC)
1145   {
1146     int off = 0;
1147     ioctl (filedesc, FIOASYNC, &off);
1148   }
1149 #endif
1150 }
1151
1152 void
1153 request_sigio (void)
1154 {
1155   Lisp_Object devcons, concons;
1156
1157   DEVICE_LOOP_NO_BREAK (devcons, concons)
1158     {
1159       struct device *d;
1160
1161       d = XDEVICE (XCAR (devcons));
1162
1163       if (!DEVICE_STREAM_P (d))
1164         request_sigio_on_device (d);
1165     }
1166 }
1167
1168 void
1169 unrequest_sigio (void)
1170 {
1171   Lisp_Object devcons, concons;
1172
1173   DEVICE_LOOP_NO_BREAK (devcons, concons)
1174     {
1175       struct device *d;
1176
1177       d = XDEVICE (XCAR (devcons));
1178
1179       if (!DEVICE_STREAM_P (d))
1180         unrequest_sigio_on_device (d);
1181     }
1182 }
1183
1184 #endif /* SIGIO */
1185 \f
1186 /* ------------------------------------------------------ */
1187 /*             Changing Emacs's process group             */
1188 /* ------------------------------------------------------ */
1189
1190 /* Saving and restoring the process group of Emacs's terminal.  */
1191
1192 /* On some systems, apparently (?!) Emacs must be in its own process
1193    group in order to receive SIGIO correctly.  On other systems
1194    (e.g. Solaris), it's not required and doing it makes things
1195    get fucked up.  So, we only do it when
1196    SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP is defined.  Basically,
1197    this is only required for BSD 4.2 systems. (Actually, I bet
1198    we don't have to do this at all -- those systems also
1199    required interrupt input, which we don't support.)
1200
1201    If Emacs was in its own process group (i.e. inherited_pgroup ==
1202    getpid ()), then we know we're running under a shell with job
1203    control (Emacs would never be run as part of a pipeline).
1204    Everything is fine.
1205
1206    If Emacs was not in its own process group, then we know we're
1207    running under a shell (or a caller) that doesn't know how to
1208    separate itself from Emacs (like sh).  Emacs must be in its own
1209    process group in order to receive SIGIO correctly.  In this
1210    situation, we put ourselves in our own pgroup, forcibly set the
1211    tty's pgroup to our pgroup, and make sure to restore and reinstate
1212    the tty's pgroup just like any other terminal setting.  If
1213    inherited_group was not the tty's pgroup, then we'll get a
1214    SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1215    it goes foreground in the future, which is what should happen.  */
1216
1217 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1218
1219 static int inherited_pgroup;
1220 static int inherited_tty_pgroup;
1221
1222 #endif
1223
1224 void
1225 munge_tty_process_group (void)
1226 {
1227 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1228   if (noninteractive)
1229     return;
1230
1231   /* Only do this munging if we have a device on the controlling
1232      terminal.  See the large comment below. */
1233
1234   if (CONSOLEP (Vcontrolling_terminal) &&
1235       CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)))
1236     {
1237       int fd = open ("/dev/tty", O_RDWR, 0);
1238       int me = getpid ();
1239       EMACS_BLOCK_SIGNAL (SIGTTOU);
1240       EMACS_SET_TTY_PROCESS_GROUP (fd, &me);
1241       EMACS_UNBLOCK_SIGNAL (SIGTTOU);
1242       close (fd);
1243     }
1244 #endif
1245 }
1246
1247 /* Split off the foreground process group to Emacs alone.
1248    When we are in the foreground, but not started in our own process
1249    group, redirect the TTY to point to our own process group.  We need
1250    to be in our own process group to receive SIGIO properly.  */
1251 static void
1252 munge_process_groups (void)
1253 {
1254 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1255   if (noninteractive)
1256     return;
1257
1258   EMACS_SEPARATE_PROCESS_GROUP ();
1259
1260   munge_tty_process_group ();
1261 #endif
1262 }
1263
1264 void
1265 unmunge_tty_process_group (void)
1266 {
1267 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1268   {
1269     int fd = open ("/dev/tty", O_RDWR, 0);
1270     EMACS_BLOCK_SIGNAL (SIGTTOU);
1271     EMACS_SET_TTY_PROCESS_GROUP (fd, &inherited_tty_pgroup);
1272     EMACS_UNBLOCK_SIGNAL (SIGTTOU);
1273     close (fd);
1274   }
1275 #endif
1276 }
1277
1278 /* Set the tty to our original foreground group.
1279    Also restore the original process group (put us back into sh's
1280    process group), so that ^Z will suspend both us and sh. */
1281 static void
1282 unmunge_process_groups (void)
1283 {
1284 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1285   if (noninteractive)
1286     return;
1287
1288   unmunge_tty_process_group ();
1289
1290   EMACS_SET_PROCESS_GROUP (inherited_pgroup);
1291 #endif
1292 }
1293
1294 /* According to some old wisdom, we need to be in a separate process
1295    group for SIGIO to work correctly (at least on some systems ...).
1296    So go ahead and put ourselves into our own process group.  This
1297    will fail if we're already in our own process group, but who cares.
1298    Also record whether we were in our own process group. (In general,
1299    we will already be in our own process group if we were started from
1300    a job-control shell like csh, but not if we were started from sh).
1301
1302    If we succeeded in changing our process group, then we will no
1303    longer be in the foreground process group of our controlling
1304    terminal.  Therefore, if we have a console open onto this terminal,
1305    we have to change the controlling terminal's foreground process
1306    group (otherwise we will get stopped with a SIGTTIN signal when
1307    attempting to read from the terminal).  It's important,
1308    however, that we do this *only* when we have a console open onto
1309    the terminal.  It's a decidedly bad idea to do so otherwise,
1310    especially if XEmacs was started from the background. */
1311
1312 void
1313 init_process_group (void)
1314 {
1315 #ifdef SIGIO_REQUIRES_SEPARATE_PROCESS_GROUP
1316   if (! noninteractive)
1317     {
1318       int fd = open ("/dev/tty", O_RDWR, 0);
1319       inherited_pgroup = EMACS_GET_PROCESS_GROUP ();
1320       EMACS_GET_TTY_PROCESS_GROUP (fd, &inherited_tty_pgroup);
1321       close (fd);
1322       EMACS_SEPARATE_PROCESS_GROUP ();
1323     }
1324 #endif
1325 }
1326
1327 void
1328 disconnect_controlling_terminal (void)
1329 {
1330 #  ifdef HAVE_SETSID
1331   /* Controlling terminals are attached to a session.
1332      Create a new session for us; it will have no controlling
1333      terminal.  This also, of course, puts us in our own
1334      process group. */
1335   setsid ();
1336 #  else
1337   /* Put us in our own process group. */
1338   EMACS_SEPARATE_PROCESS_GROUP ();
1339 #    if defined (TIOCNOTTY)
1340   /* This is the older way of disconnecting the controlling
1341      terminal, on 4.3 BSD.  We must open /dev/tty; using
1342      filedesc 0 is not sufficient because it could be
1343      something else (e.g. our stdin was redirected to
1344      another terminal).
1345      */
1346   {
1347     int j = open ("/dev/tty", O_RDWR, 0);
1348     ioctl (j, TIOCNOTTY, 0);
1349     close (j);
1350   }
1351 #    endif /* TIOCNOTTY */
1352   /*
1353      On systems without TIOCNOTTY and without
1354      setsid(), we don't need to do anything more to
1355      disconnect our controlling terminal.  Here is
1356      what the man page for termio(7) from a SYSV 3.2
1357      system says:
1358
1359      "The first terminal file opened by the process group leader
1360      of a terminal file not already associated with a process
1361      group becomes the control terminal for that process group.
1362      The control terminal plays a special role in handling quit
1363      and interrupt signals, as discussed below.  The control
1364      terminal is inherited by a child process during a fork(2).
1365      A process can break this association by changing its process
1366      group using setpgrp(2)."
1367
1368      */
1369 #  endif /* not HAVE_SETSID */
1370 }
1371
1372 \f
1373 /* ------------------------------------------------------ */
1374 /*        Getting and setting emacs_tty structures        */
1375 /* ------------------------------------------------------ */
1376
1377 /* It's wrong to encase these into #ifdef HAVE_TTY because we need
1378    them for child TTY processes.  */
1379 /* However, this does break NT support while we don't do child TTY processes */
1380 #ifndef WINDOWSNT
1381
1382 /* Set *TC to the parameters associated with the terminal FD.
1383    Return zero if all's well, or -1 if we ran into an error we
1384    couldn't deal with.  */
1385 int
1386 emacs_get_tty (int fd, struct emacs_tty *settings)
1387 {
1388   /* Retrieve the primary parameters - baud rate, character size, etcetera.  */
1389 #ifdef HAVE_TCATTR
1390   /* We have those nifty POSIX tcmumbleattr functions.  */
1391   if (tcgetattr (fd, &settings->main) < 0)
1392     return -1;
1393
1394 #elif defined HAVE_TERMIO
1395   /* The SYSV-style interface?  */
1396   if (ioctl (fd, TCGETA, &settings->main) < 0)
1397     return -1;
1398
1399 #elif !defined (WINDOWSNT)
1400   /* I give up - I hope you have the BSD ioctls.  */
1401   if (ioctl (fd, TIOCGETP, &settings->main) < 0)
1402     return -1;
1403 #endif /* HAVE_TCATTR */
1404
1405   /* Suivant - Do we have to get struct ltchars data?  */
1406 #ifdef HAVE_LTCHARS
1407   if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
1408     return -1;
1409 #endif
1410
1411   /* How about a struct tchars and a wordful of lmode bits?  */
1412 #ifdef HAVE_TCHARS
1413   if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
1414       || ioctl (fd, TIOCLGET, &settings->lmode) < 0)
1415     return -1;
1416 #endif
1417
1418   /* We have survived the tempest.  */
1419   return 0;
1420 }
1421
1422 /* Set the parameters of the tty on FD according to the contents of
1423    *SETTINGS.  If FLUSHP is non-zero, we discard input.
1424    Return 0 if all went well, and -1 if anything failed.
1425    #### All current callers use FLUSHP == 0. */
1426
1427 int
1428 emacs_set_tty (int fd, struct emacs_tty *settings, int flushp)
1429 {
1430   /* Set the primary parameters - baud rate, character size, etcetera.  */
1431 #ifdef HAVE_TCATTR
1432   int i;
1433   /* We have those nifty POSIX tcmumbleattr functions.
1434      William J. Smith <wjs@wiis.wang.com> writes:
1435      "POSIX 1003.1 defines tcsetattr() to return success if it was
1436      able to perform any of the requested actions, even if some
1437      of the requested actions could not be performed.
1438      We must read settings back to ensure tty setup properly.
1439      AIX requires this to keep tty from hanging occasionally."  */
1440   /* This makes sure that we don't loop indefinitely in here.  */
1441   for (i = 0 ; i < 10 ; i++)
1442     if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
1443       {
1444         if (errno == EINTR)
1445           continue;
1446         else
1447           return -1;
1448       }
1449     else
1450       {
1451         struct termios new;
1452
1453         /* Get the current settings, and see if they're what we asked for.  */
1454         tcgetattr (fd, &new);
1455         /* We cannot use memcmp on the whole structure here because under
1456          * aix386 the termios structure has some reserved field that may
1457          * not be filled in.
1458          */
1459         if (   new.c_iflag == settings->main.c_iflag
1460             && new.c_oflag == settings->main.c_oflag
1461             && new.c_cflag == settings->main.c_cflag
1462             && new.c_lflag == settings->main.c_lflag
1463             && memcmp(new.c_cc, settings->main.c_cc, NCCS) == 0)
1464           break;
1465         else
1466           continue;
1467       }
1468 #elif defined HAVE_TERMIO
1469   /* The SYSV-style interface?  */
1470   if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
1471     return -1;
1472
1473 #elif !defined (WINDOWSNT)
1474   /* I give up - I hope you have the BSD ioctls.  */
1475   if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
1476     return -1;
1477 #endif /* HAVE_TCATTR */
1478
1479   /* Suivant - Do we have to get struct ltchars data?  */
1480 #ifdef HAVE_LTCHARS
1481   if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
1482     return -1;
1483 #endif
1484
1485   /* How about a struct tchars and a wordful of lmode bits?  */
1486 #ifdef HAVE_TCHARS
1487   if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
1488       || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
1489     return -1;
1490 #endif
1491
1492   /* We have survived the tempest.  */
1493   return 0;
1494 }
1495
1496 #endif /* WINDOWSNT */
1497 \f
1498 /* ------------------------------------------------------ */
1499 /*                 Initializing a device                  */
1500 /* ------------------------------------------------------ */
1501
1502 #ifdef HAVE_TTY
1503
1504 /* This may also be defined in stdio,
1505    but if so, this does no harm,
1506    and using the same name avoids wasting the other one's space.  */
1507
1508 #if ((defined(USG) || defined(DGUX)) && !defined(__STDC__))
1509 char _sobuf[BUFSIZ+8];
1510 #elif (defined(USG) && !defined(LINUX) && !defined(_SCO_DS)) || defined(IRIX5)
1511 extern unsigned char _sobuf[BUFSIZ+8];
1512 #else
1513 char _sobuf[BUFSIZ];
1514 #endif
1515
1516 #if defined (TIOCGLTC) && defined (HAVE_LTCHARS) /* HAVE_LTCHARS */
1517 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
1518 #endif
1519 #ifdef TIOCGETC /* HAVE_TCHARS */
1520 #ifdef HAVE_TCHARS
1521 static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
1522 #endif
1523 #endif
1524
1525 static void
1526 tty_init_sys_modes_on_device (struct device *d)
1527 {
1528   struct emacs_tty tty;
1529   int input_fd, output_fd;
1530   struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
1531
1532   input_fd = CONSOLE_TTY_DATA (con)->infd;
1533   output_fd = CONSOLE_TTY_DATA (con)->outfd;
1534
1535   emacs_get_tty (input_fd, &CONSOLE_TTY_DATA (con)->old_tty);
1536   tty = CONSOLE_TTY_DATA (con)->old_tty;
1537
1538   con->tty_erase_char = Qnil;
1539
1540 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1541   /* after all those years... */
1542   con->tty_erase_char = make_char (tty.main.c_cc[VERASE]);
1543 #ifdef DGUX
1544   /* This allows meta to be sent on 8th bit.  */
1545   tty.main.c_iflag &= ~INPCK;   /* don't check input for parity */
1546 #endif
1547   tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
1548   tty.main.c_iflag &= ~ICRNL;   /* Disable map of CR to NL on input */
1549 #ifdef ISTRIP
1550   tty.main.c_iflag &= ~ISTRIP;  /* don't strip 8th bit on input */
1551 #endif
1552   tty.main.c_lflag &= ~ECHO;    /* Disable echo */
1553   tty.main.c_lflag &= ~ICANON;  /* Disable erase/kill processing */
1554 #ifdef IEXTEN
1555   tty.main.c_lflag &= ~IEXTEN;  /* Disable other editing characters.  */
1556 #endif
1557   tty.main.c_lflag |= ISIG;     /* Enable signals */
1558   if (TTY_FLAGS (con).flow_control)
1559     {
1560       tty.main.c_iflag |= IXON; /* Enable start/stop output control */
1561 #ifdef IXANY
1562       tty.main.c_iflag &= ~IXANY;
1563 #endif /* IXANY */
1564     }
1565   else
1566     tty.main.c_iflag &= ~IXON;  /* Disable start/stop output control */
1567   tty.main.c_oflag &= ~ONLCR;   /* Disable map of NL to CR-NL
1568                                    on output */
1569   tty.main.c_oflag &= ~TAB3;    /* Disable tab expansion */
1570 #ifdef CS8
1571   if (TTY_FLAGS (con).meta_key)
1572     {
1573       tty.main.c_cflag |= CS8;  /* allow 8th bit on input */
1574       tty.main.c_cflag &= ~PARENB;/* Don't check parity */
1575     }
1576 #endif
1577   if (CONSOLE_TTY_DATA (con)->controlling_terminal)
1578     {
1579       tty.main.c_cc[VINTR] =
1580         CONSOLE_QUIT_CHAR (con); /* C-g (usually) gives SIGINT */
1581       /* Set up C-g for both SIGQUIT and SIGINT.
1582          We don't know which we will get, but we handle both alike
1583          so which one it really gives us does not matter.  */
1584       tty.main.c_cc[VQUIT] = CONSOLE_QUIT_CHAR (con);
1585     }
1586   else
1587     {
1588       tty.main.c_cc[VINTR] = _POSIX_VDISABLE;
1589       tty.main.c_cc[VQUIT] = _POSIX_VDISABLE;
1590     }
1591   tty.main.c_cc[VMIN] = 1;      /* Input should wait for at
1592                                    least 1 char */
1593   tty.main.c_cc[VTIME] = 0;     /* no matter how long that takes.  */
1594 #ifdef VSWTCH
1595   tty.main.c_cc[VSWTCH] = _POSIX_VDISABLE; /* Turn off shell layering use
1596                                               of C-z */
1597 #endif /* VSWTCH */
1598   /* There was some conditionalizing here on (mips or TCATTR), but
1599      I think that's wrong.  There was one report of C-y (DSUSP) not being
1600      disabled on HP9000s700 systems, and this might fix it. */
1601 #ifdef VSUSP
1602   tty.main.c_cc[VSUSP] = _POSIX_VDISABLE; /* Turn off mips handling of C-z. */
1603 #endif /* VSUSP */
1604 #ifdef V_DSUSP
1605   tty.main.c_cc[V_DSUSP] = _POSIX_VDISABLE; /* Turn off mips handling of C-y. */
1606 #endif /* V_DSUSP */
1607 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP.  */
1608   tty.main.c_cc[VDSUSP] = _POSIX_VDISABLE;
1609 #endif /* VDSUSP */
1610 #ifdef VLNEXT
1611   tty.main.c_cc[VLNEXT] = _POSIX_VDISABLE;
1612 #endif /* VLNEXT */
1613 #ifdef VREPRINT
1614   tty.main.c_cc[VREPRINT] = _POSIX_VDISABLE;
1615 #endif /* VREPRINT */
1616 #ifdef VWERASE
1617   tty.main.c_cc[VWERASE] = _POSIX_VDISABLE;
1618 #endif /* VWERASE */
1619 #ifdef VDISCARD
1620   tty.main.c_cc[VDISCARD] = _POSIX_VDISABLE;
1621 #endif /* VDISCARD */
1622 #ifdef VSTART
1623   tty.main.c_cc[VSTART] = _POSIX_VDISABLE;
1624 #endif /* VSTART */
1625 #ifdef VSTRT
1626   tty.main.c_cc[VSTRT] = _POSIX_VDISABLE; /* called VSTRT on some systems */
1627 #endif /* VSTART */
1628 #ifdef VSTOP
1629   tty.main.c_cc[VSTOP] = _POSIX_VDISABLE;
1630 #endif /* VSTOP */
1631 #ifdef SET_LINE_DISCIPLINE
1632   /* Need to explicitly request TERMIODISC line discipline or
1633      Ultrix's termios does not work correctly.  */
1634   tty.main.c_line = SET_LINE_DISCIPLINE;
1635 #endif
1636
1637 #ifdef AIX
1638 #ifndef IBMR2AIX
1639   /* AIX enhanced edit loses NULs, so disable it. */
1640   tty.main.c_line = 0;
1641   tty.main.c_iflag &= ~ASCEDIT;
1642 #else
1643   tty.main.c_cc[VSTRT] = 255;
1644   tty.main.c_cc[VSTOP] = 255;
1645   tty.main.c_cc[VSUSP] = 255;
1646   tty.main.c_cc[VDSUSP] = 255;
1647 #endif /* IBMR2AIX */
1648   /* Also, PTY overloads NUL and BREAK.
1649      don't ignore break, but don't signal either, so it looks like NUL.
1650      This really serves a purpose only if running in an XTERM window
1651      or via TELNET or the like, but does no harm elsewhere.  */
1652   tty.main.c_iflag &= ~IGNBRK;
1653   tty.main.c_iflag &= ~BRKINT;
1654 #endif /* AIX */
1655 #else /* if not HAVE_TERMIO */
1656 #if !defined (WINDOWSNT)
1657   con->tty_erase_char = make_char (tty.main.sg_erase);
1658   tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1659   if (TTY_FLAGS (con).meta_key)
1660     tty.main.sg_flags |= ANYP;
1661   /* #### should we be using RAW mode here? */
1662   tty.main.sg_flags |= /* interrupt_input ? RAW : */ CBREAK;
1663 #endif /* not WINDOWSNT */
1664 #endif /* not HAVE_TERMIO */
1665
1666   /* If going to use CBREAK mode, we must request C-g to interrupt
1667      and turn off start and stop chars, etc.  If not going to use
1668      CBREAK mode, do this anyway so as to turn off local flow
1669      control for user coming over network on 4.2; in this case,
1670      only t_stopc and t_startc really matter.  */
1671 #ifndef HAVE_TERMIO
1672 #ifdef HAVE_TCHARS
1673   /* Note: if not using CBREAK mode, it makes no difference how we
1674      set this */
1675   tty.tchars = new_tchars;
1676   tty.tchars.t_intrc = CONSOLE_QUIT_CHAR (con);
1677   if (TTY_FLAGS (con).flow_control)
1678     {
1679       tty.tchars.t_startc = '\021';
1680       tty.tchars.t_stopc = '\023';
1681     }
1682
1683   tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH |
1684     CONSOLE_TTY_DATA (con)->old_tty.lmode;
1685
1686 #if defined (ultrix) || defined (__bsdi__)
1687   /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1688      anything, and leaving it in breaks the meta key.  Go figure.  */
1689   /* Turning off ONLCR is enough under BSD/386.  Leave the general
1690      output post-processing flag alone since for some reason it
1691      doesn't get reset after XEmacs goes away. */
1692   tty.lmode &= ~LLITOUT;
1693 #endif
1694
1695 #endif /* HAVE_TCHARS */
1696 #endif /* not HAVE_TERMIO */
1697
1698 #ifdef HAVE_LTCHARS
1699   tty.ltchars = new_ltchars;
1700 #endif /* HAVE_LTCHARS */
1701
1702   emacs_set_tty (input_fd, &tty, 0);
1703
1704   /* This code added to insure that, if flow-control is not to be used,
1705      we have an unlocked terminal at the start. */
1706
1707 #ifdef TCXONC
1708   if (!TTY_FLAGS (con).flow_control) ioctl (input_fd, TCXONC, 1);
1709 #endif
1710 #ifdef TIOCSTART
1711   if (!TTY_FLAGS (con).flow_control) ioctl (input_fd, TIOCSTART, 0);
1712 #endif
1713
1714 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1715 #ifdef TCOON
1716   if (!TTY_FLAGS (con).flow_control) tcflow (input_fd, TCOON);
1717 #endif
1718 #endif
1719 #ifdef AIXHFT
1720   hft_init (con);
1721 #ifdef IBMR2AIX
1722   {
1723     /* IBM's HFT device usually thinks a ^J should be LF/CR.
1724        We need it to be only LF.  This is the way that is
1725        done. */
1726     struct termio tty;
1727
1728     if (ioctl (output_fd, HFTGETID, &tty) != -1)
1729       write (output_fd, "\033[20l", 5);
1730   }
1731 #endif
1732 #endif
1733
1734 #if 0 /* We do our own buffering with lstreams. */
1735 #ifdef _IOFBF
1736   /* This symbol is defined on recent USG systems.
1737      Someone says without this call USG won't really buffer the file
1738      even with a call to setbuf. */
1739   setvbuf (CONSOLE_TTY_DATA (con)->outfd, (char *) _sobuf, _IOFBF, sizeof _sobuf);
1740 #else
1741   setbuf (CONSOLE_TTY_DATA (con)->outfd, (char *) _sobuf);
1742 #endif
1743 #endif
1744   set_tty_modes (con);
1745 }
1746
1747 #endif /* HAVE_TTY */
1748
1749 void
1750 init_one_device (struct device *d)
1751 {
1752 #ifdef HAVE_TTY
1753   if (DEVICE_TTY_P (d))
1754     tty_init_sys_modes_on_device (d);
1755 #endif
1756 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
1757   if (!DEVICE_STREAM_P (d))
1758     {
1759       init_sigio_on_device (d);
1760       request_sigio_on_device (d);
1761     }
1762 #endif
1763 }
1764
1765 void
1766 init_one_console (struct console *con)
1767 {
1768   Lisp_Object devcons;
1769
1770   CONSOLE_DEVICE_LOOP (devcons, con)
1771     {
1772       struct device *d = XDEVICE (XCAR (devcons));
1773
1774       init_one_device (d);
1775     }
1776 }
1777
1778 void
1779 reinit_initial_console (void)
1780 {
1781   munge_process_groups ();
1782   if (CONSOLEP (Vcontrolling_terminal) &&
1783       CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)))
1784     init_one_console (XCONSOLE (Vcontrolling_terminal));
1785 }
1786
1787 \f
1788 /* ------------------------------------------------------ */
1789 /*                   Other TTY functions                  */
1790 /* ------------------------------------------------------ */
1791
1792 #ifdef HAVE_TTY
1793
1794 #if 0 /* not currently used */
1795
1796 /* Return nonzero if safe to use tabs in output.
1797    At the time this is called, init_sys_modes has not been done yet.  */
1798
1799 int
1800 tabs_safe_p (struct device *d)
1801 {
1802 #ifdef HAVE_TTY
1803   if (DEVICE_TTY_P (d))
1804     {
1805       struct emacs_tty tty;
1806
1807       emacs_get_tty (DEVICE_INFD (d), &tty);
1808       return EMACS_TTY_TABS_OK (&tty);
1809     }
1810 #endif
1811   return 1;
1812 }
1813
1814 #endif /* 0 */
1815
1816 /* Get terminal size from system.
1817    Store number of lines into *heightp and width into *widthp.
1818    If zero or a negative number is stored, the value is not valid.  */
1819
1820 void
1821 get_tty_device_size (struct device *d, int *widthp, int *heightp)
1822 {
1823   int input_fd = DEVICE_INFD (d);
1824
1825   assert (DEVICE_TTY_P (d));
1826
1827 #ifdef TIOCGWINSZ
1828   {
1829     /* BSD-style.  */
1830     struct winsize size;
1831
1832     if (ioctl (input_fd, TIOCGWINSZ, &size) == -1)
1833       *widthp = *heightp = 0;
1834     else
1835       {
1836         *widthp = size.ws_col;
1837         *heightp = size.ws_row;
1838       }
1839   }
1840 #elif defined TIOCGSIZE
1841   {
1842     /* SunOS - style.  */
1843     struct ttysize size;
1844
1845     if (ioctl (input_fd, TIOCGSIZE, &size) == -1)
1846       *widthp = *heightp = 0;
1847     else
1848       {
1849         *widthp = size.ts_cols;
1850         *heightp = size.ts_lines;
1851       }
1852   }
1853 #else /* system doesn't know size */
1854
1855   *widthp = 0;
1856   *heightp = 0;
1857
1858 #endif /* not !TIOCGWINSZ */
1859 }
1860
1861 #endif /* HAVE_TTY */
1862
1863 \f
1864 /* ------------------------------------------------------ */
1865 /*                   Is device 8 bit ?                    */
1866 /* ------------------------------------------------------ */
1867
1868 #ifdef HAVE_TTY
1869
1870 int
1871 eight_bit_tty (struct device *d)
1872 {
1873   struct emacs_tty s;
1874   int input_fd;
1875   int eight_bit = 0;
1876
1877   assert (DEVICE_TTY_P (d));
1878   input_fd = DEVICE_INFD (d);
1879
1880   emacs_get_tty (input_fd, &s);
1881
1882 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1883   eight_bit = (s.main.c_cflag & CSIZE) == CS8;
1884 #else
1885   eight_bit = 0;        /* I don't know how to do it */
1886 #endif
1887   return eight_bit;
1888 }
1889
1890 #endif /* HAVE_TTY */
1891
1892 \f
1893 /* ------------------------------------------------------ */
1894 /*                   Resetting a device                   */
1895 /* ------------------------------------------------------ */
1896
1897 #ifdef HAVE_TTY
1898
1899 /* Prepare the terminal for exiting Emacs; move the cursor to the
1900    bottom of the frame, turn off interrupt-driven I/O, etc.  */
1901 static void
1902 tty_reset_sys_modes_on_device (struct device *d)
1903 {
1904   int input_fd, output_fd;
1905   struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
1906
1907   input_fd = CONSOLE_TTY_DATA (con)->infd;
1908   output_fd = CONSOLE_TTY_DATA (con)->outfd;
1909
1910 #if defined (IBMR2AIX) && defined (AIXHFT)
1911   {
1912     /* HFT consoles normally use ^J as a LF/CR.  We forced it to
1913        do the LF only.  Now, we need to reset it. */
1914     struct termio tty;
1915
1916     if (ioctl (output_fd, HFTGETID, &tty) != -1)
1917       write (output_fd, "\033[20h", 5);
1918   }
1919 #endif
1920
1921   tty_redisplay_shutdown (con);
1922   /* reset_tty_modes() flushes the connection at its end. */
1923   reset_tty_modes (con);
1924
1925 #if defined (BSD)
1926   /* Avoid possible loss of output when changing terminal modes.  */
1927   fsync (output_fd);
1928 #endif
1929
1930   while (emacs_set_tty (input_fd, &CONSOLE_TTY_DATA (con)->old_tty, 0)
1931          < 0 && errno == EINTR)
1932     ;
1933
1934 #ifdef SET_LINE_DISCIPLINE
1935   /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1936      A different old line discipline is therefore not restored, yet.
1937      Restore the old line discipline by hand.  */
1938   ioctl (input_fd, TIOCSETD, &old_tty.main.c_line);
1939 #endif
1940
1941 #ifdef AIXHFT
1942   hft_reset (con);
1943 #endif
1944
1945 }
1946
1947 #endif /* HAVE_TTY */
1948
1949 void
1950 reset_one_device (struct device *d)
1951 {
1952 #ifdef HAVE_TTY
1953   if (DEVICE_TTY_P (d))
1954     tty_reset_sys_modes_on_device (d);
1955   else
1956 #endif
1957   if (DEVICE_STREAM_P (d))
1958     fflush (CONSOLE_STREAM_DATA (XCONSOLE (DEVICE_CONSOLE (d)))->out);
1959 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
1960   if (!DEVICE_STREAM_P (d))
1961     {
1962       unrequest_sigio_on_device (d);
1963       reset_sigio_on_device (d);
1964     }
1965 #endif
1966 }
1967
1968 void
1969 reset_one_console (struct console *con)
1970 {
1971   /* Note: this can be called during GC. */
1972   Lisp_Object devcons;
1973
1974   CONSOLE_DEVICE_LOOP (devcons, con)
1975     {
1976       struct device *d = XDEVICE (XCAR (devcons));
1977
1978       reset_one_device (d);
1979     }
1980 }
1981
1982 void
1983 reset_all_consoles (void)
1984 {
1985   /* Note: this can be called during GC. */
1986   Lisp_Object concons;
1987
1988   CONSOLE_LOOP (concons)
1989     {
1990       struct console *con = XCONSOLE (XCAR (concons));
1991
1992       reset_one_console (con);
1993     }
1994
1995   unmunge_process_groups ();
1996 }
1997
1998 void
1999 reset_initial_console (void)
2000 {
2001   if (CONSOLEP (Vcontrolling_terminal) &&
2002       CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)))
2003     reset_one_console (XCONSOLE (Vcontrolling_terminal));
2004   unmunge_process_groups ();
2005 }
2006
2007 \f
2008 /* ------------------------------------------------------ */
2009 /*                 extra TTY stuff under AIX              */
2010 /* ------------------------------------------------------ */
2011
2012 #ifdef AIXHFT
2013
2014 /* Called from init_sys_modes.  */
2015 static void
2016 hft_init (struct console *con)
2017 {
2018   int junk;
2019   int input_fd;
2020
2021   assert (CONSOLE_TTY_P (con));
2022   input_fd = CONSOLE_TTY_DATA (con)->infd;
2023
2024   /* If we're not on an HFT we shouldn't do any of this.  We determine
2025      if we are on an HFT by trying to get an HFT error code.  If this
2026      call fails, we're not on an HFT. */
2027 #ifdef IBMR2AIX
2028   if (ioctl (input_fd, HFQERROR, &junk) < 0)
2029     return;
2030 #else /* not IBMR2AIX */
2031   if (ioctl (input_fd, HFQEIO, 0) < 0)
2032     return;
2033 #endif /* not IBMR2AIX */
2034
2035   /* On AIX the default hft keyboard mapping uses backspace rather than delete
2036      as the rubout key's ASCII code.  Here this is changed.  The bug is that
2037      there's no way to determine the old mapping, so in reset_one_console
2038      we need to assume that the normal map had been present.  Of course, this
2039      code also doesn't help if on a terminal emulator which doesn't understand
2040      HFT VTD's. */
2041   {
2042     struct hfbuf buf;
2043     struct hfkeymap keymap;
2044
2045     buf.hf_bufp = (char *)&keymap;
2046     buf.hf_buflen = sizeof (keymap);
2047     keymap.hf_nkeys = 2;
2048     keymap.hfkey[0].hf_kpos = 15;
2049     keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
2050 #ifdef IBMR2AIX
2051     keymap.hfkey[0].hf_keyidh = '<';
2052 #else /* not IBMR2AIX */
2053     keymap.hfkey[0].hf_page = '<';
2054 #endif /* not IBMR2AIX */
2055     keymap.hfkey[0].hf_char = 127;
2056     keymap.hfkey[1].hf_kpos = 15;
2057     keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
2058 #ifdef IBMR2AIX
2059     keymap.hfkey[1].hf_keyidh = '<';
2060 #else /* not IBMR2AIX */
2061     keymap.hfkey[1].hf_page = '<';
2062 #endif /* not IBMR2AIX */
2063     keymap.hfkey[1].hf_char = 127;
2064     hftctl (input_fd, HFSKBD, &buf);
2065   }
2066   /* #### Should probably set a console TTY flag here. */
2067 #if 0
2068   /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
2069      at times. */
2070   line_ins_del_ok = char_ins_del_ok = 0;
2071 #endif /* 0 */
2072 }
2073
2074 /* Reset the rubout key to backspace. */
2075
2076 static void
2077 hft_reset (struct console *con)
2078 {
2079   struct hfbuf buf;
2080   struct hfkeymap keymap;
2081   int junk;
2082   int input_fd;
2083
2084   assert (CONSOLE_TTY_P (con));
2085   input_fd = CONSOLE_TTY_DATA (con)->infd;
2086
2087 #ifdef IBMR2AIX
2088   if (ioctl (input_fd, HFQERROR, &junk) < 0)
2089     return;
2090 #else /* not IBMR2AIX */
2091   if (ioctl (input_fd, HFQEIO, 0) < 0)
2092     return;
2093 #endif /* not IBMR2AIX */
2094
2095   buf.hf_bufp = (char *)&keymap;
2096   buf.hf_buflen = sizeof (keymap);
2097   keymap.hf_nkeys = 2;
2098   keymap.hfkey[0].hf_kpos = 15;
2099   keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
2100 #ifdef IBMR2AIX
2101   keymap.hfkey[0].hf_keyidh = '<';
2102 #else /* not IBMR2AIX */
2103   keymap.hfkey[0].hf_page = '<';
2104 #endif /* not IBMR2AIX */
2105   keymap.hfkey[0].hf_char = 8;
2106   keymap.hfkey[1].hf_kpos = 15;
2107   keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
2108 #ifdef IBMR2AIX
2109   keymap.hfkey[1].hf_keyidh = '<';
2110 #else /* not IBMR2AIX */
2111   keymap.hfkey[1].hf_page = '<';
2112 #endif /* not IBMR2AIX */
2113   keymap.hfkey[1].hf_char = 8;
2114   hftctl (input_fd, HFSKBD, &buf);
2115 }
2116
2117 #endif /* AIXHFT */
2118
2119 \f
2120 /************************************************************************/
2121 /*                    limits of text/data segments                      */
2122 /************************************************************************/
2123
2124 #if !defined(CANNOT_DUMP) && !defined(PDUMP)
2125 #define NEED_STARTS
2126 #endif
2127
2128 #ifndef SYSTEM_MALLOC
2129 #ifndef NEED_STARTS
2130 #define NEED_STARTS
2131 #endif
2132 #endif
2133
2134 #ifdef NEED_STARTS
2135 /* Some systems that cannot dump also cannot implement these.  */
2136
2137 /*
2138  *      Return the address of the start of the text segment prior to
2139  *      doing an unexec.  After unexec the return value is undefined.
2140  *      See crt0.c for further explanation and _start.
2141  *
2142  */
2143
2144 #if !defined(HAVE_TEXT_START) && !defined(PDUMP)
2145
2146 #ifdef __cplusplus
2147   extern "C" int _start (void);
2148 #else
2149   extern int _start (void);
2150 #endif
2151
2152 char *
2153 start_of_text (void)
2154 {
2155 #ifdef TEXT_START
2156   return ((char *) TEXT_START);
2157 #else
2158 #ifdef GOULD
2159   extern csrt ();
2160   return ((char *) csrt);
2161 #else /* not GOULD */
2162   return ((char *) _start);
2163 #endif /* GOULD */
2164 #endif /* TEXT_START */
2165 }
2166 #endif /* !defined(HAVE_TEXT_START) && !defined(PDUMP) */
2167
2168 /*
2169  *      Return the address of the start of the data segment prior to
2170  *      doing an unexec.  After unexec the return value is undefined.
2171  *      See crt0.c for further information and definition of data_start.
2172  *
2173  *      Apparently, on BSD systems this is etext at startup.  On
2174  *      USG systems (swapping) this is highly mmu dependent and
2175  *      is also dependent on whether or not the program is running
2176  *      with shared text.  Generally there is a (possibly large)
2177  *      gap between end of text and start of data with shared text.
2178  *
2179  *      On Uniplus+ systems with shared text, data starts at a
2180  *      fixed address.  Each port (from a given oem) is generally
2181  *      different, and the specific value of the start of data can
2182  *      be obtained via the UniPlus+ specific "uvar" system call,
2183  *      however the method outlined in crt0.c seems to be more portable.
2184  *
2185  *      Probably what will have to happen when a USG unexec is available,
2186  *      at least on UniPlus, is temacs will have to be made unshared so
2187  *      that text and data are contiguous.  Then once loadup is complete,
2188  *      unexec will produce a shared executable where the data can be
2189  *      at the normal shared text boundary and the startofdata variable
2190  *      will be patched by unexec to the correct value.
2191  *
2192  */
2193
2194 #ifdef ORDINARY_LINK
2195 extern char **environ;
2196 #endif
2197
2198 void *
2199 start_of_data (void)
2200 {
2201 #ifdef DATA_START
2202   return ((char *) DATA_START);
2203 #else
2204 #ifdef ORDINARY_LINK
2205   /*
2206    * This is a hack.  Since we're not linking crt0.c or pre_crt0.c,
2207    * data_start isn't defined.  We take the address of environ, which
2208    * is known to live at or near the start of the system crt0.c, and
2209    * we don't sweat the handful of bytes that might lose.
2210    */
2211 #ifdef HEAP_IN_DATA
2212   extern char* static_heap_base;
2213   if (!initialized)
2214     return static_heap_base;
2215 #endif
2216   return((char *) &environ);
2217 #else
2218   extern int data_start;
2219   return ((char *) &data_start);
2220 #endif /* ORDINARY_LINK */
2221 #endif /* DATA_START */
2222 }
2223 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2224
2225 #if !defined(CANNOT_DUMP) && !defined(PDUMP)
2226 /* Some systems that cannot dump also cannot implement these.  */
2227
2228 /*
2229  *      Return the address of the end of the text segment prior to
2230  *      doing an unexec.  After unexec the return value is undefined.
2231  */
2232
2233 char *
2234 end_of_text (void)
2235 {
2236 #ifdef TEXT_END
2237   return ((char *) TEXT_END);
2238 #else
2239   extern int etext;
2240   return ((char *) &etext);
2241 #endif
2242 }
2243
2244 /*
2245  *      Return the address of the end of the data segment prior to
2246  *      doing an unexec.  After unexec the return value is undefined.
2247  */
2248
2249 char *
2250 end_of_data (void)
2251 {
2252 #ifdef DATA_END
2253   return ((char *) DATA_END);
2254 #else
2255   extern int edata;
2256   return ((char *) &edata);
2257 #endif
2258 }
2259
2260 #endif /* !defined(CANNOT_DUMP) && !defined(PDUMP) */
2261
2262 \f
2263 /************************************************************************/
2264 /*                          get the system name                         */
2265 /************************************************************************/
2266
2267 /* init_system_name sets up the string for the Lisp function
2268    system-name to return. */
2269
2270 extern Lisp_Object Vsystem_name;
2271
2272 #ifdef HAVE_SOCKETS
2273 # include <sys/socket.h>
2274 # include <netdb.h>
2275 #endif /* HAVE_SOCKETS */
2276
2277 void
2278 init_system_name (void)
2279 {
2280 #if defined (WINDOWSNT)
2281   char hostname [MAX_COMPUTERNAME_LENGTH + 1];
2282   size_t size = sizeof (hostname);
2283   GetComputerName (hostname, &size);
2284   Vsystem_name = build_string (hostname);
2285 #elif !defined (HAVE_GETHOSTNAME)
2286   struct utsname uts;
2287   uname (&uts);
2288   Vsystem_name = build_string (uts.nodename);
2289 #else /* HAVE_GETHOSTNAME */
2290   unsigned int hostname_size = 256;
2291   char *hostname = (char *) alloca (hostname_size);
2292
2293   /* Try to get the host name; if the buffer is too short, try
2294      again.  Apparently, the only indication gethostname gives of
2295      whether the buffer was large enough is the presence or absence
2296      of a '\0' in the string.  Eech.  */
2297   for (;;)
2298     {
2299       gethostname (hostname, hostname_size - 1);
2300       hostname[hostname_size - 1] = '\0';
2301
2302       /* Was the buffer large enough for the '\0'?  */
2303       if (strlen (hostname) < (size_t) (hostname_size - 1))
2304         break;
2305
2306       hostname_size <<= 1;
2307       hostname = (char *) alloca (hostname_size);
2308     }
2309 # if defined( HAVE_SOCKETS) && !defined(BROKEN_CYGWIN)
2310   /* Turn the hostname into the official, fully-qualified hostname.
2311      Don't do this if we're going to dump; this can confuse system
2312      libraries on some machines and make the dumped emacs core dump. */
2313 #  ifndef CANNOT_DUMP
2314   if (initialized)
2315 #  endif /* not CANNOT_DUMP */
2316     if (!strchr (hostname, '.'))
2317       {
2318 #  if !(defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO))
2319         struct hostent *hp = NULL;
2320         int count;
2321 #   ifdef TRY_AGAIN
2322         for (count = 0; count < 10; count++)
2323           {
2324             h_errno = 0;
2325 #   endif
2326             /* Some systems can't handle SIGALARM/SIGIO in gethostbyname(). */
2327             stop_interrupts ();
2328             hp = gethostbyname (hostname);
2329             start_interrupts ();
2330 #   ifdef TRY_AGAIN
2331             if (! (hp == 0 && h_errno == TRY_AGAIN))
2332               break;
2333             Fsleep_for (make_int (1));
2334           }
2335 #   endif
2336         if (hp)
2337           {
2338             CONST char *fqdn = (CONST char *) hp->h_name;
2339
2340             if (!strchr (fqdn, '.'))
2341               {
2342                 /* We still don't have a fully qualified domain name.
2343                    Try to find one in the list of alternate names */
2344                 char **alias = hp->h_aliases;
2345                 while (*alias && !strchr (*alias, '.'))
2346                   alias++;
2347                 if (*alias)
2348                   fqdn = *alias;
2349               }
2350             hostname = (char *) alloca (strlen (fqdn) + 1);
2351             strcpy (hostname, fqdn);
2352           }
2353 #  else /* !(HAVE_GETADDRINFO && HAVE_GETNAMEINFO) */
2354         struct addrinfo hints, *res;
2355
2356         xzero (hints);
2357         hints.ai_flags = AI_CANONNAME;
2358         hints.ai_family = AF_UNSPEC;
2359         hints.ai_socktype = SOCK_STREAM;
2360         hints.ai_protocol = 0;
2361         if (!getaddrinfo (hostname, NULL, &hints, &res))
2362           {
2363             hostname = (char *) alloca (strlen (res->ai_canonname) + 1);
2364             strcpy (hostname, res->ai_canonname);
2365
2366             freeaddrinfo (res);
2367           }
2368 #  endif  /* !(HAVE_GETADDRINFO && HAVE_GETNAMEINFO) */
2369       }
2370 # endif /* HAVE_SOCKETS */
2371   Vsystem_name = build_string (hostname);
2372 #endif /* HAVE_GETHOSTNAME  */
2373   {
2374     Bufbyte *p;
2375     Bytecount i;
2376
2377     for (i = 0, p = XSTRING_DATA (Vsystem_name);
2378          i < XSTRING_LENGTH (Vsystem_name);
2379          i++, p++)
2380       {
2381         if (*p == ' ' || *p == '\t')
2382           *p = '-';
2383       }
2384   }
2385 }
2386
2387 \f
2388 /************************************************************************/
2389 /*                        Emulation of select()                         */
2390 /************************************************************************/
2391
2392 #ifndef HAVE_SELECT
2393
2394 ERROR: XEmacs requires a working select().
2395
2396 #endif /* not HAVE_SELECT */
2397
2398 \f
2399 /************************************************************************/
2400 /*                      Emulation of signal stuff                       */
2401 /************************************************************************/
2402
2403 /* BSD 4.1 crap deleted.  4.2 was released in 1983, for God's sake!  I
2404    can't imagine that anyone is actually running that OS any more.
2405    You can't use X under it (I think) because there's no select().
2406    Anyway, the signal stuff has all been changed.  If someone wants to
2407    get this stuff working again, look in the FSF Emacs sources. */
2408
2409 /* POSIX signals support - DJB */
2410
2411 #ifdef HAVE_SIGPROCMASK
2412
2413 /* #### Is there any reason this is static global rather than local? */
2414 static struct sigaction new_action, old_action;
2415
2416 signal_handler_t
2417 sys_do_signal (int signal_number, signal_handler_t action)
2418 {
2419 #if 0
2420
2421   /* XEmacs works better if system calls are *not* restarted.
2422      This allows C-g to interrupt reads and writes, on most systems.
2423
2424      #### Another possibility is to just longjmp() out of the signal
2425      handler.  According to W.R. Stevens, this should be OK on all
2426      systems.  However, I don't want to deal with the potential
2427      evil ramifications of this at this point. */
2428
2429 #ifdef DGUX
2430   /* This gets us restartable system calls for efficiency.
2431      The "else" code will work as well. */
2432   return (berk_signal (signal_number, action));
2433 #else
2434   sigemptyset (&new_action.sa_mask);
2435   new_action.sa_handler = action;
2436 #if defined (SA_RESTART)
2437   /* Emacs mostly works better with restartable system services. If this
2438    * flag exists, we probably want to turn it on here.
2439    */
2440   new_action.sa_flags = SA_RESTART;
2441 #else
2442   new_action.sa_flags = 0;
2443 #endif
2444   sigaction (signal_number, &new_action, &old_action);
2445   return (old_action.sa_handler);
2446 #endif /* DGUX */
2447
2448 #else /* not 0 */
2449
2450   sigemptyset (&new_action.sa_mask);
2451   new_action.sa_handler = action;
2452 #if defined (SA_INTERRUPT) /* don't restart system calls, under SunOS */
2453   new_action.sa_flags = SA_INTERRUPT;
2454 #else
2455   new_action.sa_flags = 0;
2456 #endif
2457   sigaction (signal_number, &new_action, &old_action);
2458   return (signal_handler_t) (old_action.sa_handler);
2459
2460 #endif /* not 0 */
2461 }
2462
2463 #elif defined (HAVE_SIGBLOCK)
2464
2465 /* We use sigvec() rather than signal() if we have it, because
2466    it lets us specify interruptible system calls. */
2467 signal_handler_t
2468 sys_do_signal (int signal_number, signal_handler_t action)
2469 {
2470   struct sigvec vec, ovec;
2471
2472   vec.sv_handler = action;
2473   vec.sv_mask = 0;
2474 #ifdef SV_INTERRUPT /* don't restart system calls */
2475   vec.sv_flags = SV_INTERRUPT;
2476 #else
2477   vec.sv_flags = 0;
2478 #endif
2479
2480   sigvec (signal_number, &vec, &ovec);
2481
2482   return (ovec.sv_handler);
2483 }
2484
2485 #endif /* HAVE_SIGBLOCK (HAVE_SIGPROCMASK) */
2486
2487 \f
2488 /************************************************************************/
2489 /*           Emulation of strerror() and errno support                  */
2490 /************************************************************************/
2491
2492 #ifndef HAVE_STRERROR
2493
2494 #if !defined(NeXT) && !defined(__alpha) && !defined(MACH) && !defined(LINUX) && !defined(IRIX) && !defined(__NetBSD__)
2495 /* Linux added here by Raymond L. Toy <toy@alydar.crd.ge.com> for XEmacs. */
2496 /* Irix added here by gparker@sni-usa.com for XEmacs. */
2497 /* NetBSD added here by James R Grinter <jrg@doc.ic.ac.uk> for XEmacs */
2498 extern CONST char *sys_errlist[];
2499 extern int sys_nerr;
2500 #endif
2501
2502 #ifdef __NetBSD__
2503 extern char *sys_errlist[];
2504 extern int sys_nerr;
2505 #endif
2506
2507
2508 CONST char *
2509 strerror (int errnum)
2510 {
2511   if (errnum >= 0 && errnum < sys_nerr)
2512     return sys_errlist[errnum];
2513   return ((CONST char *) GETTEXT ("Unknown error"));
2514 }
2515
2516 #endif /* ! HAVE_STRERROR */
2517
2518 #ifdef WINDOWSNT
2519
2520 struct errentry {
2521   unsigned long oscode;  /* Win32 error */
2522   int errnocode;         /* unix errno */
2523 };
2524
2525 static struct errentry errtable[] = {
2526   {  ERROR_INVALID_FUNCTION,       EINVAL    },  /* 1 */
2527   {  ERROR_FILE_NOT_FOUND,         ENOENT    },  /* 2 */
2528   {  ERROR_PATH_NOT_FOUND,         ENOENT    },  /* 3 */
2529   {  ERROR_TOO_MANY_OPEN_FILES,    EMFILE    },  /* 4 */
2530   {  ERROR_ACCESS_DENIED,          EACCES    },  /* 5 */
2531   {  ERROR_INVALID_HANDLE,         EBADF     },  /* 6 */
2532   {  ERROR_ARENA_TRASHED,          ENOMEM    },  /* 7 */
2533   {  ERROR_NOT_ENOUGH_MEMORY,      ENOMEM    },  /* 8 */
2534   {  ERROR_INVALID_BLOCK,          ENOMEM    },  /* 9 */
2535   {  ERROR_BAD_ENVIRONMENT,        E2BIG     },  /* 10 */
2536   {  ERROR_BAD_FORMAT,             ENOEXEC   },  /* 11 */
2537   {  ERROR_INVALID_ACCESS,         EINVAL    },  /* 12 */
2538   {  ERROR_INVALID_DATA,           EINVAL    },  /* 13 */
2539   {  ERROR_INVALID_DRIVE,          ENOENT    },  /* 15 */
2540   {  ERROR_CURRENT_DIRECTORY,      EACCES    },  /* 16 */
2541   {  ERROR_NOT_SAME_DEVICE,        EXDEV     },  /* 17 */
2542   {  ERROR_NO_MORE_FILES,          ENOENT    },  /* 18 */
2543   {  ERROR_LOCK_VIOLATION,         EACCES    },  /* 33 */
2544   {  ERROR_BAD_NETPATH,            ENOENT    },  /* 53 */
2545   {  ERROR_NETWORK_ACCESS_DENIED,  EACCES    },  /* 65 */
2546   {  ERROR_BAD_NET_NAME,           ENOENT    },  /* 67 */
2547   {  ERROR_FILE_EXISTS,            EEXIST    },  /* 80 */
2548   {  ERROR_CANNOT_MAKE,            EACCES    },  /* 82 */
2549   {  ERROR_FAIL_I24,               EACCES    },  /* 83 */
2550   {  ERROR_INVALID_PARAMETER,      EINVAL    },  /* 87 */
2551   {  ERROR_NO_PROC_SLOTS,          EAGAIN    },  /* 89 */
2552   {  ERROR_DRIVE_LOCKED,           EACCES    },  /* 108 */
2553   {  ERROR_BROKEN_PIPE,            EPIPE     },  /* 109 */
2554   {  ERROR_DISK_FULL,              ENOSPC    },  /* 112 */
2555   {  ERROR_INVALID_TARGET_HANDLE,  EBADF     },  /* 114 */
2556   {  ERROR_INVALID_HANDLE,         EINVAL    },  /* 124 */
2557   {  ERROR_WAIT_NO_CHILDREN,       ECHILD    },  /* 128 */
2558   {  ERROR_CHILD_NOT_COMPLETE,     ECHILD    },  /* 129 */
2559   {  ERROR_DIRECT_ACCESS_HANDLE,   EBADF     },  /* 130 */
2560   {  ERROR_NEGATIVE_SEEK,          EINVAL    },  /* 131 */
2561   {  ERROR_SEEK_ON_DEVICE,         EACCES    },  /* 132 */
2562   {  ERROR_DIR_NOT_EMPTY,          ENOTEMPTY },  /* 145 */
2563   {  ERROR_NOT_LOCKED,             EACCES    },  /* 158 */
2564   {  ERROR_BAD_PATHNAME,           ENOENT    },  /* 161 */
2565   {  ERROR_MAX_THRDS_REACHED,      EAGAIN    },  /* 164 */
2566   {  ERROR_LOCK_FAILED,            EACCES    },  /* 167 */
2567   {  ERROR_ALREADY_EXISTS,         EEXIST    },  /* 183 */
2568   {  ERROR_FILENAME_EXCED_RANGE,   ENOENT    },  /* 206 */
2569   {  ERROR_NESTING_NOT_ALLOWED,    EAGAIN    },  /* 215 */
2570   {  ERROR_NOT_ENOUGH_QUOTA,       ENOMEM    }    /* 1816 */
2571 };
2572
2573 /* The following two constants must be the minimum and maximum
2574    values in the (contiguous) range of Exec Failure errors. */
2575 #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
2576 #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
2577
2578 /* These are the low and high value in the range of errors that are
2579    access violations */
2580 #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
2581 #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
2582
2583 void
2584 mswindows_set_errno (unsigned long win32_error)
2585 {
2586   int i;
2587
2588   /* check the table for the OS error code */
2589   for (i = 0; i < countof (errtable); ++i)
2590     {
2591       if (win32_error == errtable[i].oscode)
2592         {
2593           errno = errtable[i].errnocode;
2594           return;
2595         }
2596     }
2597
2598   /* The error code wasn't in the table.  We check for a range of
2599    * EACCES errors or exec failure errors (ENOEXEC).  Otherwise EINVAL is
2600    * returned. */
2601   if (win32_error >= MIN_EACCES_RANGE && win32_error <= MAX_EACCES_RANGE)
2602     errno = EACCES;
2603   else if (win32_error >= MIN_EXEC_ERROR && win32_error <= MAX_EXEC_ERROR)
2604     errno = ENOEXEC;
2605   else
2606     errno = EINVAL;
2607 }
2608
2609 void
2610 mswindows_set_last_errno (void)
2611 {
2612   mswindows_set_errno (GetLastError ());
2613 }
2614
2615 #endif /* WINDOWSNT */
2616
2617 \f
2618 /************************************************************************/
2619 /*                    Encapsulations of system calls                    */
2620 /************************************************************************/
2621
2622 #define PATHNAME_CONVERT_OUT(path) \
2623   TO_EXTERNAL_FORMAT (C_STRING, (path), C_STRING_ALLOCA, (path), Qfile_name);
2624
2625 /***************** low-level calls ****************/
2626
2627 /*
2628  *      On USG systems the system calls are INTERRUPTIBLE by signals
2629  *      that the user program has elected to catch.  Thus the system call
2630  *      must be retried in these cases.  To handle this without massive
2631  *      changes in the source code, we remap the standard system call names
2632  *      to names for our own functions in sysdep.c that do the system call
2633  *      with retries.  Actually, for portability reasons, it is good
2634  *      programming practice, as this example shows, to limit all actual
2635  *      system calls to a single occurrence in the source.  Sure, this
2636  *      adds an extra level of function call overhead but it is almost
2637  *      always negligible.   Fred Fish, Unisoft Systems Inc.
2638  */
2639
2640 /* Ben sez: read Dick Gabriel's essay about the Worse Is Better
2641    approach to programming and its connection to the silly
2642    interruptible-system-call business.  To find it, look on
2643    Jamie's home page (http://www.jwz.org/worse-is-better.html). */
2644
2645 #ifdef ENCAPSULATE_OPEN
2646 int
2647 sys_open (CONST char *path, int oflag, ...)
2648 {
2649   int mode;
2650   va_list ap;
2651
2652   va_start (ap, oflag);
2653   mode = va_arg (ap, int);
2654   va_end (ap);
2655
2656 #ifdef WINDOWSNT
2657   /* Make all handles non-inheritable */
2658   oflag |= _O_NOINHERIT;
2659 #endif
2660
2661 #ifdef INTERRUPTIBLE_OPEN
2662   {
2663     int rtnval;
2664     while ((rtnval = open (path, oflag, mode)) == -1
2665            && (errno == EINTR))
2666       DO_NOTHING;
2667     return rtnval;
2668   }
2669 #else
2670   return open (path, oflag, mode);
2671 #endif
2672 }
2673 #endif /* ENCAPSULATE_OPEN */
2674
2675 /* Like sys_open, only when open() is interrupted by EINTR, check for
2676    QUIT.  This allows the callers of this function to be interrupted
2677    with C-g when, say, reading from named pipes.  However, this should
2678    be used with caution, as it can GC.
2679
2680    This function will not function as expected on systems where open()
2681    is not interrupted by C-g.  However, the worst that can happen is
2682    the fallback to simple open().  */
2683 int
2684 interruptible_open (CONST char *path, int oflag, int mode)
2685 {
2686   /* This function can GC */
2687   size_t len = strlen (path);
2688   char *nonreloc = (char *) alloca (len + 1);
2689
2690   /* Must copy PATH, because it might be the data of a Lisp_String,
2691      which could be relocated by GC when checking for QUIT.  */
2692   memcpy (nonreloc, path, len + 1);
2693
2694   PATHNAME_CONVERT_OUT (nonreloc);
2695
2696 #ifdef WINDOWSNT
2697   /* Make all handles non-inheritable */
2698   oflag |= _O_NOINHERIT;
2699 #endif
2700
2701   for (;;)
2702     {
2703       int rtnval = open (nonreloc, oflag, mode);
2704       if (!(rtnval == -1 && errno == EINTR))
2705         return rtnval;
2706       /* open() was interrupted.  Was QUIT responsible?  */
2707       QUIT;
2708     }
2709 }
2710
2711 #ifdef ENCAPSULATE_CLOSE
2712 int
2713 sys_close (int filedes)
2714 {
2715 #ifdef INTERRUPTIBLE_CLOSE
2716   int did_retry = 0;
2717   REGISTER int rtnval;
2718
2719   while ((rtnval = close (filedes)) == -1
2720          && (errno == EINTR))
2721     did_retry = 1;
2722
2723   /* If close is interrupted SunOS 4.1 may or may not have closed the
2724      file descriptor.  If it did the second close will fail with
2725      errno = EBADF.  That means we have succeeded.  */
2726   if (rtnval == -1 && did_retry && errno == EBADF)
2727     return 0;
2728
2729   return rtnval;
2730 #else
2731   return close (filedes);
2732 #endif
2733 }
2734 #endif /* ENCAPSULATE_CLOSE */
2735
2736 ssize_t
2737 sys_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
2738 {
2739   ssize_t rtnval;
2740
2741   /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
2742   while ((rtnval = read (fildes, buf, nbyte)) == -1
2743          && (errno == EINTR))
2744     {
2745       if (allow_quit)
2746         REALLY_QUIT;
2747     }
2748   return rtnval;
2749 }
2750
2751 #ifdef ENCAPSULATE_READ
2752 ssize_t
2753 sys_read (int fildes, void *buf, size_t nbyte)
2754 {
2755   return sys_read_1 (fildes, buf, nbyte, 0);
2756 }
2757 #endif /* ENCAPSULATE_READ */
2758
2759 ssize_t
2760 sys_write_1 (int fildes, CONST void *buf, size_t nbyte, int allow_quit)
2761 {
2762   ssize_t bytes_written = 0;
2763   CONST char *b = (CONST char *) buf;
2764
2765   /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
2766   while (nbyte > 0)
2767     {
2768       ssize_t rtnval = write (fildes, b, nbyte);
2769
2770       if (allow_quit)
2771         REALLY_QUIT;
2772
2773       if (rtnval == -1)
2774         {
2775           if (errno == EINTR)
2776             continue;
2777           else
2778             return bytes_written ? bytes_written : -1;
2779         }
2780       b += rtnval;
2781       nbyte -= rtnval;
2782       bytes_written += rtnval;
2783     }
2784   return bytes_written;
2785 }
2786
2787 #ifdef ENCAPSULATE_WRITE
2788 ssize_t
2789 sys_write (int fildes, CONST void *buf, size_t nbyte)
2790 {
2791   return sys_write_1 (fildes, buf, nbyte, 0);
2792 }
2793 #endif /* ENCAPSULATE_WRITE */
2794
2795
2796 /**************** stdio calls ****************/
2797
2798 /* There is at least some evidence that the stdio calls are interruptible
2799    just like the normal system calls, at least on some systems.  In any
2800    case, it doesn't hurt to encapsulate them. */
2801
2802 /* #### Should also encapsulate fflush().
2803    #### Should conceivably encapsulate getchar() etc.  What a pain! */
2804
2805 #ifdef ENCAPSULATE_FOPEN
2806 FILE *
2807 sys_fopen (CONST char *path, CONST char *type)
2808 {
2809   PATHNAME_CONVERT_OUT (path);
2810 #if defined (WINDOWSNT)
2811   {
2812     int fd;
2813     int oflag;
2814     const char * type_save = type;
2815
2816     /* Force all file handles to be non-inheritable.  This is necessary to
2817        ensure child processes don't unwittingly inherit handles that might
2818        prevent future file access. */
2819
2820     if (type[0] == 'r')
2821       oflag = O_RDONLY;
2822     else if (type[0] == 'w' || type[0] == 'a')
2823       oflag = O_WRONLY | O_CREAT | O_TRUNC;
2824     else
2825       return 0;
2826
2827     /* Only do simplistic option parsing. */
2828     while (*++type)
2829       if (type[0] == '+')
2830         {
2831           oflag &= ~(O_RDONLY | O_WRONLY);
2832           oflag |= O_RDWR;
2833         }
2834       else if (type[0] == 'b')
2835         {
2836           oflag &= ~O_TEXT;
2837           oflag |= O_BINARY;
2838         }
2839       else if (type[0] == 't')
2840         {
2841           oflag &= ~O_BINARY;
2842           oflag |= O_TEXT;
2843         }
2844       else break;
2845
2846     fd = open (path, oflag | _O_NOINHERIT, 0644);
2847     if (fd < 0)
2848       return NULL;
2849
2850     return _fdopen (fd, type_save);
2851   }
2852 #elif defined (INTERRUPTIBLE_OPEN)
2853   {
2854     FILE *rtnval;
2855     while (!(rtnval = fopen (path, type)) && (errno == EINTR))
2856       DO_NOTHING;
2857     return rtnval;
2858   }
2859 #else
2860   return fopen (path, type);
2861 #endif
2862 }
2863 #endif /* ENCAPSULATE_FOPEN */
2864
2865
2866 #ifdef ENCAPSULATE_FCLOSE
2867 int
2868 sys_fclose (FILE *stream)
2869 {
2870 #ifdef INTERRUPTIBLE_CLOSE
2871   int rtnval;
2872
2873   while ((rtnval = fclose (stream)) == EOF
2874          && (errno == EINTR))
2875     ;
2876   return rtnval;
2877 #else
2878   return fclose (stream);
2879 #endif
2880 }
2881 #endif /* ENCAPSULATE_FCLOSE */
2882
2883
2884 #ifdef ENCAPSULATE_FREAD
2885 size_t
2886 sys_fread (void *ptr, size_t size, size_t nitem, FILE *stream)
2887 {
2888 #ifdef INTERRUPTIBLE_IO
2889   size_t rtnval;
2890   size_t items_read = 0;
2891   char *b = (char *) ptr;
2892
2893   while (nitem > 0)
2894     {
2895       rtnval = fread (b, size, nitem, stream);
2896       if (rtnval == 0)
2897         {
2898           if (ferror (stream) && errno == EINTR)
2899             continue;
2900           else
2901             return items_read;
2902         }
2903       b += size*rtnval;
2904       nitem -= rtnval;
2905       items_read += rtnval;
2906     }
2907   return (items_read);
2908 #else
2909   return fread (ptr, size, nitem, stream);
2910 #endif
2911 }
2912 #endif /* ENCAPSULATE_FREAD */
2913
2914
2915 #ifdef ENCAPSULATE_FWRITE
2916 size_t
2917 sys_fwrite (CONST void *ptr, size_t size, size_t nitem, FILE *stream)
2918 {
2919 #ifdef INTERRUPTIBLE_IO
2920   size_t rtnval;
2921   size_t items_written = 0;
2922   CONST char *b = (CONST char *) ptr;
2923
2924   while (nitem > 0)
2925     {
2926       rtnval = fwrite (b, size, nitem, stream);
2927       if (rtnval == 0)
2928         {
2929           if (ferror (stream) && errno == EINTR)
2930             continue;
2931           else
2932             return items_written;
2933         }
2934       b += size*rtnval;
2935       nitem -= rtnval;
2936       items_written += rtnval;
2937     }
2938   return (items_written);
2939 #else
2940   return fwrite (ptr, size, nitem, stream);
2941 #endif
2942 }
2943 #endif /* ENCAPSULATE_FWRITE */
2944
2945
2946 /********************* directory calls *******************/
2947
2948 #ifdef ENCAPSULATE_CHDIR
2949 int
2950 sys_chdir (CONST char *path)
2951 {
2952   PATHNAME_CONVERT_OUT (path);
2953   return chdir (path);
2954 }
2955 #endif /* ENCAPSULATE_CHDIR */
2956
2957
2958 #ifdef ENCAPSULATE_MKDIR
2959 int
2960 sys_mkdir (CONST char *path, mode_t mode)
2961 {
2962   PATHNAME_CONVERT_OUT (path);
2963 #ifdef WINDOWSNT
2964   return mkdir (path);
2965 #else
2966   return mkdir (path, mode);
2967 #endif
2968 }
2969 #endif /* ENCAPSULATE_MKDIR */
2970
2971
2972 #ifdef ENCAPSULATE_OPENDIR
2973 DIR *
2974 sys_opendir (CONST char *filename)
2975 {
2976   DIR *rtnval;
2977   PATHNAME_CONVERT_OUT (filename);
2978
2979   while (!(rtnval = opendir (filename))
2980          && (errno == EINTR))
2981     ;
2982   return rtnval;
2983 }
2984 #endif /* ENCAPSULATE_OPENDIR */
2985
2986
2987 #ifdef ENCAPSULATE_READDIR
2988 DIRENTRY *
2989 sys_readdir (DIR *dirp)
2990 {
2991   DIRENTRY *rtnval;
2992
2993   /* Apparently setting errno is necessary on some systems?
2994      Maybe readdir() doesn't always set errno ?! */
2995   while (!(errno = 0, rtnval = readdir (dirp))
2996          && (errno == EINTR))
2997     ;
2998 #ifndef MULE
2999   return rtnval;
3000 #else /* MULE */
3001   if (rtnval == NULL)           /* End of directory */
3002     return NULL;
3003   {
3004     Extcount external_len;
3005     int ascii_filename_p = 1;
3006     CONST Extbyte * CONST external_name = (CONST Extbyte *) rtnval->d_name;
3007
3008     /* Optimize for the common all-ASCII case, computing len en passant */
3009     for (external_len = 0; external_name[external_len] ; external_len++)
3010       {
3011         if (!BYTE_ASCII_P (external_name[external_len]))
3012           ascii_filename_p = 0;
3013       }
3014     if (ascii_filename_p)
3015       return rtnval;
3016
3017     { /* Non-ASCII filename */
3018       static Bufbyte_dynarr *internal_DIRENTRY;
3019       CONST Bufbyte *internal_name;
3020       Bytecount internal_len;
3021       if (!internal_DIRENTRY)
3022         internal_DIRENTRY = Dynarr_new (Bufbyte);
3023       else
3024         Dynarr_reset (internal_DIRENTRY);
3025
3026       Dynarr_add_many (internal_DIRENTRY, (Bufbyte *) rtnval,
3027                        offsetof (DIRENTRY, d_name));
3028
3029       TO_INTERNAL_FORMAT (DATA, (external_name, external_len),
3030                           ALLOCA, (internal_name, internal_len),
3031                           Qfile_name);
3032
3033       Dynarr_add_many (internal_DIRENTRY, internal_name, internal_len);
3034       Dynarr_add (internal_DIRENTRY, 0); /* zero-terminate */
3035       return (DIRENTRY *) Dynarr_atp (internal_DIRENTRY, 0);
3036     }
3037   }
3038 #endif /* MULE */
3039 }
3040 #endif /* ENCAPSULATE_READDIR */
3041
3042
3043 #ifdef ENCAPSULATE_CLOSEDIR
3044 int
3045 sys_closedir (DIR *dirp)
3046 {
3047   int rtnval;
3048
3049   while ((rtnval = closedir (dirp)) == -1
3050          && (errno == EINTR))
3051     ;
3052   return rtnval;
3053 }
3054 #endif /* ENCAPSULATE_CLOSEDIR */
3055
3056
3057 #ifdef ENCAPSULATE_RMDIR
3058 int
3059 sys_rmdir (CONST char *path)
3060 {
3061   PATHNAME_CONVERT_OUT (path);
3062   return rmdir (path);
3063 }
3064 #endif /* ENCAPSULATE_RMDIR */
3065
3066
3067 /***************** file-information calls ******************/
3068
3069 #ifdef ENCAPSULATE_ACCESS
3070 int
3071 sys_access (CONST char *path, int mode)
3072 {
3073   PATHNAME_CONVERT_OUT (path);
3074   return access (path, mode);
3075 }
3076 #endif /* ENCAPSULATE_ACCESS */
3077
3078
3079 #ifdef HAVE_EACCESS
3080 #ifdef ENCAPSULATE_EACCESS
3081 int
3082 sys_eaccess (CONST char *path, int mode)
3083 {
3084   PATHNAME_CONVERT_OUT (path);
3085   return eaccess (path, mode);
3086 }
3087 #endif /* ENCAPSULATE_EACCESS */
3088 #endif /* HAVE_EACCESS */
3089
3090
3091 #ifdef ENCAPSULATE_LSTAT
3092 int
3093 sys_lstat (CONST char *path, struct stat *buf)
3094 {
3095   PATHNAME_CONVERT_OUT (path);
3096   return lstat (path, buf);
3097 }
3098 #endif /* ENCAPSULATE_LSTAT */
3099
3100
3101 #ifdef ENCAPSULATE_READLINK
3102 int
3103 sys_readlink (CONST char *path, char *buf, size_t bufsiz)
3104 {
3105   PATHNAME_CONVERT_OUT (path);
3106   /* #### currently we don't do conversions on the incoming data */
3107   return readlink (path, buf, bufsiz);
3108 }
3109 #endif /* ENCAPSULATE_READLINK */
3110
3111
3112 #ifdef ENCAPSULATE_FSTAT
3113 int
3114 sys_fstat (int fd, struct stat *buf)
3115 {
3116   return fstat (fd, buf);
3117 }
3118 #endif /* ENCAPSULATE_FSTAT */
3119
3120
3121 #ifdef ENCAPSULATE_STAT
3122 int
3123 sys_stat (CONST char *path, struct stat *buf)
3124 {
3125   PATHNAME_CONVERT_OUT (path);
3126   return stat (path, buf);
3127 }
3128 #endif /* ENCAPSULATE_STAT */
3129
3130
3131 /****************** file-manipulation calls *****************/
3132
3133 #ifdef ENCAPSULATE_CHMOD
3134 int
3135 sys_chmod (CONST char *path, mode_t mode)
3136 {
3137   PATHNAME_CONVERT_OUT (path);
3138   return chmod (path, mode);
3139 }
3140 #endif /* ENCAPSULATE_CHMOD */
3141
3142
3143 #ifdef ENCAPSULATE_CREAT
3144 int
3145 sys_creat (CONST char *path, mode_t mode)
3146 {
3147   PATHNAME_CONVERT_OUT (path);
3148   return creat (path, mode);
3149 }
3150 #endif /* ENCAPSULATE_CREAT */
3151
3152
3153 #ifdef ENCAPSULATE_LINK
3154 int
3155 sys_link (CONST char *existing, CONST char *new)
3156 {
3157   PATHNAME_CONVERT_OUT (existing);
3158   PATHNAME_CONVERT_OUT (new);
3159   return link (existing, new);
3160 }
3161 #endif /* ENCAPSULATE_LINK */
3162
3163
3164 #ifdef ENCAPSULATE_RENAME
3165 int
3166 sys_rename (CONST char *old, CONST char *new)
3167 {
3168   PATHNAME_CONVERT_OUT (old);
3169   PATHNAME_CONVERT_OUT (new);
3170 #ifdef WINDOWSNT
3171   /* Windows rename fails if NEW exists */
3172   if (rename (old, new) == 0)
3173     return 0;
3174   if (errno != EEXIST)
3175     return -1;
3176   unlink (new);
3177 #endif /* WINDOWSNT */
3178   return rename (old, new);
3179 }
3180 #endif /* ENCAPSULATE_RENAME */
3181
3182
3183 #ifdef ENCAPSULATE_SYMLINK
3184 int
3185 sys_symlink (CONST char *name1, CONST char *name2)
3186 {
3187   PATHNAME_CONVERT_OUT (name1);
3188   PATHNAME_CONVERT_OUT (name2);
3189   return symlink (name1, name2);
3190 }
3191 #endif /* ENCAPSULATE_SYMLINK */
3192
3193
3194 #ifdef ENCAPSULATE_UNLINK
3195 int
3196 sys_unlink (CONST char *path)
3197 {
3198   PATHNAME_CONVERT_OUT (path);
3199   return unlink (path);
3200 }
3201 #endif /* ENCAPSULATE_UNLINK */
3202
3203
3204 #ifdef ENCAPSULATE_EXECVP
3205 int
3206 sys_execvp (CONST char *path, char * CONST * argv)
3207 {
3208   int i, argc;
3209   char ** new_argv;
3210
3211   PATHNAME_CONVERT_OUT (path);
3212   for (argc = 0; argv[argc]; argc++)
3213     ;
3214   new_argv = alloca_array (char *, argc + 1);
3215   for (i = 0; i < argc; i++)
3216     {
3217       new_argv[i] = argv[i];
3218       PATHNAME_CONVERT_OUT (new_argv[i]);
3219     }
3220   new_argv[argc] = NULL;
3221   return execvp (path, new_argv);
3222 }
3223 #endif /* ENCAPSULATE_EXECVP */
3224
3225 \f
3226 /************************************************************************/
3227 /*                  Emulations of missing system calls                  */
3228 /************************************************************************/
3229
3230 /***** (these are primarily required for USG, it seems) *****/
3231
3232 #ifndef HAVE_GETCWD
3233 char *
3234 getcwd (char *pathname, int size)
3235 {
3236   return getwd (pathname);
3237 }
3238 #endif /* emulate getcwd */
3239
3240
3241 #if 0 /* mrb */
3242 /*
3243  *      Warning, this function may not duplicate BSD 4.2 action properly
3244  *      under error conditions.
3245  */
3246
3247 #ifndef HAVE_GETWD
3248 char *
3249 getwd (char *pathname)
3250 {
3251   char *npath, *spath;
3252 #if !__STDC__ && !defined(STDC_HEADERS)
3253   extern char *getcwd ();
3254 #endif
3255
3256   spath = npath = getcwd ((char *) 0, MAXPATHLEN);
3257   if (spath == 0)
3258     return spath;
3259   /* On Altos 3068, getcwd can return @hostname/dir, so discard
3260      up to first slash.  Should be harmless on other systems.  */
3261   while (*npath && *npath != '/')
3262     npath++;
3263   strcpy (pathname, npath);
3264   xfree (spath);                  /* getcwd uses malloc */
3265   return pathname;
3266 }
3267 #endif /* HAVE_GETWD */
3268 #endif /* 0 - mrb */
3269
3270 /*
3271  *      Emulate rename using unlink/link.  Note that this is
3272  *      only partially correct.  Also, doesn't enforce restriction
3273  *      that files be of same type (regular->regular, dir->dir, etc).
3274  */
3275
3276 #ifndef HAVE_RENAME
3277 int
3278 rename (CONST char *from, CONST char *to)
3279 {
3280   if (access (from, 0) == 0)
3281     {
3282       unlink (to);
3283       if (link (from, to) == 0)
3284         if (unlink (from) == 0)
3285           return (0);
3286     }
3287   return (-1);
3288 }
3289 #endif /* HAVE_RENAME */
3290
3291 #ifdef HPUX
3292 #ifndef HAVE_PERROR
3293
3294 /* HPUX curses library references perror, but as far as we know
3295    it won't be called.  Anyway this definition will do for now.  */
3296
3297 perror (void)
3298 {
3299 }
3300
3301 #endif /* not HAVE_PERROR */
3302 #endif /* HPUX */
3303
3304 #ifndef HAVE_DUP2
3305
3306 /*
3307  *      Emulate BSD dup2.  First close newd if it already exists.
3308  *      Then, attempt to dup oldd.  If not successful, call dup2 recursively
3309  *      until we are, then close the unsuccessful ones.
3310  */
3311
3312 int
3313 dup2 (int oldd, int newd)
3314 {
3315   int fd, ret;
3316
3317   sys_close (newd);
3318
3319 #ifdef F_DUPFD
3320   fd = fcntl (oldd, F_DUPFD, newd);
3321   if (fd != newd)
3322     error ("can't dup2 (%i,%i) : %s", oldd, newd, strerror (errno));
3323 #else
3324   fd = dup (old);
3325   if (fd == -1)
3326     return -1;
3327   if (fd == new)
3328     return new;
3329   ret = dup2 (old, new);
3330   sys_close (fd);
3331   return ret;
3332 #endif /*  F_DUPFD */
3333 }
3334
3335 #endif /* not HAVE_DUP2 */
3336
3337 /*
3338  *      Gettimeofday.  Simulate as much as possible.  Only accurate
3339  *      to nearest second.  Emacs doesn't use tzp so ignore it for now.
3340  */
3341
3342 #if !defined (HAVE_GETTIMEOFDAY)
3343
3344 int
3345 gettimeofday (struct timeval *tp, struct timezone *tzp)
3346 {
3347   extern long time ();
3348
3349   tp->tv_sec = time ((long *)0);
3350   tp->tv_usec = 0;
3351   if (tzp != 0)
3352     tzp->tz_minuteswest = -1;
3353   return (0);
3354 }
3355
3356 #endif /* !HAVE_GETTIMEOFDAY */
3357
3358 /* No need to encapsulate utime and utimes explicitly because all
3359    access to those functions goes through the following. */
3360
3361 int
3362 set_file_times (char *filename, EMACS_TIME atime, EMACS_TIME mtime)
3363 {
3364 #ifdef HAVE_UTIMES
3365   struct timeval tv[2];
3366   tv[0] = atime;
3367   tv[1] = mtime;
3368   return utimes (filename, tv);
3369 #else /* not HAVE_UTIMES */
3370   struct utimbuf utb;
3371   utb.actime = EMACS_SECS (atime);
3372   utb.modtime = EMACS_SECS (mtime);
3373   return utime (filename, &utb);
3374 #endif /* not HAVE_UTIMES */
3375 }
3376
3377 /* */
3378
3379 static long ticks_per_second;
3380 static long orig_user_ticks, orig_system_ticks;
3381 EMACS_TIME orig_real_time;
3382
3383 static int process_times_available;
3384
3385 /* Return the relative user and system tick count.  We try to
3386    maintain calculations in terms of integers as long as possible
3387    for increased accuracy. */
3388
3389 static int
3390 get_process_times_1 (long *user_ticks, long *system_ticks)
3391 {
3392 #if defined (_SC_CLK_TCK) || defined (CLK_TCK) && !defined(WINDOWSNT)
3393   /* We have the POSIX times() function available. */
3394   struct tms tttt;
3395   times (&tttt);
3396   *user_ticks = (long) tttt.tms_utime;
3397   *system_ticks = (long) tttt.tms_stime;
3398   return 1;
3399 #elif defined (CLOCKS_PER_SEC)
3400   *user_ticks = (long) clock ();
3401   *system_ticks = 0;
3402   return 1;
3403 #else
3404   return 0;
3405 #endif
3406 }
3407
3408 void
3409 init_process_times_very_early (void)
3410 {
3411 #if defined (_SC_CLK_TCK)
3412   ticks_per_second = sysconf (_SC_CLK_TCK);
3413 #elif defined (CLK_TCK)
3414   ticks_per_second = CLK_TCK;
3415 #elif defined (CLOCKS_PER_SEC)
3416   ticks_per_second = CLOCKS_PER_SEC;
3417 #endif
3418
3419   process_times_available = get_process_times_1 (&orig_user_ticks,
3420                                                  &orig_system_ticks);
3421   EMACS_GET_TIME (orig_real_time);
3422 }
3423
3424 /* Return the user and system times used up by this process so far. */
3425 void
3426 get_process_times (double *user_time, double *system_time, double *real_time)
3427 {
3428   EMACS_TIME curr_real_time;
3429   EMACS_TIME elapsed_time;
3430   long curr_user_ticks, curr_system_ticks;
3431
3432   EMACS_GET_TIME (curr_real_time);
3433   EMACS_SUB_TIME (elapsed_time, curr_real_time, orig_real_time);
3434   *real_time = (EMACS_SECS (elapsed_time)
3435                 + ((double) EMACS_USECS (elapsed_time)) / 1000000);
3436   if (get_process_times_1 (&curr_user_ticks, &curr_system_ticks))
3437     {
3438       *user_time = (((double) (curr_user_ticks - orig_user_ticks))
3439                     / ticks_per_second);
3440       *system_time = (((double) (curr_system_ticks - orig_system_ticks))
3441                       / ticks_per_second);
3442     }
3443   else
3444     {
3445       /* A lame OS */
3446       *user_time = *real_time;
3447       *system_time = 0;
3448     }
3449 }
3450
3451 #ifndef HAVE_RANDOM
3452 #ifdef random
3453 #define HAVE_RANDOM
3454 #endif
3455 #endif
3456
3457 /* Figure out how many bits the system's random number generator uses.
3458    `random' and `lrand48' are assumed to return 31 usable bits.
3459    BSD `rand' returns a 31 bit value but the low order bits are unusable;
3460    so we'll shift it and treat it like the 15-bit USG `rand'.  */
3461
3462 #ifndef RAND_BITS
3463 # ifdef HAVE_RANDOM
3464 #  define RAND_BITS 31
3465 # else /* !HAVE_RANDOM */
3466 #  ifdef HAVE_LRAND48
3467 #   define RAND_BITS 31
3468 #   define random lrand48
3469 #  else /* !HAVE_LRAND48 */
3470 #   define RAND_BITS 15
3471 #   if RAND_MAX == 32767
3472 #    define random rand
3473 #   else /* RAND_MAX != 32767 */
3474 #    if RAND_MAX == 2147483647
3475 #     define random() (rand () >> 16)
3476 #    else /* RAND_MAX != 2147483647 */
3477 #     ifdef USG
3478 #      define random rand
3479 #     else
3480 #      define random() (rand () >> 16)
3481 #     endif /* !BSD */
3482 #    endif /* RAND_MAX != 2147483647 */
3483 #   endif /* RAND_MAX != 32767 */
3484 #  endif /* !HAVE_LRAND48 */
3485 # endif /* !HAVE_RANDOM */
3486 #endif /* !RAND_BITS */
3487
3488 void seed_random (long arg);
3489 void
3490 seed_random (long arg)
3491 {
3492 #ifdef HAVE_RANDOM
3493   srandom ((unsigned int)arg);
3494 #else
3495 # ifdef HAVE_LRAND48
3496   srand48 (arg);
3497 # else
3498   srand ((unsigned int)arg);
3499 # endif
3500 #endif
3501 }
3502
3503 /*
3504  * Build a full Emacs-sized word out of whatever we've got.
3505  * This suffices even for a 64-bit architecture with a 15-bit rand.
3506  */
3507 long get_random (void);
3508 long
3509 get_random (void)
3510 {
3511   long val = random ();
3512 #if VALBITS > RAND_BITS
3513   val = (val << RAND_BITS) ^ random ();
3514 #if VALBITS > 2*RAND_BITS
3515   val = (val << RAND_BITS) ^ random ();
3516 #if VALBITS > 3*RAND_BITS
3517   val = (val << RAND_BITS) ^ random ();
3518 #if VALBITS > 4*RAND_BITS
3519   val = (val << RAND_BITS) ^ random ();
3520 #endif /* need at least 5 */
3521 #endif /* need at least 4 */
3522 #endif /* need at least 3 */
3523 #endif /* need at least 2 */
3524   return val & ((1L << VALBITS) - 1);
3525 }
3526
3527 \f
3528 /************************************************************************/
3529 /*               Strings corresponding to defined signals               */
3530 /************************************************************************/
3531
3532 #if !defined (SYS_SIGLIST_DECLARED) && !defined (HAVE_SYS_SIGLIST)
3533
3534 #if defined(WINDOWSNT) || defined(__CYGWIN32__)
3535 CONST char *sys_siglist[] =
3536   {
3537     "bum signal!!",
3538     "hangup",
3539     "interrupt",
3540     "quit",
3541     "illegal instruction",
3542     "trace trap",
3543     "iot instruction",
3544     "emt instruction",
3545     "floating point exception",
3546     "kill",
3547     "bus error",
3548     "segmentation violation",
3549     "bad argument to system call",
3550     "write on a pipe with no one to read it",
3551     "alarm clock",
3552     "software termination signal from kill",
3553     "status signal",
3554     "sendable stop signal not from tty",
3555     "stop signal from tty",
3556     "continue a stopped process",
3557     "child status has changed",
3558     "background read attempted from control tty",
3559     "background write attempted from control tty",
3560     "input record available at control tty",
3561     "exceeded CPU time limit",
3562     "exceeded file size limit"
3563     };
3564 #endif
3565
3566 #ifdef USG
3567 #ifdef AIX
3568 CONST char *sys_siglist[NSIG + 1] =
3569   {
3570     /* AIX has changed the signals a bit */
3571     DEFER_GETTEXT ("bogus signal"),                     /* 0 */
3572     DEFER_GETTEXT ("hangup"),                           /* 1  SIGHUP */
3573     DEFER_GETTEXT ("interrupt"),                        /* 2  SIGINT */
3574     DEFER_GETTEXT ("quit"),                             /* 3  SIGQUIT */
3575     DEFER_GETTEXT ("illegal instruction"),              /* 4  SIGILL */
3576     DEFER_GETTEXT ("trace trap"),                       /* 5  SIGTRAP */
3577     DEFER_GETTEXT ("IOT instruction"),                  /* 6  SIGIOT */
3578     DEFER_GETTEXT ("crash likely"),                     /* 7  SIGDANGER */
3579     DEFER_GETTEXT ("floating point exception"),         /* 8  SIGFPE */
3580     DEFER_GETTEXT ("kill"),                             /* 9  SIGKILL */
3581     DEFER_GETTEXT ("bus error"),                        /* 10 SIGBUS */
3582     DEFER_GETTEXT ("segmentation violation"),           /* 11 SIGSEGV */
3583     DEFER_GETTEXT ("bad argument to system call"),      /* 12 SIGSYS */
3584     DEFER_GETTEXT ("write on a pipe with no one to read it"), /* 13 SIGPIPE */
3585     DEFER_GETTEXT ("alarm clock"),                      /* 14 SIGALRM */
3586     DEFER_GETTEXT ("software termination signum"),      /* 15 SIGTERM */
3587     DEFER_GETTEXT ("user defined signal 1"),            /* 16 SIGUSR1 */
3588     DEFER_GETTEXT ("user defined signal 2"),            /* 17 SIGUSR2 */
3589     DEFER_GETTEXT ("death of a child"),                 /* 18 SIGCLD */
3590     DEFER_GETTEXT ("power-fail restart"),               /* 19 SIGPWR */
3591     DEFER_GETTEXT ("bogus signal"),                     /* 20 */
3592     DEFER_GETTEXT ("bogus signal"),                     /* 21 */
3593     DEFER_GETTEXT ("bogus signal"),                     /* 22 */
3594     DEFER_GETTEXT ("bogus signal"),                     /* 23 */
3595     DEFER_GETTEXT ("bogus signal"),                     /* 24 */
3596     DEFER_GETTEXT ("LAN I/O interrupt"),                /* 25 SIGAIO */
3597     DEFER_GETTEXT ("PTY I/O interrupt"),                /* 26 SIGPTY */
3598     DEFER_GETTEXT ("I/O intervention required"),        /* 27 SIGIOINT */
3599 #ifdef AIXHFT
3600     DEFER_GETTEXT ("HFT grant"),                        /* 28 SIGGRANT */
3601     DEFER_GETTEXT ("HFT retract"),                      /* 29 SIGRETRACT */
3602     DEFER_GETTEXT ("HFT sound done"),                   /* 30 SIGSOUND */
3603     DEFER_GETTEXT ("HFT input ready"),                  /* 31 SIGMSG */
3604 #endif
3605     0
3606   };
3607 #else /* USG, not AIX */
3608 CONST char *sys_siglist[NSIG + 1] =
3609   {
3610     DEFER_GETTEXT ("bogus signal"),                     /* 0 */
3611     DEFER_GETTEXT ("hangup"),                           /* 1  SIGHUP */
3612     DEFER_GETTEXT ("interrupt"),                        /* 2  SIGINT */
3613     DEFER_GETTEXT ("quit"),                             /* 3  SIGQUIT */
3614     DEFER_GETTEXT ("illegal instruction"),              /* 4  SIGILL */
3615     DEFER_GETTEXT ("trace trap"),                       /* 5  SIGTRAP */
3616     DEFER_GETTEXT ("IOT instruction"),                  /* 6  SIGIOT */
3617     DEFER_GETTEXT ("EMT instruction"),                  /* 7  SIGEMT */
3618     DEFER_GETTEXT ("floating point exception"),         /* 8  SIGFPE */
3619     DEFER_GETTEXT ("kill"),                             /* 9  SIGKILL */
3620     DEFER_GETTEXT ("bus error"),                        /* 10 SIGBUS */
3621     DEFER_GETTEXT ("segmentation violation"),           /* 11 SIGSEGV */
3622     DEFER_GETTEXT ("bad argument to system call"),      /* 12 SIGSYS */
3623     DEFER_GETTEXT ("write on a pipe with no one to read it"), /* 13 SIGPIPE */
3624     DEFER_GETTEXT ("alarm clock"),                      /* 14 SIGALRM */
3625     DEFER_GETTEXT ("software termination signum"),      /* 15 SIGTERM */
3626     DEFER_GETTEXT ("user defined signal 1"),            /* 16 SIGUSR1 */
3627     DEFER_GETTEXT ("user defined signal 2"),            /* 17 SIGUSR2 */
3628     DEFER_GETTEXT ("death of a child"),                 /* 18 SIGCLD */
3629     DEFER_GETTEXT ("power-fail restart"),               /* 19 SIGPWR */
3630 #ifdef sun
3631     DEFER_GETTEXT ("window size changed"),              /* 20 SIGWINCH */
3632     DEFER_GETTEXT ("urgent socket condition"),          /* 21 SIGURG */
3633     DEFER_GETTEXT ("pollable event occurred"),          /* 22 SIGPOLL */
3634     DEFER_GETTEXT ("stop (cannot be caught or ignored)"), /*  23 SIGSTOP */
3635     DEFER_GETTEXT ("user stop requested from tty"),     /* 24 SIGTSTP */
3636     DEFER_GETTEXT ("stopped process has been continued"), /* 25 SIGCONT */
3637     DEFER_GETTEXT ("background tty read attempted"),    /* 26 SIGTTIN */
3638     DEFER_GETTEXT ("background tty write attempted"),   /* 27 SIGTTOU */
3639     DEFER_GETTEXT ("virtual timer expired"),            /* 28 SIGVTALRM */
3640     DEFER_GETTEXT ("profiling timer expired"),          /* 29 SIGPROF */
3641     DEFER_GETTEXT ("exceeded cpu limit"),               /* 30 SIGXCPU */
3642     DEFER_GETTEXT ("exceeded file size limit"),         /* 31 SIGXFSZ */
3643     DEFER_GETTEXT ("process's lwps are blocked"),       /* 32 SIGWAITING */
3644     DEFER_GETTEXT ("special signal used by thread library"), /* 33 SIGLWP */
3645 #ifdef SIGFREEZE
3646     DEFER_GETTEXT ("special signal used by CPR"),        /* 34 SIGFREEZE */
3647 #endif
3648 #ifdef SIGTHAW
3649     DEFER_GETTEXT ("special signal used by CPR"),        /* 35 SIGTHAW */
3650 #endif
3651 #endif /* sun */
3652     0
3653   };
3654 #endif /* not AIX */
3655 #endif /* USG */
3656 #ifdef DGUX
3657 CONST char *sys_siglist[NSIG + 1] =
3658   {
3659     DEFER_GETTEXT ("null signal"),                       /*  0 SIGNULL   */
3660     DEFER_GETTEXT ("hangup"),                            /*  1 SIGHUP    */
3661     DEFER_GETTEXT ("interrupt"),                         /*  2 SIGINT    */
3662     DEFER_GETTEXT ("quit"),                              /*  3 SIGQUIT   */
3663     DEFER_GETTEXT ("illegal instruction"),               /*  4 SIGILL    */
3664     DEFER_GETTEXT ("trace trap"),                        /*  5 SIGTRAP   */
3665     DEFER_GETTEXT ("abort termination"),                 /*  6 SIGABRT   */
3666     DEFER_GETTEXT ("SIGEMT"),                            /*  7 SIGEMT    */
3667     DEFER_GETTEXT ("floating point exception"),          /*  8 SIGFPE    */
3668     DEFER_GETTEXT ("kill"),                              /*  9 SIGKILL   */
3669     DEFER_GETTEXT ("bus error"),                         /* 10 SIGBUS    */
3670     DEFER_GETTEXT ("segmentation violation"),            /* 11 SIGSEGV   */
3671     DEFER_GETTEXT ("bad argument to system call"),       /* 12 SIGSYS    */
3672     DEFER_GETTEXT ("write on a pipe with no reader"),    /* 13 SIGPIPE   */
3673     DEFER_GETTEXT ("alarm clock"),                       /* 14 SIGALRM   */
3674     DEFER_GETTEXT ("software termination signal"),       /* 15 SIGTERM   */
3675     DEFER_GETTEXT ("user defined signal 1"),             /* 16 SIGUSR1   */
3676     DEFER_GETTEXT ("user defined signal 2"),             /* 17 SIGUSR2   */
3677     DEFER_GETTEXT ("child stopped or terminated"),       /* 18 SIGCLD    */
3678     DEFER_GETTEXT ("power-fail restart"),                /* 19 SIGPWR    */
3679     DEFER_GETTEXT ("window size changed"),               /* 20 SIGWINCH  */
3680     DEFER_GETTEXT ("undefined"),                         /* 21           */
3681     DEFER_GETTEXT ("pollable event occurred"),           /* 22 SIGPOLL   */
3682     DEFER_GETTEXT ("sendable stop signal not from tty"), /* 23 SIGSTOP   */
3683     DEFER_GETTEXT ("stop signal from tty"),              /* 24 SIGSTP    */
3684     DEFER_GETTEXT ("continue a stopped process"),        /* 25 SIGCONT   */
3685     DEFER_GETTEXT ("attempted background tty read"),     /* 26 SIGTTIN   */
3686     DEFER_GETTEXT ("attempted background tty write"),    /* 27 SIGTTOU   */
3687     DEFER_GETTEXT ("undefined"),                         /* 28           */
3688     DEFER_GETTEXT ("undefined"),                         /* 29           */
3689     DEFER_GETTEXT ("undefined"),                         /* 30           */
3690     DEFER_GETTEXT ("undefined"),                         /* 31           */
3691     DEFER_GETTEXT ("undefined"),                         /* 32           */
3692     DEFER_GETTEXT ("socket (TCP/IP) urgent data arrival"), /* 33 SIGURG    */
3693     DEFER_GETTEXT ("I/O is possible"),                   /* 34 SIGIO     */
3694     DEFER_GETTEXT ("exceeded cpu time limit"),           /* 35 SIGXCPU   */
3695     DEFER_GETTEXT ("exceeded file size limit"),          /* 36 SIGXFSZ   */
3696     DEFER_GETTEXT ("virtual time alarm"),                /* 37 SIGVTALRM */
3697     DEFER_GETTEXT ("profiling time alarm"),              /* 38 SIGPROF   */
3698     DEFER_GETTEXT ("undefined"),                         /* 39           */
3699     DEFER_GETTEXT ("file record locks revoked"),         /* 40 SIGLOST   */
3700     DEFER_GETTEXT ("undefined"),                         /* 41           */
3701     DEFER_GETTEXT ("undefined"),                         /* 42           */
3702     DEFER_GETTEXT ("undefined"),                         /* 43           */
3703     DEFER_GETTEXT ("undefined"),                         /* 44           */
3704     DEFER_GETTEXT ("undefined"),                         /* 45           */
3705     DEFER_GETTEXT ("undefined"),                         /* 46           */
3706     DEFER_GETTEXT ("undefined"),                         /* 47           */
3707     DEFER_GETTEXT ("undefined"),                         /* 48           */
3708     DEFER_GETTEXT ("undefined"),                         /* 49           */
3709     DEFER_GETTEXT ("undefined"),                         /* 50           */
3710     DEFER_GETTEXT ("undefined"),                         /* 51           */
3711     DEFER_GETTEXT ("undefined"),                         /* 52           */
3712     DEFER_GETTEXT ("undefined"),                         /* 53           */
3713     DEFER_GETTEXT ("undefined"),                         /* 54           */
3714     DEFER_GETTEXT ("undefined"),                         /* 55           */
3715     DEFER_GETTEXT ("undefined"),                         /* 56           */
3716     DEFER_GETTEXT ("undefined"),                         /* 57           */
3717     DEFER_GETTEXT ("undefined"),                         /* 58           */
3718     DEFER_GETTEXT ("undefined"),                         /* 59           */
3719     DEFER_GETTEXT ("undefined"),                         /* 60           */
3720     DEFER_GETTEXT ("undefined"),                         /* 61           */
3721     DEFER_GETTEXT ("undefined"),                         /* 62           */
3722     DEFER_GETTEXT ("undefined"),                         /* 63           */
3723     DEFER_GETTEXT ("notification message in mess. queue"), /* 64 SIGDGNOTIFY */
3724     0
3725   };
3726 #endif /* DGUX */
3727
3728 #endif /* ! SYS_SIGLIST_DECLARED && ! HAVE_SYS_SIGLIST */
3729
3730 \f
3731 /************************************************************************/
3732 /*         Directory routines for systems that don't have them          */
3733 /************************************************************************/
3734
3735 #ifdef SYSV_SYSTEM_DIR
3736
3737 #include <dirent.h>
3738
3739 #if defined(BROKEN_CLOSEDIR) || !defined(HAVE_CLOSEDIR)
3740 int
3741 closedir (DIR *dirp)  /* stream from opendir */
3742 {
3743   int rtnval;
3744
3745   rtnval = sys_close (dirp->dd_fd);
3746
3747   /* Some systems (like Solaris) allocate the buffer and the DIR all
3748      in one block.  Why in the world are we freeing this ourselves
3749      anyway?  */
3750 #if ! (defined (sun) && defined (USG5_4))
3751   xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
3752 #endif
3753   xfree ((char *) dirp);
3754   return (rtnval);
3755 }
3756 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3757 #endif /* SYSV_SYSTEM_DIR */
3758
3759 #ifdef NONSYSTEM_DIR_LIBRARY
3760
3761 DIR *
3762 opendir (CONST char *filename)  /* name of directory */
3763 {
3764   DIR *dirp;            /* -> malloc'ed storage */
3765   int fd;               /* file descriptor for read */
3766   struct stat sbuf;             /* result of fstat */
3767
3768   fd = sys_open (filename, O_RDONLY);
3769   if (fd < 0)
3770     return 0;
3771
3772   if (fstat (fd, &sbuf) < 0
3773       || (sbuf.st_mode & S_IFMT) != S_IFDIR
3774       || (dirp = (DIR *) malloc (sizeof (DIR))) == 0)
3775     {
3776       sys_close (fd);
3777       return 0;         /* bad luck today */
3778     }
3779
3780   dirp->dd_fd = fd;
3781   dirp->dd_loc = dirp->dd_size = 0;     /* refill needed */
3782
3783   return dirp;
3784 }
3785
3786 void
3787 closedir (DIR *dirp)            /* stream from opendir */
3788 {
3789   sys_close (dirp->dd_fd);
3790   xfree (dirp);
3791 }
3792
3793
3794 #define DIRSIZ  14
3795 struct olddir
3796   {
3797     ino_t od_ino;               /* inode */
3798     char od_name[DIRSIZ];       /* filename */
3799   };
3800
3801 static struct direct dir_static; /* simulated directory contents */
3802
3803 /* ARGUSED */
3804 struct direct *
3805 readdir (DIR *dirp)     /* stream from opendir */
3806 {
3807   struct olddir *dp;    /* -> directory data */
3808
3809   for (; ;)
3810     {
3811       if (dirp->dd_loc >= dirp->dd_size)
3812         dirp->dd_loc = dirp->dd_size = 0;
3813
3814       if (dirp->dd_size == 0    /* refill buffer */
3815           && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3816         return 0;
3817
3818       dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
3819       dirp->dd_loc += sizeof (struct olddir);
3820
3821       if (dp->od_ino != 0)      /* not deleted entry */
3822         {
3823           dir_static.d_ino = dp->od_ino;
3824           strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
3825           dir_static.d_name[DIRSIZ] = '\0';
3826           dir_static.d_namlen = strlen (dir_static.d_name);
3827           dir_static.d_reclen = sizeof (struct direct)
3828             - MAXNAMLEN + 3
3829               + dir_static.d_namlen - dir_static.d_namlen % 4;
3830           return &dir_static;   /* -> simulated structure */
3831         }
3832     }
3833 }
3834
3835
3836 #endif /* NONSYSTEM_DIR_LIBRARY */
3837
3838 \f
3839 /* mkdir and rmdir functions, for systems which don't have them.  */
3840
3841 #ifndef HAVE_MKDIR
3842 /*
3843  * Written by Robert Rother, Mariah Corporation, August 1985.
3844  *
3845  * If you want it, it's yours.  All I ask in return is that if you
3846  * figure out how to do this in a Bourne Shell script you send me
3847  * a copy.
3848  *                                      sdcsvax!rmr or rmr@uscd
3849  *
3850  * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3851  * subroutine.  11Mar86; hoptoad!gnu
3852  *
3853  * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3854  * subroutine didn't return EEXIST.  It does now.
3855  */
3856
3857 /*
3858  * Make a directory.
3859  */
3860 #ifdef MKDIR_PROTOTYPE
3861 MKDIR_PROTOTYPE
3862 #else
3863 int
3864 mkdir (CONST char *dpath, int dmode)
3865 #endif
3866 {
3867   int cpid, status, fd;
3868   struct stat statbuf;
3869
3870   if (stat (dpath, &statbuf) == 0)
3871     {
3872       errno = EEXIST;           /* Stat worked, so it already exists */
3873       return -1;
3874     }
3875
3876   /* If stat fails for a reason other than non-existence, return error */
3877   if (errno != ENOENT)
3878     return -1;
3879
3880   synch_process_alive = 1;
3881   switch (cpid = fork ())
3882     {
3883
3884     case -1:                    /* Error in fork() */
3885       return -1;                /* Errno is set already */
3886
3887     case 0:                     /* Child process */
3888     {
3889       /*
3890        * Cheap hack to set mode of new directory.  Since this
3891        * child process is going away anyway, we zap its umask.
3892        * ####, this won't suffice to set SUID, SGID, etc. on this
3893        * directory.  Does anybody care?
3894        */
3895       status = umask (0);       /* Get current umask */
3896       status = umask (status | (0777 & ~dmode));        /* Set for mkdir */
3897       fd = sys_open ("/dev/null", O_RDWR);
3898       if (fd >= 0)
3899         {
3900           if (fd != STDIN_FILENO)  dup2 (fd, STDIN_FILENO);
3901           if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
3902           if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);
3903         }
3904       execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
3905       _exit (-1);               /* Can't exec /bin/mkdir */
3906     }
3907
3908     default:                    /* Parent process */
3909       wait_for_termination (cpid);
3910     }
3911
3912   if (synch_process_death != 0 || synch_process_retcode != 0)
3913     {
3914       errno = EIO;              /* We don't know why, but */
3915       return -1;                /* /bin/mkdir failed */
3916     }
3917
3918   return 0;
3919 }
3920 #endif /* not HAVE_MKDIR */
3921
3922 #ifndef HAVE_RMDIR
3923 int
3924 rmdir (CONST char *dpath)
3925 {
3926   int cpid, status, fd;
3927   struct stat statbuf;
3928
3929   if (stat (dpath, &statbuf) != 0)
3930     {
3931       /* Stat just set errno.  We don't have to */
3932       return -1;
3933     }
3934
3935   synch_process_alive = 1;
3936   switch (cpid = fork ())
3937     {
3938
3939     case -1:                    /* Error in fork() */
3940       return (-1);              /* Errno is set already */
3941
3942     case 0:                     /* Child process */
3943       fd = sys_open("/dev/null", O_RDWR);
3944       if (fd >= 0)
3945         {
3946           if (fd != STDIN_FILENO)  dup2 (fd, STDIN_FILENO);
3947           if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
3948           if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);
3949         }
3950       execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
3951       _exit (-1);               /* Can't exec /bin/mkdir */
3952
3953     default:                    /* Parent process */
3954       wait_for_termination (cpid);
3955     }
3956
3957   if (synch_process_death   != 0 ||
3958       synch_process_retcode != 0)
3959     {
3960       errno = EIO;              /* We don't know why, but */
3961       return -1;                /* /bin/rmdir failed */
3962     }
3963
3964   return 0;
3965 }
3966 #endif /* !HAVE_RMDIR */
3967
3968 \f
3969 /************************************************************************/
3970 /*                            Misc. SunOS crap                          */
3971 /************************************************************************/
3972
3973 #ifdef USE_DL_STUBS
3974
3975 /* These are included on Sunos 4.1 when we do not use shared libraries.
3976    X11 libraries may refer to these functions but (we hope) do not
3977    actually call them.  */
3978
3979 void *
3980 dlopen (void)
3981 {
3982   return 0;
3983 }
3984
3985 void *
3986 dlsym (void)
3987 {
3988   return 0;
3989 }
3990
3991 int
3992 dlclose (void)
3993 {
3994   return -1;
3995 }
3996
3997 #endif /* USE_DL_STUBS */
3998
3999 \f
4000
4001 #ifndef HAVE_STRCASECMP
4002 /*
4003  * From BSD
4004  */
4005 static unsigned char charmap[] = {
4006         '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
4007         '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
4008         '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
4009         '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
4010         '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
4011         '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
4012         '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
4013         '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
4014         '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
4015         '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
4016         '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
4017         '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
4018         '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
4019         '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
4020         '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
4021         '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
4022         '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
4023         '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
4024         '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
4025         '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
4026         '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
4027         '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
4028         '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
4029         '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
4030         '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
4031         '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
4032         '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
4033         '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
4034         '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
4035         '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
4036         '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
4037         '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
4038 };
4039
4040 int
4041 strcasecmp (char *s1, char *s2)
4042 {
4043   unsigned char *cm = charmap;
4044   unsigned char *us1 = (unsigned char *) s1;
4045   unsigned char *us2 = (unsigned char *)s2;
4046
4047   while (cm[*us1] == cm[*us2++])
4048     if (*us1++ == '\0')
4049       return (0);
4050
4051   return (cm[*us1] - cm[*--us2]);
4052 }
4053 #endif /* !HAVE_STRCASECMP */