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