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