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