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