XEmacs 21.2.30 "Hygeia".
[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 = (HANDLE) _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   PATHNAME_CONVERT_OUT (path);
2657
2658 #ifdef WINDOWSNT
2659   /* Make all handles non-inheritable */
2660   oflag |= _O_NOINHERIT;
2661 #endif
2662
2663 #ifdef INTERRUPTIBLE_OPEN
2664   {
2665     int rtnval;
2666     while ((rtnval = open (path, oflag, mode)) == -1
2667            && (errno == EINTR))
2668       DO_NOTHING;
2669     return rtnval;
2670   }
2671 #else
2672   return open (path, oflag, mode);
2673 #endif
2674 }
2675 #endif /* ENCAPSULATE_OPEN */
2676
2677 /* Like sys_open, only when open() is interrupted by EINTR, check for
2678    QUIT.  This allows the callers of this function to be interrupted
2679    with C-g when, say, reading from named pipes.  However, this should
2680    be used with caution, as it can GC.
2681
2682    This function will not function as expected on systems where open()
2683    is not interrupted by C-g.  However, the worst that can happen is
2684    the fallback to simple open().  */
2685 int
2686 interruptible_open (const char *path, int oflag, int mode)
2687 {
2688   /* This function can GC */
2689   size_t len = strlen (path);
2690   char *nonreloc = (char *) alloca (len + 1);
2691
2692   /* Must copy PATH, because it might be the data of a Lisp_String,
2693      which could be relocated by GC when checking for QUIT.  */
2694   memcpy (nonreloc, path, len + 1);
2695
2696   PATHNAME_CONVERT_OUT (nonreloc);
2697
2698 #ifdef WINDOWSNT
2699   /* Make all handles non-inheritable */
2700   oflag |= _O_NOINHERIT;
2701 #endif
2702
2703   for (;;)
2704     {
2705       int rtnval = open (nonreloc, oflag, mode);
2706       if (!(rtnval == -1 && errno == EINTR))
2707         return rtnval;
2708       /* open() was interrupted.  Was QUIT responsible?  */
2709       QUIT;
2710     }
2711 }
2712
2713 #ifdef ENCAPSULATE_CLOSE
2714 int
2715 sys_close (int filedes)
2716 {
2717 #ifdef INTERRUPTIBLE_CLOSE
2718   int did_retry = 0;
2719   REGISTER int rtnval;
2720
2721   while ((rtnval = close (filedes)) == -1
2722          && (errno == EINTR))
2723     did_retry = 1;
2724
2725   /* If close is interrupted SunOS 4.1 may or may not have closed the
2726      file descriptor.  If it did the second close will fail with
2727      errno = EBADF.  That means we have succeeded.  */
2728   if (rtnval == -1 && did_retry && errno == EBADF)
2729     return 0;
2730
2731   return rtnval;
2732 #else
2733   return close (filedes);
2734 #endif
2735 }
2736 #endif /* ENCAPSULATE_CLOSE */
2737
2738 ssize_t
2739 sys_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
2740 {
2741   ssize_t rtnval;
2742
2743   /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
2744   while ((rtnval = read (fildes, buf, nbyte)) == -1
2745          && (errno == EINTR))
2746     {
2747       if (allow_quit)
2748         REALLY_QUIT;
2749     }
2750   return rtnval;
2751 }
2752
2753 #ifdef ENCAPSULATE_READ
2754 ssize_t
2755 sys_read (int fildes, void *buf, size_t nbyte)
2756 {
2757   return sys_read_1 (fildes, buf, nbyte, 0);
2758 }
2759 #endif /* ENCAPSULATE_READ */
2760
2761 ssize_t
2762 sys_write_1 (int fildes, const void *buf, size_t nbyte, int allow_quit)
2763 {
2764   ssize_t bytes_written = 0;
2765   const char *b = (const char *) buf;
2766
2767   /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
2768   while (nbyte > 0)
2769     {
2770       ssize_t rtnval = write (fildes, b, nbyte);
2771
2772       if (allow_quit)
2773         REALLY_QUIT;
2774
2775       if (rtnval == -1)
2776         {
2777           if (errno == EINTR)
2778             continue;
2779           else
2780             return bytes_written ? bytes_written : -1;
2781         }
2782       b += rtnval;
2783       nbyte -= rtnval;
2784       bytes_written += rtnval;
2785     }
2786   return bytes_written;
2787 }
2788
2789 #ifdef ENCAPSULATE_WRITE
2790 ssize_t
2791 sys_write (int fildes, const void *buf, size_t nbyte)
2792 {
2793   return sys_write_1 (fildes, buf, nbyte, 0);
2794 }
2795 #endif /* ENCAPSULATE_WRITE */
2796
2797
2798 /**************** stdio calls ****************/
2799
2800 /* There is at least some evidence that the stdio calls are interruptible
2801    just like the normal system calls, at least on some systems.  In any
2802    case, it doesn't hurt to encapsulate them. */
2803
2804 /* #### Should also encapsulate fflush().
2805    #### Should conceivably encapsulate getchar() etc.  What a pain! */
2806
2807 #ifdef ENCAPSULATE_FOPEN
2808 FILE *
2809 sys_fopen (const char *path, const char *type)
2810 {
2811   PATHNAME_CONVERT_OUT (path);
2812 #if defined (WINDOWSNT)
2813   {
2814     int fd;
2815     int oflag;
2816     const char * type_save = type;
2817
2818     /* Force all file handles to be non-inheritable.  This is necessary to
2819        ensure child processes don't unwittingly inherit handles that might
2820        prevent future file access. */
2821
2822     if (type[0] == 'r')
2823       oflag = O_RDONLY;
2824     else if (type[0] == 'w' || type[0] == 'a')
2825       oflag = O_WRONLY | O_CREAT | O_TRUNC;
2826     else
2827       return 0;
2828
2829     /* Only do simplistic option parsing. */
2830     while (*++type)
2831       if (type[0] == '+')
2832         {
2833           oflag &= ~(O_RDONLY | O_WRONLY);
2834           oflag |= O_RDWR;
2835         }
2836       else if (type[0] == 'b')
2837         {
2838           oflag &= ~O_TEXT;
2839           oflag |= O_BINARY;
2840         }
2841       else if (type[0] == 't')
2842         {
2843           oflag &= ~O_BINARY;
2844           oflag |= O_TEXT;
2845         }
2846       else break;
2847
2848     fd = open (path, oflag | _O_NOINHERIT, 0644);
2849     if (fd < 0)
2850       return NULL;
2851
2852     return _fdopen (fd, type_save);
2853   }
2854 #elif defined (INTERRUPTIBLE_OPEN)
2855   {
2856     FILE *rtnval;
2857     while (!(rtnval = fopen (path, type)) && (errno == EINTR))
2858       DO_NOTHING;
2859     return rtnval;
2860   }
2861 #else
2862   return fopen (path, type);
2863 #endif
2864 }
2865 #endif /* ENCAPSULATE_FOPEN */
2866
2867
2868 #ifdef ENCAPSULATE_FCLOSE
2869 int
2870 sys_fclose (FILE *stream)
2871 {
2872 #ifdef INTERRUPTIBLE_CLOSE
2873   int rtnval;
2874
2875   while ((rtnval = fclose (stream)) == EOF
2876          && (errno == EINTR))
2877     ;
2878   return rtnval;
2879 #else
2880   return fclose (stream);
2881 #endif
2882 }
2883 #endif /* ENCAPSULATE_FCLOSE */
2884
2885
2886 #ifdef ENCAPSULATE_FREAD
2887 size_t
2888 sys_fread (void *ptr, size_t size, size_t nitem, FILE *stream)
2889 {
2890 #ifdef INTERRUPTIBLE_IO
2891   size_t rtnval;
2892   size_t items_read = 0;
2893   char *b = (char *) ptr;
2894
2895   while (nitem > 0)
2896     {
2897       rtnval = fread (b, size, nitem, stream);
2898       if (rtnval == 0)
2899         {
2900           if (ferror (stream) && errno == EINTR)
2901             continue;
2902           else
2903             return items_read;
2904         }
2905       b += size*rtnval;
2906       nitem -= rtnval;
2907       items_read += rtnval;
2908     }
2909   return (items_read);
2910 #else
2911   return fread (ptr, size, nitem, stream);
2912 #endif
2913 }
2914 #endif /* ENCAPSULATE_FREAD */
2915
2916
2917 #ifdef ENCAPSULATE_FWRITE
2918 size_t
2919 sys_fwrite (const void *ptr, size_t size, size_t nitem, FILE *stream)
2920 {
2921 #ifdef INTERRUPTIBLE_IO
2922   size_t rtnval;
2923   size_t items_written = 0;
2924   const char *b = (const char *) ptr;
2925
2926   while (nitem > 0)
2927     {
2928       rtnval = fwrite (b, size, nitem, stream);
2929       if (rtnval == 0)
2930         {
2931           if (ferror (stream) && errno == EINTR)
2932             continue;
2933           else
2934             return items_written;
2935         }
2936       b += size*rtnval;
2937       nitem -= rtnval;
2938       items_written += rtnval;
2939     }
2940   return (items_written);
2941 #else
2942   return fwrite (ptr, size, nitem, stream);
2943 #endif
2944 }
2945 #endif /* ENCAPSULATE_FWRITE */
2946
2947
2948 /********************* directory calls *******************/
2949
2950 #ifdef ENCAPSULATE_CHDIR
2951 int
2952 sys_chdir (const char *path)
2953 {
2954   PATHNAME_CONVERT_OUT (path);
2955   return chdir (path);
2956 }
2957 #endif /* ENCAPSULATE_CHDIR */
2958
2959
2960 #ifdef ENCAPSULATE_MKDIR
2961 int
2962 sys_mkdir (const char *path, mode_t mode)
2963 {
2964   PATHNAME_CONVERT_OUT (path);
2965 #ifdef WINDOWSNT
2966   return mkdir (path);
2967 #else
2968   return mkdir (path, mode);
2969 #endif
2970 }
2971 #endif /* ENCAPSULATE_MKDIR */
2972
2973
2974 #ifdef ENCAPSULATE_OPENDIR
2975 DIR *
2976 sys_opendir (const char *filename)
2977 {
2978   DIR *rtnval;
2979   PATHNAME_CONVERT_OUT (filename);
2980
2981   while (!(rtnval = opendir (filename))
2982          && (errno == EINTR))
2983     ;
2984   return rtnval;
2985 }
2986 #endif /* ENCAPSULATE_OPENDIR */
2987
2988
2989 #ifdef ENCAPSULATE_READDIR
2990 DIRENTRY *
2991 sys_readdir (DIR *dirp)
2992 {
2993   DIRENTRY *rtnval;
2994
2995   /* Apparently setting errno is necessary on some systems?
2996      Maybe readdir() doesn't always set errno ?! */
2997   while (!(errno = 0, rtnval = readdir (dirp))
2998          && (errno == EINTR))
2999     ;
3000 #ifndef MULE
3001   return rtnval;
3002 #else /* MULE */
3003   if (rtnval == NULL)           /* End of directory */
3004     return NULL;
3005   {
3006     Extcount external_len;
3007     int ascii_filename_p = 1;
3008     const Extbyte * const external_name = (const Extbyte *) rtnval->d_name;
3009
3010     /* Optimize for the common all-ASCII case, computing len en passant */
3011     for (external_len = 0; external_name[external_len] ; external_len++)
3012       {
3013         if (!BYTE_ASCII_P (external_name[external_len]))
3014           ascii_filename_p = 0;
3015       }
3016     if (ascii_filename_p)
3017       return rtnval;
3018
3019     { /* Non-ASCII filename */
3020       static Bufbyte_dynarr *internal_DIRENTRY;
3021       const Bufbyte *internal_name;
3022       Bytecount internal_len;
3023       if (!internal_DIRENTRY)
3024         internal_DIRENTRY = Dynarr_new (Bufbyte);
3025       else
3026         Dynarr_reset (internal_DIRENTRY);
3027
3028       Dynarr_add_many (internal_DIRENTRY, (Bufbyte *) rtnval,
3029                        offsetof (DIRENTRY, d_name));
3030
3031       TO_INTERNAL_FORMAT (DATA, (external_name, external_len),
3032                           ALLOCA, (internal_name, internal_len),
3033                           Qfile_name);
3034
3035       Dynarr_add_many (internal_DIRENTRY, internal_name, internal_len);
3036       Dynarr_add (internal_DIRENTRY, 0); /* zero-terminate */
3037       return (DIRENTRY *) Dynarr_atp (internal_DIRENTRY, 0);
3038     }
3039   }
3040 #endif /* MULE */
3041 }
3042 #endif /* ENCAPSULATE_READDIR */
3043
3044
3045 #ifdef ENCAPSULATE_CLOSEDIR
3046 int
3047 sys_closedir (DIR *dirp)
3048 {
3049   int rtnval;
3050
3051   while ((rtnval = closedir (dirp)) == -1
3052          && (errno == EINTR))
3053     ;
3054   return rtnval;
3055 }
3056 #endif /* ENCAPSULATE_CLOSEDIR */
3057
3058
3059 #ifdef ENCAPSULATE_RMDIR
3060 int
3061 sys_rmdir (const char *path)
3062 {
3063   PATHNAME_CONVERT_OUT (path);
3064   return rmdir (path);
3065 }
3066 #endif /* ENCAPSULATE_RMDIR */
3067
3068
3069 /***************** file-information calls ******************/
3070
3071 #ifdef ENCAPSULATE_ACCESS
3072 int
3073 sys_access (const char *path, int mode)
3074 {
3075   PATHNAME_CONVERT_OUT (path);
3076   return access (path, mode);
3077 }
3078 #endif /* ENCAPSULATE_ACCESS */
3079
3080
3081 #ifdef HAVE_EACCESS
3082 #ifdef ENCAPSULATE_EACCESS
3083 int
3084 sys_eaccess (const char *path, int mode)
3085 {
3086   PATHNAME_CONVERT_OUT (path);
3087   return eaccess (path, mode);
3088 }
3089 #endif /* ENCAPSULATE_EACCESS */
3090 #endif /* HAVE_EACCESS */
3091
3092
3093 #ifdef ENCAPSULATE_LSTAT
3094 int
3095 sys_lstat (const char *path, struct stat *buf)
3096 {
3097   PATHNAME_CONVERT_OUT (path);
3098   return lstat (path, buf);
3099 }
3100 #endif /* ENCAPSULATE_LSTAT */
3101
3102
3103 #ifdef ENCAPSULATE_READLINK
3104 int
3105 sys_readlink (const char *path, char *buf, size_t bufsiz)
3106 {
3107   PATHNAME_CONVERT_OUT (path);
3108   /* #### currently we don't do conversions on the incoming data */
3109   return readlink (path, buf, bufsiz);
3110 }
3111 #endif /* ENCAPSULATE_READLINK */
3112
3113
3114 #ifdef ENCAPSULATE_FSTAT
3115 int
3116 sys_fstat (int fd, struct stat *buf)
3117 {
3118   return fstat (fd, buf);
3119 }
3120 #endif /* ENCAPSULATE_FSTAT */
3121
3122
3123 #ifdef ENCAPSULATE_STAT
3124 int
3125 sys_stat (const char *path, struct stat *buf)
3126 {
3127   PATHNAME_CONVERT_OUT (path);
3128   return stat (path, buf);
3129 }
3130 #endif /* ENCAPSULATE_STAT */
3131
3132
3133 /****************** file-manipulation calls *****************/
3134
3135 #ifdef ENCAPSULATE_CHMOD
3136 int
3137 sys_chmod (const char *path, mode_t mode)
3138 {
3139   PATHNAME_CONVERT_OUT (path);
3140   return chmod (path, mode);
3141 }
3142 #endif /* ENCAPSULATE_CHMOD */
3143
3144
3145 #ifdef ENCAPSULATE_CREAT
3146 int
3147 sys_creat (const char *path, mode_t mode)
3148 {
3149   PATHNAME_CONVERT_OUT (path);
3150   return creat (path, mode);
3151 }
3152 #endif /* ENCAPSULATE_CREAT */
3153
3154
3155 #ifdef ENCAPSULATE_LINK
3156 int
3157 sys_link (const char *existing, const char *new)
3158 {
3159   PATHNAME_CONVERT_OUT (existing);
3160   PATHNAME_CONVERT_OUT (new);
3161   return link (existing, new);
3162 }
3163 #endif /* ENCAPSULATE_LINK */
3164
3165
3166 #ifdef ENCAPSULATE_RENAME
3167 int
3168 sys_rename (const char *old, const char *new)
3169 {
3170   PATHNAME_CONVERT_OUT (old);
3171   PATHNAME_CONVERT_OUT (new);
3172 #ifdef WINDOWSNT
3173   /* Windows rename fails if NEW exists */
3174   if (rename (old, new) == 0)
3175     return 0;
3176   if (errno != EEXIST)
3177     return -1;
3178   unlink (new);
3179 #endif /* WINDOWSNT */
3180   return rename (old, new);
3181 }
3182 #endif /* ENCAPSULATE_RENAME */
3183
3184
3185 #ifdef ENCAPSULATE_SYMLINK
3186 int
3187 sys_symlink (const char *name1, const char *name2)
3188 {
3189   PATHNAME_CONVERT_OUT (name1);
3190   PATHNAME_CONVERT_OUT (name2);
3191   return symlink (name1, name2);
3192 }
3193 #endif /* ENCAPSULATE_SYMLINK */
3194
3195
3196 #ifdef ENCAPSULATE_UNLINK
3197 int
3198 sys_unlink (const char *path)
3199 {
3200   PATHNAME_CONVERT_OUT (path);
3201   return unlink (path);
3202 }
3203 #endif /* ENCAPSULATE_UNLINK */
3204
3205
3206 #ifdef ENCAPSULATE_EXECVP
3207 int
3208 sys_execvp (const char *path, char * const * argv)
3209 {
3210   int i, argc;
3211   char ** new_argv;
3212
3213   PATHNAME_CONVERT_OUT (path);
3214   for (argc = 0; argv[argc]; argc++)
3215     ;
3216   new_argv = alloca_array (char *, argc + 1);
3217   for (i = 0; i < argc; i++)
3218     {
3219       new_argv[i] = argv[i];
3220       PATHNAME_CONVERT_OUT (new_argv[i]);
3221     }
3222   new_argv[argc] = NULL;
3223   return execvp (path, new_argv);
3224 }
3225 #endif /* ENCAPSULATE_EXECVP */
3226
3227 \f
3228 /************************************************************************/
3229 /*                  Emulations of missing system calls                  */
3230 /************************************************************************/
3231
3232 /***** (these are primarily required for USG, it seems) *****/
3233
3234 #ifndef HAVE_GETCWD
3235 char *
3236 getcwd (char *pathname, size_t size)
3237 {
3238   return getwd (pathname);
3239 }
3240 #endif /* emulate getcwd */
3241
3242
3243 #if 0 /* mrb */
3244 /*
3245  *      Warning, this function may not duplicate BSD 4.2 action properly
3246  *      under error conditions.
3247  */
3248
3249 #ifndef HAVE_GETWD
3250 char *
3251 getwd (char *pathname)
3252 {
3253   char *npath, *spath;
3254 #if !__STDC__ && !defined(STDC_HEADERS)
3255   extern char *getcwd ();
3256 #endif
3257
3258   spath = npath = getcwd ((char *) 0, MAXPATHLEN);
3259   if (spath == 0)
3260     return spath;
3261   /* On Altos 3068, getcwd can return @hostname/dir, so discard
3262      up to first slash.  Should be harmless on other systems.  */
3263   while (*npath && *npath != '/')
3264     npath++;
3265   strcpy (pathname, npath);
3266   xfree (spath);                  /* getcwd uses malloc */
3267   return pathname;
3268 }
3269 #endif /* HAVE_GETWD */
3270 #endif /* 0 - mrb */
3271
3272 /*
3273  *      Emulate rename using unlink/link.  Note that this is
3274  *      only partially correct.  Also, doesn't enforce restriction
3275  *      that files be of same type (regular->regular, dir->dir, etc).
3276  */
3277
3278 #ifndef HAVE_RENAME
3279 int
3280 rename (const char *from, const char *to)
3281 {
3282   if (access (from, 0) == 0)
3283     {
3284       unlink (to);
3285       if (link (from, to) == 0)
3286         if (unlink (from) == 0)
3287           return (0);
3288     }
3289   return (-1);
3290 }
3291 #endif /* HAVE_RENAME */
3292
3293 #ifdef HPUX
3294 #ifndef HAVE_PERROR
3295
3296 /* HPUX curses library references perror, but as far as we know
3297    it won't be called.  Anyway this definition will do for now.  */
3298
3299 perror (void)
3300 {
3301 }
3302
3303 #endif /* not HAVE_PERROR */
3304 #endif /* HPUX */
3305
3306 #ifndef HAVE_DUP2
3307
3308 /*
3309  *      Emulate BSD dup2.  First close newd if it already exists.
3310  *      Then, attempt to dup oldd.  If not successful, call dup2 recursively
3311  *      until we are, then close the unsuccessful ones.
3312  */
3313
3314 int
3315 dup2 (int oldd, int newd)
3316 {
3317   int fd, ret;
3318
3319   sys_close (newd);
3320
3321 #ifdef F_DUPFD
3322   fd = fcntl (oldd, F_DUPFD, newd);
3323   if (fd != newd)
3324     error ("can't dup2 (%i,%i) : %s", oldd, newd, strerror (errno));
3325 #else
3326   fd = dup (old);
3327   if (fd == -1)
3328     return -1;
3329   if (fd == new)
3330     return new;
3331   ret = dup2 (old, new);
3332   sys_close (fd);
3333   return ret;
3334 #endif /*  F_DUPFD */
3335 }
3336
3337 #endif /* not HAVE_DUP2 */
3338
3339 /*
3340  *      Gettimeofday.  Simulate as much as possible.  Only accurate
3341  *      to nearest second.  Emacs doesn't use tzp so ignore it for now.
3342  */
3343
3344 #if !defined (HAVE_GETTIMEOFDAY)
3345
3346 int
3347 gettimeofday (struct timeval *tp, struct timezone *tzp)
3348 {
3349   extern long time ();
3350
3351   tp->tv_sec = time ((long *)0);
3352   tp->tv_usec = 0;
3353   if (tzp != 0)
3354     tzp->tz_minuteswest = -1;
3355   return (0);
3356 }
3357
3358 #endif /* !HAVE_GETTIMEOFDAY */
3359
3360 /* No need to encapsulate utime and utimes explicitly because all
3361    access to those functions goes through the following. */
3362
3363 int
3364 set_file_times (char *filename, EMACS_TIME atime, EMACS_TIME mtime)
3365 {
3366 #ifdef HAVE_UTIMES
3367   struct timeval tv[2];
3368   tv[0] = atime;
3369   tv[1] = mtime;
3370   return utimes (filename, tv);
3371 #else /* not HAVE_UTIMES */
3372   struct utimbuf utb;
3373   utb.actime = EMACS_SECS (atime);
3374   utb.modtime = EMACS_SECS (mtime);
3375   return utime (filename, &utb);
3376 #endif /* not HAVE_UTIMES */
3377 }
3378
3379 /* */
3380
3381 static long ticks_per_second;
3382 static long orig_user_ticks, orig_system_ticks;
3383 EMACS_TIME orig_real_time;
3384
3385 static int process_times_available;
3386
3387 /* Return the relative user and system tick count.  We try to
3388    maintain calculations in terms of integers as long as possible
3389    for increased accuracy. */
3390
3391 static int
3392 get_process_times_1 (long *user_ticks, long *system_ticks)
3393 {
3394 #if defined (_SC_CLK_TCK) || defined (CLK_TCK) && !defined(WINDOWSNT)
3395   /* We have the POSIX times() function available. */
3396   struct tms tttt;
3397   times (&tttt);
3398   *user_ticks = (long) tttt.tms_utime;
3399   *system_ticks = (long) tttt.tms_stime;
3400   return 1;
3401 #elif defined (CLOCKS_PER_SEC)
3402   *user_ticks = (long) clock ();
3403   *system_ticks = 0;
3404   return 1;
3405 #else
3406   return 0;
3407 #endif
3408 }
3409
3410 void
3411 init_process_times_very_early (void)
3412 {
3413 #if defined (_SC_CLK_TCK)
3414   ticks_per_second = sysconf (_SC_CLK_TCK);
3415 #elif defined (CLK_TCK)
3416   ticks_per_second = CLK_TCK;
3417 #elif defined (CLOCKS_PER_SEC)
3418   ticks_per_second = CLOCKS_PER_SEC;
3419 #endif
3420
3421   process_times_available = get_process_times_1 (&orig_user_ticks,
3422                                                  &orig_system_ticks);
3423   EMACS_GET_TIME (orig_real_time);
3424 }
3425
3426 /* Return the user and system times used up by this process so far. */
3427 void
3428 get_process_times (double *user_time, double *system_time, double *real_time)
3429 {
3430   EMACS_TIME curr_real_time;
3431   EMACS_TIME elapsed_time;
3432   long curr_user_ticks, curr_system_ticks;
3433
3434   EMACS_GET_TIME (curr_real_time);
3435   EMACS_SUB_TIME (elapsed_time, curr_real_time, orig_real_time);
3436   *real_time = (EMACS_SECS (elapsed_time)
3437                 + ((double) EMACS_USECS (elapsed_time)) / 1000000);
3438   if (get_process_times_1 (&curr_user_ticks, &curr_system_ticks))
3439     {
3440       *user_time = (((double) (curr_user_ticks - orig_user_ticks))
3441                     / ticks_per_second);
3442       *system_time = (((double) (curr_system_ticks - orig_system_ticks))
3443                       / ticks_per_second);
3444     }
3445   else
3446     {
3447       /* A lame OS */
3448       *user_time = *real_time;
3449       *system_time = 0;
3450     }
3451 }
3452
3453 #ifndef HAVE_RANDOM
3454 #ifdef random
3455 #define HAVE_RANDOM
3456 #endif
3457 #endif
3458
3459 /* Figure out how many bits the system's random number generator uses.
3460    `random' and `lrand48' are assumed to return 31 usable bits.
3461    BSD `rand' returns a 31 bit value but the low order bits are unusable;
3462    so we'll shift it and treat it like the 15-bit USG `rand'.  */
3463
3464 #ifndef RAND_BITS
3465 # ifdef HAVE_RANDOM
3466 #  define RAND_BITS 31
3467 # else /* !HAVE_RANDOM */
3468 #  ifdef HAVE_LRAND48
3469 #   define RAND_BITS 31
3470 #   define random lrand48
3471 #  else /* !HAVE_LRAND48 */
3472 #   define RAND_BITS 15
3473 #   if RAND_MAX == 32767
3474 #    define random rand
3475 #   else /* RAND_MAX != 32767 */
3476 #    if RAND_MAX == 2147483647
3477 #     define random() (rand () >> 16)
3478 #    else /* RAND_MAX != 2147483647 */
3479 #     ifdef USG
3480 #      define random rand
3481 #     else
3482 #      define random() (rand () >> 16)
3483 #     endif /* !BSD */
3484 #    endif /* RAND_MAX != 2147483647 */
3485 #   endif /* RAND_MAX != 32767 */
3486 #  endif /* !HAVE_LRAND48 */
3487 # endif /* !HAVE_RANDOM */
3488 #endif /* !RAND_BITS */
3489
3490 void seed_random (long arg);
3491 void
3492 seed_random (long arg)
3493 {
3494 #ifdef HAVE_RANDOM
3495   srandom ((unsigned int)arg);
3496 #else
3497 # ifdef HAVE_LRAND48
3498   srand48 (arg);
3499 # else
3500   srand ((unsigned int)arg);
3501 # endif
3502 #endif
3503 }
3504
3505 /*
3506  * Build a full Emacs-sized word out of whatever we've got.
3507  * This suffices even for a 64-bit architecture with a 15-bit rand.
3508  */
3509 long get_random (void);
3510 long
3511 get_random (void)
3512 {
3513   long val = random ();
3514 #if VALBITS > RAND_BITS
3515   val = (val << RAND_BITS) ^ random ();
3516 #if VALBITS > 2*RAND_BITS
3517   val = (val << RAND_BITS) ^ random ();
3518 #if VALBITS > 3*RAND_BITS
3519   val = (val << RAND_BITS) ^ random ();
3520 #if VALBITS > 4*RAND_BITS
3521   val = (val << RAND_BITS) ^ random ();
3522 #endif /* need at least 5 */
3523 #endif /* need at least 4 */
3524 #endif /* need at least 3 */
3525 #endif /* need at least 2 */
3526   return val & ((1L << VALBITS) - 1);
3527 }
3528
3529 \f
3530 /************************************************************************/
3531 /*               Strings corresponding to defined signals               */
3532 /************************************************************************/
3533
3534 #if !defined (SYS_SIGLIST_DECLARED) && !defined (HAVE_SYS_SIGLIST)
3535
3536 #if defined(WINDOWSNT) || defined(__CYGWIN32__)
3537 const char *sys_siglist[] =
3538   {
3539     "bum signal!!",
3540     "hangup",
3541     "interrupt",
3542     "quit",
3543     "illegal instruction",
3544     "trace trap",
3545     "iot instruction",
3546     "emt instruction",
3547     "floating point exception",
3548     "kill",
3549     "bus error",
3550     "segmentation violation",
3551     "bad argument to system call",
3552     "write on a pipe with no one to read it",
3553     "alarm clock",
3554     "software termination signal from kill",
3555     "status signal",
3556     "sendable stop signal not from tty",
3557     "stop signal from tty",
3558     "continue a stopped process",
3559     "child status has changed",
3560     "background read attempted from control tty",
3561     "background write attempted from control tty",
3562     "input record available at control tty",
3563     "exceeded CPU time limit",
3564     "exceeded file size limit"
3565     };
3566 #endif
3567
3568 #ifdef USG
3569 #ifdef AIX
3570 const char *sys_siglist[NSIG + 1] =
3571   {
3572     /* AIX has changed the signals a bit */
3573     DEFER_GETTEXT ("bogus signal"),                     /* 0 */
3574     DEFER_GETTEXT ("hangup"),                           /* 1  SIGHUP */
3575     DEFER_GETTEXT ("interrupt"),                        /* 2  SIGINT */
3576     DEFER_GETTEXT ("quit"),                             /* 3  SIGQUIT */
3577     DEFER_GETTEXT ("illegal instruction"),              /* 4  SIGILL */
3578     DEFER_GETTEXT ("trace trap"),                       /* 5  SIGTRAP */
3579     DEFER_GETTEXT ("IOT instruction"),                  /* 6  SIGIOT */
3580     DEFER_GETTEXT ("crash likely"),                     /* 7  SIGDANGER */
3581     DEFER_GETTEXT ("floating point exception"),         /* 8  SIGFPE */
3582     DEFER_GETTEXT ("kill"),                             /* 9  SIGKILL */
3583     DEFER_GETTEXT ("bus error"),                        /* 10 SIGBUS */
3584     DEFER_GETTEXT ("segmentation violation"),           /* 11 SIGSEGV */
3585     DEFER_GETTEXT ("bad argument to system call"),      /* 12 SIGSYS */
3586     DEFER_GETTEXT ("write on a pipe with no one to read it"), /* 13 SIGPIPE */
3587     DEFER_GETTEXT ("alarm clock"),                      /* 14 SIGALRM */
3588     DEFER_GETTEXT ("software termination signum"),      /* 15 SIGTERM */
3589     DEFER_GETTEXT ("user defined signal 1"),            /* 16 SIGUSR1 */
3590     DEFER_GETTEXT ("user defined signal 2"),            /* 17 SIGUSR2 */
3591     DEFER_GETTEXT ("death of a child"),                 /* 18 SIGCLD */
3592     DEFER_GETTEXT ("power-fail restart"),               /* 19 SIGPWR */
3593     DEFER_GETTEXT ("bogus signal"),                     /* 20 */
3594     DEFER_GETTEXT ("bogus signal"),                     /* 21 */
3595     DEFER_GETTEXT ("bogus signal"),                     /* 22 */
3596     DEFER_GETTEXT ("bogus signal"),                     /* 23 */
3597     DEFER_GETTEXT ("bogus signal"),                     /* 24 */
3598     DEFER_GETTEXT ("LAN I/O interrupt"),                /* 25 SIGAIO */
3599     DEFER_GETTEXT ("PTY I/O interrupt"),                /* 26 SIGPTY */
3600     DEFER_GETTEXT ("I/O intervention required"),        /* 27 SIGIOINT */
3601 #ifdef AIXHFT
3602     DEFER_GETTEXT ("HFT grant"),                        /* 28 SIGGRANT */
3603     DEFER_GETTEXT ("HFT retract"),                      /* 29 SIGRETRACT */
3604     DEFER_GETTEXT ("HFT sound done"),                   /* 30 SIGSOUND */
3605     DEFER_GETTEXT ("HFT input ready"),                  /* 31 SIGMSG */
3606 #endif
3607     0
3608   };
3609 #else /* USG, not AIX */
3610 const char *sys_siglist[NSIG + 1] =
3611   {
3612     DEFER_GETTEXT ("bogus signal"),                     /* 0 */
3613     DEFER_GETTEXT ("hangup"),                           /* 1  SIGHUP */
3614     DEFER_GETTEXT ("interrupt"),                        /* 2  SIGINT */
3615     DEFER_GETTEXT ("quit"),                             /* 3  SIGQUIT */
3616     DEFER_GETTEXT ("illegal instruction"),              /* 4  SIGILL */
3617     DEFER_GETTEXT ("trace trap"),                       /* 5  SIGTRAP */
3618     DEFER_GETTEXT ("IOT instruction"),                  /* 6  SIGIOT */
3619     DEFER_GETTEXT ("EMT instruction"),                  /* 7  SIGEMT */
3620     DEFER_GETTEXT ("floating point exception"),         /* 8  SIGFPE */
3621     DEFER_GETTEXT ("kill"),                             /* 9  SIGKILL */
3622     DEFER_GETTEXT ("bus error"),                        /* 10 SIGBUS */
3623     DEFER_GETTEXT ("segmentation violation"),           /* 11 SIGSEGV */
3624     DEFER_GETTEXT ("bad argument to system call"),      /* 12 SIGSYS */
3625     DEFER_GETTEXT ("write on a pipe with no one to read it"), /* 13 SIGPIPE */
3626     DEFER_GETTEXT ("alarm clock"),                      /* 14 SIGALRM */
3627     DEFER_GETTEXT ("software termination signum"),      /* 15 SIGTERM */
3628     DEFER_GETTEXT ("user defined signal 1"),            /* 16 SIGUSR1 */
3629     DEFER_GETTEXT ("user defined signal 2"),            /* 17 SIGUSR2 */
3630     DEFER_GETTEXT ("death of a child"),                 /* 18 SIGCLD */
3631     DEFER_GETTEXT ("power-fail restart"),               /* 19 SIGPWR */
3632 #ifdef sun
3633     DEFER_GETTEXT ("window size changed"),              /* 20 SIGWINCH */
3634     DEFER_GETTEXT ("urgent socket condition"),          /* 21 SIGURG */
3635     DEFER_GETTEXT ("pollable event occurred"),          /* 22 SIGPOLL */
3636     DEFER_GETTEXT ("stop (cannot be caught or ignored)"), /*  23 SIGSTOP */
3637     DEFER_GETTEXT ("user stop requested from tty"),     /* 24 SIGTSTP */
3638     DEFER_GETTEXT ("stopped process has been continued"), /* 25 SIGCONT */
3639     DEFER_GETTEXT ("background tty read attempted"),    /* 26 SIGTTIN */
3640     DEFER_GETTEXT ("background tty write attempted"),   /* 27 SIGTTOU */
3641     DEFER_GETTEXT ("virtual timer expired"),            /* 28 SIGVTALRM */
3642     DEFER_GETTEXT ("profiling timer expired"),          /* 29 SIGPROF */
3643     DEFER_GETTEXT ("exceeded cpu limit"),               /* 30 SIGXCPU */
3644     DEFER_GETTEXT ("exceeded file size limit"),         /* 31 SIGXFSZ */
3645     DEFER_GETTEXT ("process's lwps are blocked"),       /* 32 SIGWAITING */
3646     DEFER_GETTEXT ("special signal used by thread library"), /* 33 SIGLWP */
3647 #ifdef SIGFREEZE
3648     DEFER_GETTEXT ("special signal used by CPR"),        /* 34 SIGFREEZE */
3649 #endif
3650 #ifdef SIGTHAW
3651     DEFER_GETTEXT ("special signal used by CPR"),        /* 35 SIGTHAW */
3652 #endif
3653 #endif /* sun */
3654     0
3655   };
3656 #endif /* not AIX */
3657 #endif /* USG */
3658 #ifdef DGUX
3659 const char *sys_siglist[NSIG + 1] =
3660   {
3661     DEFER_GETTEXT ("null signal"),                       /*  0 SIGNULL   */
3662     DEFER_GETTEXT ("hangup"),                            /*  1 SIGHUP    */
3663     DEFER_GETTEXT ("interrupt"),                         /*  2 SIGINT    */
3664     DEFER_GETTEXT ("quit"),                              /*  3 SIGQUIT   */
3665     DEFER_GETTEXT ("illegal instruction"),               /*  4 SIGILL    */
3666     DEFER_GETTEXT ("trace trap"),                        /*  5 SIGTRAP   */
3667     DEFER_GETTEXT ("abort termination"),                 /*  6 SIGABRT   */
3668     DEFER_GETTEXT ("SIGEMT"),                            /*  7 SIGEMT    */
3669     DEFER_GETTEXT ("floating point exception"),          /*  8 SIGFPE    */
3670     DEFER_GETTEXT ("kill"),                              /*  9 SIGKILL   */
3671     DEFER_GETTEXT ("bus error"),                         /* 10 SIGBUS    */
3672     DEFER_GETTEXT ("segmentation violation"),            /* 11 SIGSEGV   */
3673     DEFER_GETTEXT ("bad argument to system call"),       /* 12 SIGSYS    */
3674     DEFER_GETTEXT ("write on a pipe with no reader"),    /* 13 SIGPIPE   */
3675     DEFER_GETTEXT ("alarm clock"),                       /* 14 SIGALRM   */
3676     DEFER_GETTEXT ("software termination signal"),       /* 15 SIGTERM   */
3677     DEFER_GETTEXT ("user defined signal 1"),             /* 16 SIGUSR1   */
3678     DEFER_GETTEXT ("user defined signal 2"),             /* 17 SIGUSR2   */
3679     DEFER_GETTEXT ("child stopped or terminated"),       /* 18 SIGCLD    */
3680     DEFER_GETTEXT ("power-fail restart"),                /* 19 SIGPWR    */
3681     DEFER_GETTEXT ("window size changed"),               /* 20 SIGWINCH  */
3682     DEFER_GETTEXT ("undefined"),                         /* 21           */
3683     DEFER_GETTEXT ("pollable event occurred"),           /* 22 SIGPOLL   */
3684     DEFER_GETTEXT ("sendable stop signal not from tty"), /* 23 SIGSTOP   */
3685     DEFER_GETTEXT ("stop signal from tty"),              /* 24 SIGSTP    */
3686     DEFER_GETTEXT ("continue a stopped process"),        /* 25 SIGCONT   */
3687     DEFER_GETTEXT ("attempted background tty read"),     /* 26 SIGTTIN   */
3688     DEFER_GETTEXT ("attempted background tty write"),    /* 27 SIGTTOU   */
3689     DEFER_GETTEXT ("undefined"),                         /* 28           */
3690     DEFER_GETTEXT ("undefined"),                         /* 29           */
3691     DEFER_GETTEXT ("undefined"),                         /* 30           */
3692     DEFER_GETTEXT ("undefined"),                         /* 31           */
3693     DEFER_GETTEXT ("undefined"),                         /* 32           */
3694     DEFER_GETTEXT ("socket (TCP/IP) urgent data arrival"), /* 33 SIGURG    */
3695     DEFER_GETTEXT ("I/O is possible"),                   /* 34 SIGIO     */
3696     DEFER_GETTEXT ("exceeded cpu time limit"),           /* 35 SIGXCPU   */
3697     DEFER_GETTEXT ("exceeded file size limit"),          /* 36 SIGXFSZ   */
3698     DEFER_GETTEXT ("virtual time alarm"),                /* 37 SIGVTALRM */
3699     DEFER_GETTEXT ("profiling time alarm"),              /* 38 SIGPROF   */
3700     DEFER_GETTEXT ("undefined"),                         /* 39           */
3701     DEFER_GETTEXT ("file record locks revoked"),         /* 40 SIGLOST   */
3702     DEFER_GETTEXT ("undefined"),                         /* 41           */
3703     DEFER_GETTEXT ("undefined"),                         /* 42           */
3704     DEFER_GETTEXT ("undefined"),                         /* 43           */
3705     DEFER_GETTEXT ("undefined"),                         /* 44           */
3706     DEFER_GETTEXT ("undefined"),                         /* 45           */
3707     DEFER_GETTEXT ("undefined"),                         /* 46           */
3708     DEFER_GETTEXT ("undefined"),                         /* 47           */
3709     DEFER_GETTEXT ("undefined"),                         /* 48           */
3710     DEFER_GETTEXT ("undefined"),                         /* 49           */
3711     DEFER_GETTEXT ("undefined"),                         /* 50           */
3712     DEFER_GETTEXT ("undefined"),                         /* 51           */
3713     DEFER_GETTEXT ("undefined"),                         /* 52           */
3714     DEFER_GETTEXT ("undefined"),                         /* 53           */
3715     DEFER_GETTEXT ("undefined"),                         /* 54           */
3716     DEFER_GETTEXT ("undefined"),                         /* 55           */
3717     DEFER_GETTEXT ("undefined"),                         /* 56           */
3718     DEFER_GETTEXT ("undefined"),                         /* 57           */
3719     DEFER_GETTEXT ("undefined"),                         /* 58           */
3720     DEFER_GETTEXT ("undefined"),                         /* 59           */
3721     DEFER_GETTEXT ("undefined"),                         /* 60           */
3722     DEFER_GETTEXT ("undefined"),                         /* 61           */
3723     DEFER_GETTEXT ("undefined"),                         /* 62           */
3724     DEFER_GETTEXT ("undefined"),                         /* 63           */
3725     DEFER_GETTEXT ("notification message in mess. queue"), /* 64 SIGDGNOTIFY */
3726     0
3727   };
3728 #endif /* DGUX */
3729
3730 #endif /* ! SYS_SIGLIST_DECLARED && ! HAVE_SYS_SIGLIST */
3731
3732 \f
3733 /************************************************************************/
3734 /*         Directory routines for systems that don't have them          */
3735 /************************************************************************/
3736
3737 #ifdef SYSV_SYSTEM_DIR
3738
3739 #include <dirent.h>
3740
3741 #if defined(BROKEN_CLOSEDIR) || !defined(HAVE_CLOSEDIR)
3742 int
3743 closedir (DIR *dirp)  /* stream from opendir */
3744 {
3745   int rtnval;
3746
3747   rtnval = sys_close (dirp->dd_fd);
3748
3749   /* Some systems (like Solaris) allocate the buffer and the DIR all
3750      in one block.  Why in the world are we freeing this ourselves
3751      anyway?  */
3752 #if ! (defined (sun) && defined (USG5_4))
3753   xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
3754 #endif
3755   xfree ((char *) dirp);
3756   return (rtnval);
3757 }
3758 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3759 #endif /* SYSV_SYSTEM_DIR */
3760
3761 #ifdef NONSYSTEM_DIR_LIBRARY
3762
3763 DIR *
3764 opendir (const char *filename)  /* name of directory */
3765 {
3766   DIR *dirp;            /* -> malloc'ed storage */
3767   int fd;               /* file descriptor for read */
3768   struct stat sbuf;             /* result of fstat */
3769
3770   fd = sys_open (filename, O_RDONLY);
3771   if (fd < 0)
3772     return 0;
3773
3774   if (fstat (fd, &sbuf) < 0
3775       || (sbuf.st_mode & S_IFMT) != S_IFDIR
3776       || (dirp = (DIR *) malloc (sizeof (DIR))) == 0)
3777     {
3778       sys_close (fd);
3779       return 0;         /* bad luck today */
3780     }
3781
3782   dirp->dd_fd = fd;
3783   dirp->dd_loc = dirp->dd_size = 0;     /* refill needed */
3784
3785   return dirp;
3786 }
3787
3788 void
3789 closedir (DIR *dirp)            /* stream from opendir */
3790 {
3791   sys_close (dirp->dd_fd);
3792   xfree (dirp);
3793 }
3794
3795
3796 #define DIRSIZ  14
3797 struct olddir
3798   {
3799     ino_t od_ino;               /* inode */
3800     char od_name[DIRSIZ];       /* filename */
3801   };
3802
3803 static struct direct dir_static; /* simulated directory contents */
3804
3805 /* ARGUSED */
3806 struct direct *
3807 readdir (DIR *dirp)     /* stream from opendir */
3808 {
3809   struct olddir *dp;    /* -> directory data */
3810
3811   for (; ;)
3812     {
3813       if (dirp->dd_loc >= dirp->dd_size)
3814         dirp->dd_loc = dirp->dd_size = 0;
3815
3816       if (dirp->dd_size == 0    /* refill buffer */
3817           && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3818         return 0;
3819
3820       dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
3821       dirp->dd_loc += sizeof (struct olddir);
3822
3823       if (dp->od_ino != 0)      /* not deleted entry */
3824         {
3825           dir_static.d_ino = dp->od_ino;
3826           strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
3827           dir_static.d_name[DIRSIZ] = '\0';
3828           dir_static.d_namlen = strlen (dir_static.d_name);
3829           dir_static.d_reclen = sizeof (struct direct)
3830             - MAXNAMLEN + 3
3831               + dir_static.d_namlen - dir_static.d_namlen % 4;
3832           return &dir_static;   /* -> simulated structure */
3833         }
3834     }
3835 }
3836
3837
3838 #endif /* NONSYSTEM_DIR_LIBRARY */
3839
3840 \f
3841 /* mkdir and rmdir functions, for systems which don't have them.  */
3842
3843 #ifndef HAVE_MKDIR
3844 /*
3845  * Written by Robert Rother, Mariah Corporation, August 1985.
3846  *
3847  * If you want it, it's yours.  All I ask in return is that if you
3848  * figure out how to do this in a Bourne Shell script you send me
3849  * a copy.
3850  *                                      sdcsvax!rmr or rmr@uscd
3851  *
3852  * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3853  * subroutine.  11Mar86; hoptoad!gnu
3854  *
3855  * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3856  * subroutine didn't return EEXIST.  It does now.
3857  */
3858
3859 /*
3860  * Make a directory.
3861  */
3862 #ifdef MKDIR_PROTOTYPE
3863 MKDIR_PROTOTYPE
3864 #else
3865 int
3866 mkdir (const char *dpath, int dmode)
3867 #endif
3868 {
3869   int cpid, status, fd;
3870   struct stat statbuf;
3871
3872   if (stat (dpath, &statbuf) == 0)
3873     {
3874       errno = EEXIST;           /* Stat worked, so it already exists */
3875       return -1;
3876     }
3877
3878   /* If stat fails for a reason other than non-existence, return error */
3879   if (errno != ENOENT)
3880     return -1;
3881
3882   synch_process_alive = 1;
3883   switch (cpid = fork ())
3884     {
3885
3886     case -1:                    /* Error in fork() */
3887       return -1;                /* Errno is set already */
3888
3889     case 0:                     /* Child process */
3890     {
3891       /*
3892        * Cheap hack to set mode of new directory.  Since this
3893        * child process is going away anyway, we zap its umask.
3894        * ####, this won't suffice to set SUID, SGID, etc. on this
3895        * directory.  Does anybody care?
3896        */
3897       status = umask (0);       /* Get current umask */
3898       status = umask (status | (0777 & ~dmode));        /* Set for mkdir */
3899       fd = sys_open ("/dev/null", O_RDWR);
3900       if (fd >= 0)
3901         {
3902           if (fd != STDIN_FILENO)  dup2 (fd, STDIN_FILENO);
3903           if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
3904           if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);
3905         }
3906       execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
3907       _exit (-1);               /* Can't exec /bin/mkdir */
3908     }
3909
3910     default:                    /* Parent process */
3911       wait_for_termination (cpid);
3912     }
3913
3914   if (synch_process_death != 0 || synch_process_retcode != 0)
3915     {
3916       errno = EIO;              /* We don't know why, but */
3917       return -1;                /* /bin/mkdir failed */
3918     }
3919
3920   return 0;
3921 }
3922 #endif /* not HAVE_MKDIR */
3923
3924 #ifndef HAVE_RMDIR
3925 int
3926 rmdir (const char *dpath)
3927 {
3928   int cpid, status, fd;
3929   struct stat statbuf;
3930
3931   if (stat (dpath, &statbuf) != 0)
3932     {
3933       /* Stat just set errno.  We don't have to */
3934       return -1;
3935     }
3936
3937   synch_process_alive = 1;
3938   switch (cpid = fork ())
3939     {
3940
3941     case -1:                    /* Error in fork() */
3942       return (-1);              /* Errno is set already */
3943
3944     case 0:                     /* Child process */
3945       fd = sys_open("/dev/null", O_RDWR);
3946       if (fd >= 0)
3947         {
3948           if (fd != STDIN_FILENO)  dup2 (fd, STDIN_FILENO);
3949           if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
3950           if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);
3951         }
3952       execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
3953       _exit (-1);               /* Can't exec /bin/mkdir */
3954
3955     default:                    /* Parent process */
3956       wait_for_termination (cpid);
3957     }
3958
3959   if (synch_process_death   != 0 ||
3960       synch_process_retcode != 0)
3961     {
3962       errno = EIO;              /* We don't know why, but */
3963       return -1;                /* /bin/rmdir failed */
3964     }
3965
3966   return 0;
3967 }
3968 #endif /* !HAVE_RMDIR */
3969
3970 \f
3971 /************************************************************************/
3972 /*                            Misc. SunOS crap                          */
3973 /************************************************************************/
3974
3975 #ifdef USE_DL_STUBS
3976
3977 /* These are included on Sunos 4.1 when we do not use shared libraries.
3978    X11 libraries may refer to these functions but (we hope) do not
3979    actually call them.  */
3980
3981 void *
3982 dlopen (void)
3983 {
3984   return 0;
3985 }
3986
3987 void *
3988 dlsym (void)
3989 {
3990   return 0;
3991 }
3992
3993 int
3994 dlclose (void)
3995 {
3996   return -1;
3997 }
3998
3999 #endif /* USE_DL_STUBS */
4000
4001 \f
4002
4003 #ifndef HAVE_STRCASECMP
4004 /*
4005  * From BSD
4006  */
4007 static unsigned char charmap[] = {
4008         '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
4009         '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
4010         '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
4011         '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
4012         '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
4013         '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
4014         '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
4015         '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
4016         '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
4017         '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
4018         '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
4019         '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
4020         '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
4021         '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
4022         '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
4023         '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
4024         '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
4025         '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
4026         '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
4027         '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
4028         '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
4029         '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
4030         '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
4031         '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
4032         '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
4033         '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
4034         '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
4035         '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
4036         '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
4037         '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
4038         '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
4039         '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
4040 };
4041
4042 int
4043 strcasecmp (char *s1, char *s2)
4044 {
4045   unsigned char *cm = charmap;
4046   unsigned char *us1 = (unsigned char *) s1;
4047   unsigned char *us2 = (unsigned char *)s2;
4048
4049   while (cm[*us1] == cm[*us2++])
4050     if (*us1++ == '\0')
4051       return (0);
4052
4053   return (cm[*us1] - cm[*--us2]);
4054 }
4055 #endif /* !HAVE_STRCASECMP */