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