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