XEmacs 21.2.22 "Mercedes".
[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
1377 int
1378 emacs_set_tty (int fd, struct emacs_tty *settings, int flushp)
1379 {
1380   /* Set the primary parameters - baud rate, character size, etcetera.  */
1381 #ifdef HAVE_TCATTR
1382   int i;
1383   /* We have those nifty POSIX tcmumbleattr functions.
1384      William J. Smith <wjs@wiis.wang.com> writes:
1385      "POSIX 1003.1 defines tcsetattr() to return success if it was
1386      able to perform any of the requested actions, even if some
1387      of the requested actions could not be performed.
1388      We must read settings back to ensure tty setup properly.
1389      AIX requires this to keep tty from hanging occasionally."  */
1390   /* This makes sure that we don't loop indefinitely in here.  */
1391   for (i = 0 ; i < 10 ; i++)
1392     if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
1393       {
1394         if (errno == EINTR)
1395           continue;
1396         else
1397           return -1;
1398       }
1399     else
1400       {
1401         struct termios new;
1402
1403         /* Get the current settings, and see if they're what we asked for.  */
1404         tcgetattr (fd, &new);
1405         /* We cannot use memcmp on the whole structure here because under
1406          * aix386 the termios structure has some reserved field that may
1407          * not be filled in.
1408          */
1409         if (   new.c_iflag == settings->main.c_iflag
1410             && new.c_oflag == settings->main.c_oflag
1411             && new.c_cflag == settings->main.c_cflag
1412             && new.c_lflag == settings->main.c_lflag
1413             && memcmp(new.c_cc, settings->main.c_cc, NCCS) == 0)
1414           break;
1415         else
1416           continue;
1417       }
1418 #elif defined HAVE_TERMIO
1419   /* The SYSV-style interface?  */
1420   if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
1421     return -1;
1422
1423 #elif !defined (WINDOWSNT)
1424   /* I give up - I hope you have the BSD ioctls.  */
1425   if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
1426     return -1;
1427 #endif /* HAVE_TCATTR */
1428
1429   /* Suivant - Do we have to get struct ltchars data?  */
1430 #ifdef HAVE_LTCHARS
1431   if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
1432     return -1;
1433 #endif
1434
1435   /* How about a struct tchars and a wordful of lmode bits?  */
1436 #ifdef HAVE_TCHARS
1437   if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
1438       || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
1439     return -1;
1440 #endif
1441
1442   /* We have survived the tempest.  */
1443   return 0;
1444 }
1445
1446 #endif /* WINDOWSNT */
1447 \f
1448 /* ------------------------------------------------------ */
1449 /*                 Initializing a device                  */
1450 /* ------------------------------------------------------ */
1451
1452 #ifdef HAVE_TTY
1453
1454 /* This may also be defined in stdio,
1455    but if so, this does no harm,
1456    and using the same name avoids wasting the other one's space.  */
1457
1458 #if ((defined(USG) || defined(DGUX)) && !defined(__STDC__))
1459 char _sobuf[BUFSIZ+8];
1460 #elif (defined(USG) && !defined(LINUX) && !defined(_SCO_DS)) || defined(IRIX5)
1461 extern unsigned char _sobuf[BUFSIZ+8];
1462 #else
1463 char _sobuf[BUFSIZ];
1464 #endif
1465
1466 #if defined (TIOCGLTC) && defined (HAVE_LTCHARS) /* HAVE_LTCHARS */
1467 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
1468 #endif
1469 #ifdef TIOCGETC /* HAVE_TCHARS */
1470 #ifdef HAVE_TCHARS
1471 static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
1472 #endif
1473 #endif
1474
1475 static void
1476 tty_init_sys_modes_on_device (struct device *d)
1477 {
1478   struct emacs_tty tty;
1479   int input_fd, output_fd;
1480   struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
1481
1482   input_fd = CONSOLE_TTY_DATA (con)->infd;
1483   output_fd = CONSOLE_TTY_DATA (con)->outfd;
1484
1485   EMACS_GET_TTY (input_fd, &CONSOLE_TTY_DATA (con)->old_tty);
1486   tty = CONSOLE_TTY_DATA (con)->old_tty;
1487
1488   con->tty_erase_char = Qnil;
1489
1490 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1491   /* after all those years... */
1492   con->tty_erase_char = make_char (tty.main.c_cc[VERASE]);
1493 #ifdef DGUX
1494   /* This allows meta to be sent on 8th bit.  */
1495   tty.main.c_iflag &= ~INPCK;   /* don't check input for parity */
1496 #endif
1497   tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
1498   tty.main.c_iflag &= ~ICRNL;   /* Disable map of CR to NL on input */
1499 #ifdef ISTRIP
1500   tty.main.c_iflag &= ~ISTRIP;  /* don't strip 8th bit on input */
1501 #endif
1502   tty.main.c_lflag &= ~ECHO;    /* Disable echo */
1503   tty.main.c_lflag &= ~ICANON;  /* Disable erase/kill processing */
1504 #ifdef IEXTEN
1505   tty.main.c_lflag &= ~IEXTEN;  /* Disable other editing characters.  */
1506 #endif
1507   tty.main.c_lflag |= ISIG;     /* Enable signals */
1508   if (TTY_FLAGS (con).flow_control)
1509     {
1510       tty.main.c_iflag |= IXON; /* Enable start/stop output control */
1511 #ifdef IXANY
1512       tty.main.c_iflag &= ~IXANY;
1513 #endif /* IXANY */
1514     }
1515   else
1516     tty.main.c_iflag &= ~IXON;  /* Disable start/stop output control */
1517   tty.main.c_oflag &= ~ONLCR;   /* Disable map of NL to CR-NL
1518                                    on output */
1519   tty.main.c_oflag &= ~TAB3;    /* Disable tab expansion */
1520 #ifdef CS8
1521   if (TTY_FLAGS (con).meta_key)
1522     {
1523       tty.main.c_cflag |= CS8;  /* allow 8th bit on input */
1524       tty.main.c_cflag &= ~PARENB;/* Don't check parity */
1525     }
1526 #endif
1527   if (CONSOLE_TTY_DATA (con)->controlling_terminal)
1528     {
1529       tty.main.c_cc[VINTR] =
1530         CONSOLE_QUIT_CHAR (con); /* C-g (usually) gives SIGINT */
1531       /* Set up C-g for both SIGQUIT and SIGINT.
1532          We don't know which we will get, but we handle both alike
1533          so which one it really gives us does not matter.  */
1534       tty.main.c_cc[VQUIT] = CONSOLE_QUIT_CHAR (con);
1535     }
1536   else
1537     {
1538       tty.main.c_cc[VINTR] = _POSIX_VDISABLE;
1539       tty.main.c_cc[VQUIT] = _POSIX_VDISABLE;
1540     }
1541   tty.main.c_cc[VMIN] = 1;      /* Input should wait for at
1542                                    least 1 char */
1543   tty.main.c_cc[VTIME] = 0;     /* no matter how long that takes.  */
1544 #ifdef VSWTCH
1545   tty.main.c_cc[VSWTCH] = _POSIX_VDISABLE; /* Turn off shell layering use
1546                                               of C-z */
1547 #endif /* VSWTCH */
1548   /* There was some conditionalizing here on (mips or TCATTR), but
1549      I think that's wrong.  There was one report of C-y (DSUSP) not being
1550      disabled on HP9000s700 systems, and this might fix it. */
1551 #ifdef VSUSP
1552   tty.main.c_cc[VSUSP] = _POSIX_VDISABLE; /* Turn off mips handling of C-z. */
1553 #endif /* VSUSP */
1554 #ifdef V_DSUSP
1555   tty.main.c_cc[V_DSUSP] = _POSIX_VDISABLE; /* Turn off mips handling of C-y. */
1556 #endif /* V_DSUSP */
1557 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP.  */
1558   tty.main.c_cc[VDSUSP] = _POSIX_VDISABLE;
1559 #endif /* VDSUSP */
1560 #ifdef VLNEXT
1561   tty.main.c_cc[VLNEXT] = _POSIX_VDISABLE;
1562 #endif /* VLNEXT */
1563 #ifdef VREPRINT
1564   tty.main.c_cc[VREPRINT] = _POSIX_VDISABLE;
1565 #endif /* VREPRINT */
1566 #ifdef VWERASE
1567   tty.main.c_cc[VWERASE] = _POSIX_VDISABLE;
1568 #endif /* VWERASE */
1569 #ifdef VDISCARD
1570   tty.main.c_cc[VDISCARD] = _POSIX_VDISABLE;
1571 #endif /* VDISCARD */
1572 #ifdef VSTART
1573   tty.main.c_cc[VSTART] = _POSIX_VDISABLE;
1574 #endif /* VSTART */
1575 #ifdef VSTRT
1576   tty.main.c_cc[VSTRT] = _POSIX_VDISABLE; /* called VSTRT on some systems */
1577 #endif /* VSTART */
1578 #ifdef VSTOP
1579   tty.main.c_cc[VSTOP] = _POSIX_VDISABLE;
1580 #endif /* VSTOP */
1581 #ifdef SET_LINE_DISCIPLINE
1582   /* Need to explicitly request TERMIODISC line discipline or
1583      Ultrix's termios does not work correctly.  */
1584   tty.main.c_line = SET_LINE_DISCIPLINE;
1585 #endif
1586
1587 #ifdef AIX
1588 #ifndef IBMR2AIX
1589   /* AIX enhanced edit loses NULs, so disable it. */
1590   tty.main.c_line = 0;
1591   tty.main.c_iflag &= ~ASCEDIT;
1592 #else
1593   tty.main.c_cc[VSTRT] = 255;
1594   tty.main.c_cc[VSTOP] = 255;
1595   tty.main.c_cc[VSUSP] = 255;
1596   tty.main.c_cc[VDSUSP] = 255;
1597 #endif /* IBMR2AIX */
1598   /* Also, PTY overloads NUL and BREAK.
1599      don't ignore break, but don't signal either, so it looks like NUL.
1600      This really serves a purpose only if running in an XTERM window
1601      or via TELNET or the like, but does no harm elsewhere.  */
1602   tty.main.c_iflag &= ~IGNBRK;
1603   tty.main.c_iflag &= ~BRKINT;
1604 #endif /* AIX */
1605 #else /* if not HAVE_TERMIO */
1606 #if !defined (WINDOWSNT)
1607   con->tty_erase_char = make_char (tty.main.sg_erase);
1608   tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1609   if (TTY_FLAGS (con).meta_key)
1610     tty.main.sg_flags |= ANYP;
1611   /* #### should we be using RAW mode here? */
1612   tty.main.sg_flags |= /* interrupt_input ? RAW : */ CBREAK;
1613 #endif /* not WINDOWSNT */
1614 #endif /* not HAVE_TERMIO */
1615
1616   /* If going to use CBREAK mode, we must request C-g to interrupt
1617      and turn off start and stop chars, etc.  If not going to use
1618      CBREAK mode, do this anyway so as to turn off local flow
1619      control for user coming over network on 4.2; in this case,
1620      only t_stopc and t_startc really matter.  */
1621 #ifndef HAVE_TERMIO
1622 #ifdef HAVE_TCHARS
1623   /* Note: if not using CBREAK mode, it makes no difference how we
1624      set this */
1625   tty.tchars = new_tchars;
1626   tty.tchars.t_intrc = CONSOLE_QUIT_CHAR (con);
1627   if (TTY_FLAGS (con).flow_control)
1628     {
1629       tty.tchars.t_startc = '\021';
1630       tty.tchars.t_stopc = '\023';
1631     }
1632
1633   tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH |
1634     CONSOLE_TTY_DATA (con)->old_tty.lmode;
1635
1636 #if defined (ultrix) || defined (__bsdi__)
1637   /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1638      anything, and leaving it in breaks the meta key.  Go figure.  */
1639   /* Turning off ONLCR is enough under BSD/386.  Leave the general
1640      output post-processing flag alone since for some reason it
1641      doesn't get reset after XEmacs goes away. */
1642   tty.lmode &= ~LLITOUT;
1643 #endif
1644
1645 #endif /* HAVE_TCHARS */
1646 #endif /* not HAVE_TERMIO */
1647
1648 #ifdef HAVE_LTCHARS
1649   tty.ltchars = new_ltchars;
1650 #endif /* HAVE_LTCHARS */
1651
1652   EMACS_SET_TTY (input_fd, &tty, 0);
1653
1654   /* This code added to insure that, if flow-control is not to be used,
1655      we have an unlocked terminal at the start. */
1656
1657 #ifdef TCXONC
1658   if (!TTY_FLAGS (con).flow_control) ioctl (input_fd, TCXONC, 1);
1659 #endif
1660 #ifndef APOLLO
1661 #ifdef TIOCSTART
1662   if (!TTY_FLAGS (con).flow_control) ioctl (input_fd, TIOCSTART, 0);
1663 #endif
1664 #endif
1665
1666 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1667 #ifdef TCOON
1668   if (!TTY_FLAGS (con).flow_control) tcflow (input_fd, TCOON);
1669 #endif
1670 #endif
1671 #ifdef AIXHFT
1672   hft_init (con);
1673 #ifdef IBMR2AIX
1674   {
1675     /* IBM's HFT device usually thinks a ^J should be LF/CR.
1676        We need it to be only LF.  This is the way that is
1677        done. */
1678     struct termio tty;
1679
1680     if (ioctl (output_fd, HFTGETID, &tty) != -1)
1681       write (output_fd, "\033[20l", 5);
1682   }
1683 #endif
1684 #endif
1685
1686 #if 0 /* We do our own buffering with lstreams. */
1687 #ifdef _IOFBF
1688   /* This symbol is defined on recent USG systems.
1689      Someone says without this call USG won't really buffer the file
1690      even with a call to setbuf. */
1691   setvbuf (CONSOLE_TTY_DATA (con)->outfd, (char *) _sobuf, _IOFBF, sizeof _sobuf);
1692 #else
1693   setbuf (CONSOLE_TTY_DATA (con)->outfd, (char *) _sobuf);
1694 #endif
1695 #endif
1696   set_tty_modes (con);
1697 }
1698
1699 #endif /* HAVE_TTY */
1700
1701 void
1702 init_one_device (struct device *d)
1703 {
1704 #ifdef HAVE_TTY
1705   if (DEVICE_TTY_P (d))
1706     tty_init_sys_modes_on_device (d);
1707 #endif
1708 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
1709   if (!DEVICE_STREAM_P (d))
1710     {
1711       init_sigio_on_device (d);
1712       request_sigio_on_device (d);
1713     }
1714 #endif
1715 }
1716
1717 void
1718 init_one_console (struct console *con)
1719 {
1720   Lisp_Object devcons;
1721
1722   CONSOLE_DEVICE_LOOP (devcons, con)
1723     {
1724       struct device *d = XDEVICE (XCAR (devcons));
1725
1726       init_one_device (d);
1727     }
1728 }
1729
1730 void
1731 reinit_initial_console (void)
1732 {
1733   munge_process_groups ();
1734   if (CONSOLEP (Vcontrolling_terminal) &&
1735       CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)))
1736     init_one_console (XCONSOLE (Vcontrolling_terminal));
1737 }
1738
1739 \f
1740 /* ------------------------------------------------------ */
1741 /*                   Other TTY functions                  */
1742 /* ------------------------------------------------------ */
1743
1744 #ifdef HAVE_TTY
1745
1746 #if 0 /* not currently used */
1747
1748 /* Return nonzero if safe to use tabs in output.
1749    At the time this is called, init_sys_modes has not been done yet.  */
1750
1751 int
1752 tabs_safe_p (struct device *d)
1753 {
1754 #ifdef HAVE_TTY
1755   if (DEVICE_TTY_P (d))
1756     {
1757       struct emacs_tty tty;
1758
1759       EMACS_GET_TTY (DEVICE_INFD (d), &tty);
1760       return EMACS_TTY_TABS_OK (&tty);
1761     }
1762 #endif
1763   return 1;
1764 }
1765
1766 #endif /* 0 */
1767
1768 /* Get terminal size from system.
1769    Store number of lines into *heightp and width into *widthp.
1770    If zero or a negative number is stored, the value is not valid.  */
1771
1772 void
1773 get_tty_device_size (struct device *d, int *widthp, int *heightp)
1774 {
1775   int input_fd = DEVICE_INFD (d);
1776
1777   assert (DEVICE_TTY_P (d));
1778
1779 #ifdef TIOCGWINSZ
1780   {
1781     /* BSD-style.  */
1782     struct winsize size;
1783
1784     if (ioctl (input_fd, TIOCGWINSZ, &size) == -1)
1785       *widthp = *heightp = 0;
1786     else
1787       {
1788         *widthp = size.ws_col;
1789         *heightp = size.ws_row;
1790       }
1791   }
1792 #elif defined TIOCGSIZE
1793   {
1794     /* SunOS - style.  */
1795     struct ttysize size;
1796
1797     if (ioctl (input_fd, TIOCGSIZE, &size) == -1)
1798       *widthp = *heightp = 0;
1799     else
1800       {
1801         *widthp = size.ts_cols;
1802         *heightp = size.ts_lines;
1803       }
1804   }
1805 #else /* system doesn't know size */
1806
1807   *widthp = 0;
1808   *heightp = 0;
1809
1810 #endif /* not !TIOCGWINSZ */
1811 }
1812
1813 #endif /* HAVE_TTY */
1814
1815 \f
1816 /* ------------------------------------------------------ */
1817 /*                   Is device 8 bit ?                    */
1818 /* ------------------------------------------------------ */
1819
1820 #ifdef HAVE_TTY
1821
1822 int
1823 eight_bit_tty (struct device *d)
1824 {
1825   struct emacs_tty s;
1826   int input_fd;
1827   int eight_bit = 0;
1828
1829   assert (DEVICE_TTY_P (d));
1830   input_fd = DEVICE_INFD (d);
1831
1832   EMACS_GET_TTY (input_fd, &s);
1833
1834 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1835   eight_bit = (s.main.c_cflag & CSIZE) == CS8;
1836 #else
1837   eight_bit = 0;        /* I don't know how to do it */
1838 #endif
1839   return eight_bit;
1840 }
1841
1842 #endif /* HAVE_TTY */
1843
1844 \f
1845 /* ------------------------------------------------------ */
1846 /*                   Resetting a device                   */
1847 /* ------------------------------------------------------ */
1848
1849 #ifdef HAVE_TTY
1850
1851 /* Prepare the terminal for exiting Emacs; move the cursor to the
1852    bottom of the frame, turn off interrupt-driven I/O, etc.  */
1853 static void
1854 tty_reset_sys_modes_on_device (struct device *d)
1855 {
1856   int input_fd, output_fd;
1857   struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
1858
1859   input_fd = CONSOLE_TTY_DATA (con)->infd;
1860   output_fd = CONSOLE_TTY_DATA (con)->outfd;
1861
1862 #if defined (IBMR2AIX) && defined (AIXHFT)
1863   {
1864     /* HFT consoles normally use ^J as a LF/CR.  We forced it to
1865        do the LF only.  Now, we need to reset it. */
1866     struct termio tty;
1867
1868     if (ioctl (output_fd, HFTGETID, &tty) != -1)
1869       write (output_fd, "\033[20h", 5);
1870   }
1871 #endif
1872
1873   tty_redisplay_shutdown (con);
1874   /* reset_tty_modes() flushes the connection at its end. */
1875   reset_tty_modes (con);
1876
1877 #if defined (BSD)
1878   /* Avoid possible loss of output when changing terminal modes.  */
1879   fsync (output_fd);
1880 #endif
1881
1882   while (EMACS_SET_TTY (input_fd, &CONSOLE_TTY_DATA (con)->old_tty, 0)
1883          < 0 && errno == EINTR)
1884     ;
1885
1886 #ifdef SET_LINE_DISCIPLINE
1887   /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1888      A different old line discipline is therefore not restored, yet.
1889      Restore the old line discipline by hand.  */
1890   ioctl (input_fd, TIOCSETD, &old_tty.main.c_line);
1891 #endif
1892
1893 #ifdef AIXHFT
1894   hft_reset (con);
1895 #endif
1896
1897 }
1898
1899 #endif /* HAVE_TTY */
1900
1901 void
1902 reset_one_device (struct device *d)
1903 {
1904 #ifdef HAVE_TTY
1905   if (DEVICE_TTY_P (d))
1906     tty_reset_sys_modes_on_device (d);
1907   else
1908 #endif
1909   if (DEVICE_STREAM_P (d))
1910     fflush (CONSOLE_STREAM_DATA (XCONSOLE (DEVICE_CONSOLE (d)))->out);
1911 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
1912   if (!DEVICE_STREAM_P (d))
1913     {
1914       unrequest_sigio_on_device (d);
1915       reset_sigio_on_device (d);
1916     }
1917 #endif
1918 }
1919
1920 void
1921 reset_one_console (struct console *con)
1922 {
1923   /* Note: this can be called during GC. */
1924   Lisp_Object devcons;
1925
1926   CONSOLE_DEVICE_LOOP (devcons, con)
1927     {
1928       struct device *d = XDEVICE (XCAR (devcons));
1929
1930       reset_one_device (d);
1931     }
1932 }
1933
1934 void
1935 reset_all_consoles (void)
1936 {
1937   /* Note: this can be called during GC. */
1938   Lisp_Object concons;
1939
1940   CONSOLE_LOOP (concons)
1941     {
1942       struct console *con = XCONSOLE (XCAR (concons));
1943
1944       reset_one_console (con);
1945     }
1946
1947   unmunge_process_groups ();
1948 }
1949
1950 void
1951 reset_initial_console (void)
1952 {
1953   if (CONSOLEP (Vcontrolling_terminal) &&
1954       CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)))
1955     reset_one_console (XCONSOLE (Vcontrolling_terminal));
1956   unmunge_process_groups ();
1957 }
1958
1959 \f
1960 /* ------------------------------------------------------ */
1961 /*                 extra TTY stuff under AIX              */
1962 /* ------------------------------------------------------ */
1963
1964 #ifdef AIXHFT
1965
1966 /* Called from init_sys_modes.  */
1967 static void
1968 hft_init (struct console *con)
1969 {
1970   int junk;
1971   int input_fd;
1972
1973   assert (CONSOLE_TTY_P (con));
1974   input_fd = CONSOLE_TTY_DATA (con)->infd;
1975
1976   /* If we're not on an HFT we shouldn't do any of this.  We determine
1977      if we are on an HFT by trying to get an HFT error code.  If this
1978      call fails, we're not on an HFT. */
1979 #ifdef IBMR2AIX
1980   if (ioctl (input_fd, HFQERROR, &junk) < 0)
1981     return;
1982 #else /* not IBMR2AIX */
1983   if (ioctl (input_fd, HFQEIO, 0) < 0)
1984     return;
1985 #endif /* not IBMR2AIX */
1986
1987   /* On AIX the default hft keyboard mapping uses backspace rather than delete
1988      as the rubout key's ASCII code.  Here this is changed.  The bug is that
1989      there's no way to determine the old mapping, so in reset_one_console
1990      we need to assume that the normal map had been present.  Of course, this
1991      code also doesn't help if on a terminal emulator which doesn't understand
1992      HFT VTD's. */
1993   {
1994     struct hfbuf buf;
1995     struct hfkeymap keymap;
1996
1997     buf.hf_bufp = (char *)&keymap;
1998     buf.hf_buflen = sizeof (keymap);
1999     keymap.hf_nkeys = 2;
2000     keymap.hfkey[0].hf_kpos = 15;
2001     keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
2002 #ifdef IBMR2AIX
2003     keymap.hfkey[0].hf_keyidh = '<';
2004 #else /* not IBMR2AIX */
2005     keymap.hfkey[0].hf_page = '<';
2006 #endif /* not IBMR2AIX */
2007     keymap.hfkey[0].hf_char = 127;
2008     keymap.hfkey[1].hf_kpos = 15;
2009     keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
2010 #ifdef IBMR2AIX
2011     keymap.hfkey[1].hf_keyidh = '<';
2012 #else /* not IBMR2AIX */
2013     keymap.hfkey[1].hf_page = '<';
2014 #endif /* not IBMR2AIX */
2015     keymap.hfkey[1].hf_char = 127;
2016     hftctl (input_fd, HFSKBD, &buf);
2017   }
2018   /* #### Should probably set a console TTY flag here. */
2019 #if 0
2020   /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
2021      at times. */
2022   line_ins_del_ok = char_ins_del_ok = 0;
2023 #endif /* 0 */
2024 }
2025
2026 /* Reset the rubout key to backspace. */
2027
2028 static void
2029 hft_reset (struct console *con)
2030 {
2031   struct hfbuf buf;
2032   struct hfkeymap keymap;
2033   int junk;
2034   int input_fd;
2035
2036   assert (CONSOLE_TTY_P (con));
2037   input_fd = CONSOLE_TTY_DATA (con)->infd;
2038
2039 #ifdef IBMR2AIX
2040   if (ioctl (input_fd, HFQERROR, &junk) < 0)
2041     return;
2042 #else /* not IBMR2AIX */
2043   if (ioctl (input_fd, HFQEIO, 0) < 0)
2044     return;
2045 #endif /* not IBMR2AIX */
2046
2047   buf.hf_bufp = (char *)&keymap;
2048   buf.hf_buflen = sizeof (keymap);
2049   keymap.hf_nkeys = 2;
2050   keymap.hfkey[0].hf_kpos = 15;
2051   keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
2052 #ifdef IBMR2AIX
2053   keymap.hfkey[0].hf_keyidh = '<';
2054 #else /* not IBMR2AIX */
2055   keymap.hfkey[0].hf_page = '<';
2056 #endif /* not IBMR2AIX */
2057   keymap.hfkey[0].hf_char = 8;
2058   keymap.hfkey[1].hf_kpos = 15;
2059   keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
2060 #ifdef IBMR2AIX
2061   keymap.hfkey[1].hf_keyidh = '<';
2062 #else /* not IBMR2AIX */
2063   keymap.hfkey[1].hf_page = '<';
2064 #endif /* not IBMR2AIX */
2065   keymap.hfkey[1].hf_char = 8;
2066   hftctl (input_fd, HFSKBD, &buf);
2067 }
2068
2069 #endif /* AIXHFT */
2070
2071 \f
2072 /************************************************************************/
2073 /*                    limits of text/data segments                      */
2074 /************************************************************************/
2075
2076 #ifndef CANNOT_DUMP
2077 #define NEED_STARTS
2078 #endif
2079
2080 #ifndef SYSTEM_MALLOC
2081 #ifndef NEED_STARTS
2082 #define NEED_STARTS
2083 #endif
2084 #endif
2085
2086 #ifdef NEED_STARTS
2087 /* Some systems that cannot dump also cannot implement these.  */
2088
2089 /*
2090  *      Return the address of the start of the text segment prior to
2091  *      doing an unexec.  After unexec the return value is undefined.
2092  *      See crt0.c for further explanation and _start.
2093  *
2094  */
2095
2096 #ifdef __cplusplus
2097   extern "C" int _start ();
2098 #else
2099   extern int _start ();
2100 #endif
2101
2102 #ifndef HAVE_TEXT_START
2103 char *
2104 start_of_text (void)
2105 {
2106 #ifdef TEXT_START
2107   return ((char *) TEXT_START);
2108 #else
2109 #ifdef GOULD
2110   extern csrt ();
2111   return ((char *) csrt);
2112 #else /* not GOULD */
2113   return ((char *) _start);
2114 #endif /* GOULD */
2115 #endif /* TEXT_START */
2116 }
2117 #endif /* not HAVE_TEXT_START */
2118
2119 /*
2120  *      Return the address of the start of the data segment prior to
2121  *      doing an unexec.  After unexec the return value is undefined.
2122  *      See crt0.c for further information and definition of data_start.
2123  *
2124  *      Apparently, on BSD systems this is etext at startup.  On
2125  *      USG systems (swapping) this is highly mmu dependent and
2126  *      is also dependent on whether or not the program is running
2127  *      with shared text.  Generally there is a (possibly large)
2128  *      gap between end of text and start of data with shared text.
2129  *
2130  *      On Uniplus+ systems with shared text, data starts at a
2131  *      fixed address.  Each port (from a given oem) is generally
2132  *      different, and the specific value of the start of data can
2133  *      be obtained via the UniPlus+ specific "uvar" system call,
2134  *      however the method outlined in crt0.c seems to be more portable.
2135  *
2136  *      Probably what will have to happen when a USG unexec is available,
2137  *      at least on UniPlus, is temacs will have to be made unshared so
2138  *      that text and data are contiguous.  Then once loadup is complete,
2139  *      unexec will produce a shared executable where the data can be
2140  *      at the normal shared text boundary and the startofdata variable
2141  *      will be patched by unexec to the correct value.
2142  *
2143  */
2144
2145 #ifdef ORDINARY_LINK
2146 extern char **environ;
2147 #endif
2148
2149 void *
2150 start_of_data (void)
2151 {
2152 #ifdef DATA_START
2153   return ((char *) DATA_START);
2154 #else
2155 #ifdef ORDINARY_LINK
2156   /*
2157    * This is a hack.  Since we're not linking crt0.c or pre_crt0.c,
2158    * data_start isn't defined.  We take the address of environ, which
2159    * is known to live at or near the start of the system crt0.c, and
2160    * we don't sweat the handful of bytes that might lose.
2161    */
2162 #ifdef HEAP_IN_DATA
2163   extern char* static_heap_base;
2164   if (!initialized)
2165     return static_heap_base;
2166 #endif
2167   return((char *) &environ);
2168 #else
2169   extern int data_start;
2170   return ((char *) &data_start);
2171 #endif /* ORDINARY_LINK */
2172 #endif /* DATA_START */
2173 }
2174 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2175
2176 #ifndef CANNOT_DUMP
2177 /* Some systems that cannot dump also cannot implement these.  */
2178
2179 /*
2180  *      Return the address of the end of the text segment prior to
2181  *      doing an unexec.  After unexec the return value is undefined.
2182  */
2183
2184 char *
2185 end_of_text (void)
2186 {
2187 #ifdef TEXT_END
2188   return ((char *) TEXT_END);
2189 #else
2190   extern int etext;
2191   return ((char *) &etext);
2192 #endif
2193 }
2194
2195 /*
2196  *      Return the address of the end of the data segment prior to
2197  *      doing an unexec.  After unexec the return value is undefined.
2198  */
2199
2200 char *
2201 end_of_data (void)
2202 {
2203 #ifdef DATA_END
2204   return ((char *) DATA_END);
2205 #else
2206   extern int edata;
2207   return ((char *) &edata);
2208 #endif
2209 }
2210
2211 #endif /* not CANNOT_DUMP */
2212
2213 \f
2214 /************************************************************************/
2215 /*                          get the system name                         */
2216 /************************************************************************/
2217
2218 /* init_system_name sets up the string for the Lisp function
2219    system-name to return. */
2220
2221 extern Lisp_Object Vsystem_name;
2222
2223 #ifdef HAVE_SOCKETS
2224 # include <sys/socket.h>
2225 # include <netdb.h>
2226 #endif /* HAVE_SOCKETS */
2227
2228 void
2229 init_system_name (void)
2230 {
2231 #if defined (WINDOWSNT)
2232   char hostname [MAX_COMPUTERNAME_LENGTH + 1];
2233   size_t size = sizeof(hostname);
2234   GetComputerName (hostname, &size);
2235   Vsystem_name = build_string (hostname);
2236 #elif !defined (HAVE_GETHOSTNAME)
2237   struct utsname uts;
2238   uname (&uts);
2239   Vsystem_name = build_string (uts.nodename);
2240 #else /* HAVE_GETHOSTNAME */
2241   unsigned int hostname_size = 256;
2242   char *hostname = (char *) alloca (hostname_size);
2243
2244   /* Try to get the host name; if the buffer is too short, try
2245      again.  Apparently, the only indication gethostname gives of
2246      whether the buffer was large enough is the presence or absence
2247      of a '\0' in the string.  Eech.  */
2248   for (;;)
2249     {
2250       gethostname (hostname, hostname_size - 1);
2251       hostname[hostname_size - 1] = '\0';
2252
2253       /* Was the buffer large enough for the '\0'?  */
2254       if (strlen (hostname) < (size_t) (hostname_size - 1))
2255         break;
2256
2257       hostname_size <<= 1;
2258       hostname = (char *) alloca (hostname_size);
2259     }
2260 # if defined( HAVE_SOCKETS) && !defined(BROKEN_CYGWIN)
2261   /* Turn the hostname into the official, fully-qualified hostname.
2262      Don't do this if we're going to dump; this can confuse system
2263      libraries on some machines and make the dumped emacs core dump. */
2264 #  ifndef CANNOT_DUMP
2265   if (initialized)
2266 #  endif /* not CANNOT_DUMP */
2267     if (!strchr (hostname, '.'))
2268       {
2269         struct hostent *hp = NULL;
2270         int count;
2271 #  ifdef TRY_AGAIN
2272         for (count = 0; count < 10; count++)
2273           {
2274             h_errno = 0;
2275 #  endif
2276             /* Some systems can't handle SIGALARM/SIGIO in gethostbyname(). */
2277             stop_interrupts ();
2278             hp = gethostbyname (hostname);
2279             start_interrupts ();
2280 #  ifdef TRY_AGAIN
2281             if (! (hp == 0 && h_errno == TRY_AGAIN))
2282               break;
2283             Fsleep_for (make_int (1));
2284           }
2285 #  endif
2286         if (hp)
2287           {
2288             CONST char *fqdn = (CONST char *) hp->h_name;
2289
2290             if (!strchr (fqdn, '.'))
2291               {
2292                 /* We still don't have a fully qualified domain name.
2293                    Try to find one in the list of alternate names */
2294                 char **alias = hp->h_aliases;
2295                 while (*alias && !strchr (*alias, '.'))
2296                   alias++;
2297                 if (*alias)
2298                   fqdn = *alias;
2299               }
2300             hostname = (char *) alloca (strlen (fqdn) + 1);
2301             strcpy (hostname, fqdn);
2302           }
2303       }
2304 # endif /* HAVE_SOCKETS */
2305   Vsystem_name = build_string (hostname);
2306 #endif /* HAVE_GETHOSTNAME  */
2307   {
2308     Bufbyte *p;
2309     Bytecount i;
2310
2311     for (i = 0, p = XSTRING_DATA (Vsystem_name);
2312          i < XSTRING_LENGTH (Vsystem_name);
2313          i++, p++)
2314       {
2315         if (*p == ' ' || *p == '\t')
2316           *p = '-';
2317       }
2318   }
2319 }
2320
2321 \f
2322 /************************************************************************/
2323 /*                        Emulation of select()                         */
2324 /************************************************************************/
2325
2326 #ifndef HAVE_SELECT
2327
2328 ERROR: XEmacs requires a working select().
2329
2330 #endif /* not HAVE_SELECT */
2331
2332 \f
2333 /************************************************************************/
2334 /*                      Emulation of signal stuff                       */
2335 /************************************************************************/
2336
2337 /* BSD 4.1 crap deleted.  4.2 was released in 1983, for God's sake!  I
2338    can't imagine that anyone is actually running that OS any more.
2339    You can't use X under it (I think) because there's no select().
2340    Anyway, the signal stuff has all been changed.  If someone wants to
2341    get this stuff working again, look in the FSF Emacs sources. */
2342
2343 /* POSIX signals support - DJB */
2344
2345 #ifdef HAVE_SIGPROCMASK
2346
2347 /* #### Is there any reason this is static global rather than local? */
2348 static struct sigaction new_action, old_action;
2349
2350 signal_handler_t
2351 sys_do_signal (int signal_number, signal_handler_t action)
2352 {
2353 #if 0
2354
2355   /* XEmacs works better if system calls are *not* restarted.
2356      This allows C-g to interrupt reads and writes, on most systems.
2357
2358      #### Another possibility is to just longjmp() out of the signal
2359      handler.  According to W.R. Stevens, this should be OK on all
2360      systems.  However, I don't want to deal with the potential
2361      evil ramifications of this at this point. */
2362
2363 #ifdef DGUX
2364   /* This gets us restartable system calls for efficiency.
2365      The "else" code will work as well. */
2366   return (berk_signal (signal_number, action));
2367 #else
2368   sigemptyset (&new_action.sa_mask);
2369   new_action.sa_handler = action;
2370 #if defined (SA_RESTART)
2371   /* Emacs mostly works better with restartable system services. If this
2372    * flag exists, we probably want to turn it on here.
2373    */
2374   new_action.sa_flags = SA_RESTART;
2375 #else
2376   new_action.sa_flags = 0;
2377 #endif
2378   sigaction (signal_number, &new_action, &old_action);
2379   return (old_action.sa_handler);
2380 #endif /* DGUX */
2381
2382 #else /* not 0 */
2383
2384   sigemptyset (&new_action.sa_mask);
2385   new_action.sa_handler = action;
2386 #if defined (SA_INTERRUPT) /* don't restart system calls, under SunOS */
2387   new_action.sa_flags = SA_INTERRUPT;
2388 #else
2389   new_action.sa_flags = 0;
2390 #endif
2391   sigaction (signal_number, &new_action, &old_action);
2392   return (signal_handler_t) (old_action.sa_handler);
2393
2394 #endif /* not 0 */
2395 }
2396
2397 #elif defined (HAVE_SIGBLOCK)
2398
2399 /* We use sigvec() rather than signal() if we have it, because
2400    it lets us specify interruptible system calls. */
2401 signal_handler_t
2402 sys_do_signal (int signal_number, signal_handler_t action)
2403 {
2404   struct sigvec vec, ovec;
2405
2406   vec.sv_handler = action;
2407   vec.sv_mask = 0;
2408 #ifdef SV_INTERRUPT /* don't restart system calls */
2409   vec.sv_flags = SV_INTERRUPT;
2410 #else
2411   vec.sv_flags = 0;
2412 #endif
2413
2414   sigvec (signal_number, &vec, &ovec);
2415
2416   return (ovec.sv_handler);
2417 }
2418
2419 #endif /* HAVE_SIGBLOCK (HAVE_SIGPROCMASK) */
2420
2421 \f
2422 /************************************************************************/
2423 /*           Emulation of strerror() and errno support                  */
2424 /************************************************************************/
2425
2426 #ifndef HAVE_STRERROR
2427
2428 #if !defined(NeXT) && !defined(__alpha) && !defined(MACH) && !defined(LINUX) && !defined(IRIX) && !defined(__NetBSD__)
2429 /* Linux added here by Raymond L. Toy <toy@alydar.crd.ge.com> for XEmacs. */
2430 /* Irix added here by gparker@sni-usa.com for XEmacs. */
2431 /* NetBSD added here by James R Grinter <jrg@doc.ic.ac.uk> for XEmacs */
2432 extern CONST char *sys_errlist[];
2433 extern int sys_nerr;
2434 #endif
2435
2436 #ifdef __NetBSD__
2437 extern char *sys_errlist[];
2438 extern int sys_nerr;
2439 #endif
2440
2441
2442 CONST char *
2443 strerror (int errnum)
2444 {
2445   if (errnum >= 0 && errnum < sys_nerr)
2446     return sys_errlist[errnum];
2447   return ((CONST char *) GETTEXT ("Unknown error"));
2448 }
2449
2450 #endif /* ! HAVE_STRERROR */
2451
2452 #ifdef WINDOWSNT
2453
2454 struct errentry {
2455   unsigned long oscode;  /* Win32 error */
2456   int errnocode;         /* unix errno */
2457 };
2458
2459 static struct errentry errtable[] = {
2460   {  ERROR_INVALID_FUNCTION,       EINVAL    },  /* 1 */
2461   {  ERROR_FILE_NOT_FOUND,         ENOENT    },  /* 2 */
2462   {  ERROR_PATH_NOT_FOUND,         ENOENT    },  /* 3 */
2463   {  ERROR_TOO_MANY_OPEN_FILES,    EMFILE    },  /* 4 */
2464   {  ERROR_ACCESS_DENIED,          EACCES    },  /* 5 */
2465   {  ERROR_INVALID_HANDLE,         EBADF     },  /* 6 */
2466   {  ERROR_ARENA_TRASHED,          ENOMEM    },  /* 7 */
2467   {  ERROR_NOT_ENOUGH_MEMORY,      ENOMEM    },  /* 8 */
2468   {  ERROR_INVALID_BLOCK,          ENOMEM    },  /* 9 */
2469   {  ERROR_BAD_ENVIRONMENT,        E2BIG     },  /* 10 */
2470   {  ERROR_BAD_FORMAT,             ENOEXEC   },  /* 11 */
2471   {  ERROR_INVALID_ACCESS,         EINVAL    },  /* 12 */
2472   {  ERROR_INVALID_DATA,           EINVAL    },  /* 13 */
2473   {  ERROR_INVALID_DRIVE,          ENOENT    },  /* 15 */
2474   {  ERROR_CURRENT_DIRECTORY,      EACCES    },  /* 16 */
2475   {  ERROR_NOT_SAME_DEVICE,        EXDEV     },  /* 17 */
2476   {  ERROR_NO_MORE_FILES,          ENOENT    },  /* 18 */
2477   {  ERROR_LOCK_VIOLATION,         EACCES    },  /* 33 */
2478   {  ERROR_BAD_NETPATH,            ENOENT    },  /* 53 */
2479   {  ERROR_NETWORK_ACCESS_DENIED,  EACCES    },  /* 65 */
2480   {  ERROR_BAD_NET_NAME,           ENOENT    },  /* 67 */
2481   {  ERROR_FILE_EXISTS,            EEXIST    },  /* 80 */
2482   {  ERROR_CANNOT_MAKE,            EACCES    },  /* 82 */
2483   {  ERROR_FAIL_I24,               EACCES    },  /* 83 */
2484   {  ERROR_INVALID_PARAMETER,      EINVAL    },  /* 87 */
2485   {  ERROR_NO_PROC_SLOTS,          EAGAIN    },  /* 89 */
2486   {  ERROR_DRIVE_LOCKED,           EACCES    },  /* 108 */
2487   {  ERROR_BROKEN_PIPE,            EPIPE     },  /* 109 */
2488   {  ERROR_DISK_FULL,              ENOSPC    },  /* 112 */
2489   {  ERROR_INVALID_TARGET_HANDLE,  EBADF     },  /* 114 */
2490   {  ERROR_INVALID_HANDLE,         EINVAL    },  /* 124 */
2491   {  ERROR_WAIT_NO_CHILDREN,       ECHILD    },  /* 128 */
2492   {  ERROR_CHILD_NOT_COMPLETE,     ECHILD    },  /* 129 */
2493   {  ERROR_DIRECT_ACCESS_HANDLE,   EBADF     },  /* 130 */
2494   {  ERROR_NEGATIVE_SEEK,          EINVAL    },  /* 131 */
2495   {  ERROR_SEEK_ON_DEVICE,         EACCES    },  /* 132 */
2496   {  ERROR_DIR_NOT_EMPTY,          ENOTEMPTY },  /* 145 */
2497   {  ERROR_NOT_LOCKED,             EACCES    },  /* 158 */
2498   {  ERROR_BAD_PATHNAME,           ENOENT    },  /* 161 */
2499   {  ERROR_MAX_THRDS_REACHED,      EAGAIN    },  /* 164 */
2500   {  ERROR_LOCK_FAILED,            EACCES    },  /* 167 */
2501   {  ERROR_ALREADY_EXISTS,         EEXIST    },  /* 183 */
2502   {  ERROR_FILENAME_EXCED_RANGE,   ENOENT    },  /* 206 */
2503   {  ERROR_NESTING_NOT_ALLOWED,    EAGAIN    },  /* 215 */
2504   {  ERROR_NOT_ENOUGH_QUOTA,       ENOMEM    }    /* 1816 */
2505 };
2506
2507 /* The following two constants must be the minimum and maximum
2508    values in the (contiguous) range of Exec Failure errors. */
2509 #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
2510 #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
2511
2512 /* These are the low and high value in the range of errors that are
2513    access violations */
2514 #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
2515 #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
2516
2517 void
2518 mswindows_set_errno (unsigned long win32_error)
2519 {
2520   int i;
2521
2522   /* check the table for the OS error code */
2523   for (i = 0; i < sizeof(errtable)/sizeof(errtable[0]); ++i)
2524     {
2525       if (win32_error == errtable[i].oscode)
2526         {
2527           errno = errtable[i].errnocode;
2528           return;
2529         }
2530     }
2531
2532   /* The error code wasn't in the table.  We check for a range of
2533    * EACCES errors or exec failure errors (ENOEXEC).  Otherwise EINVAL is
2534    * returned. */
2535   if (win32_error >= MIN_EACCES_RANGE && win32_error <= MAX_EACCES_RANGE)
2536     errno = EACCES;
2537   else if (win32_error >= MIN_EXEC_ERROR && win32_error <= MAX_EXEC_ERROR)
2538     errno = ENOEXEC;
2539   else
2540     errno = EINVAL;
2541 }
2542
2543 void
2544 mswindows_set_last_errno (void)
2545 {
2546   mswindows_set_errno (GetLastError ());
2547 }
2548
2549 #endif /* WINDOWSNT */
2550
2551 \f
2552 /************************************************************************/
2553 /*                    Encapsulations of system calls                    */
2554 /************************************************************************/
2555
2556 #define PATHNAME_CONVERT_OUT(path) \
2557   GET_C_CHARPTR_EXT_FILENAME_DATA_ALLOCA ((CONST Bufbyte *) path, path)
2558
2559 /***************** low-level calls ****************/
2560
2561 /*
2562  *      On USG systems the system calls are INTERRUPTIBLE by signals
2563  *      that the user program has elected to catch.  Thus the system call
2564  *      must be retried in these cases.  To handle this without massive
2565  *      changes in the source code, we remap the standard system call names
2566  *      to names for our own functions in sysdep.c that do the system call
2567  *      with retries.  Actually, for portability reasons, it is good
2568  *      programming practice, as this example shows, to limit all actual
2569  *      system calls to a single occurrence in the source.  Sure, this
2570  *      adds an extra level of function call overhead but it is almost
2571  *      always negligible.   Fred Fish, Unisoft Systems Inc.
2572  */
2573
2574 /* Ben sez: read Dick Gabriel's essay about the Worse Is Better
2575    approach to programming and its connection to the silly
2576    interruptible-system-call business.  To find it, look on
2577    Jamie's home page (http://www.jwz.org/worse-is-better.html). */
2578
2579 #ifdef ENCAPSULATE_OPEN
2580 int
2581 sys_open (CONST char *path, int oflag, ...)
2582 {
2583   int mode;
2584   va_list ap;
2585
2586   va_start (ap, oflag);
2587   mode = va_arg (ap, int);
2588   va_end (ap);
2589
2590   PATHNAME_CONVERT_OUT (path);
2591 #if defined (WINDOWSNT)
2592   /* Make all handles non-inheritable */
2593   return open (path, oflag | _O_NOINHERIT, mode);
2594 #elif defined (INTERRUPTIBLE_OPEN)
2595   {
2596     int rtnval;
2597     while ((rtnval = open (path, oflag, mode)) == -1
2598            && (errno == EINTR))
2599       DO_NOTHING;
2600     return rtnval;
2601   }
2602 #else
2603   return open (path, oflag, mode);
2604 #endif
2605 }
2606 #endif /* ENCAPSULATE_OPEN */
2607
2608 /* Like sys_open, only when open() is interrupted by EINTR, check for
2609    QUIT.  This allows the callers of this function to be interrupted
2610    with C-g when, say, reading from named pipes.  However, this should
2611    be used with caution, as it can GC.
2612
2613    This function will not function as expected on systems where open()
2614    is not interrupted by C-g.  However, the worst that can happen is
2615    the fallback to simple open().  */
2616 int
2617 interruptible_open (CONST char *path, int oflag, int mode)
2618 {
2619   /* This function can GC */
2620   size_t len = strlen (path);
2621   char *nonreloc = (char *) alloca (len + 1);
2622
2623   /* Must copy PATH, because it might be the data of a Lisp_String,
2624      which could be relocated by GC when checking for QUIT.  */
2625   memcpy (nonreloc, path, len + 1);
2626
2627   PATHNAME_CONVERT_OUT (nonreloc);
2628
2629   for (;;)
2630     {
2631       int rtnval = open (nonreloc, oflag, mode);
2632       if (!(rtnval == -1 && errno == EINTR))
2633         return rtnval;
2634       /* open() was interrupted.  Was QUIT responsible?  */
2635       QUIT;
2636     }
2637 }
2638
2639 #ifdef ENCAPSULATE_CLOSE
2640 int
2641 sys_close (int filedes)
2642 {
2643 #ifdef INTERRUPTIBLE_CLOSE
2644   int did_retry = 0;
2645   REGISTER int rtnval;
2646
2647   while ((rtnval = close (filedes)) == -1
2648          && (errno == EINTR))
2649     did_retry = 1;
2650
2651   /* If close is interrupted SunOS 4.1 may or may not have closed the
2652      file descriptor.  If it did the second close will fail with
2653      errno = EBADF.  That means we have succeeded.  */
2654   if (rtnval == -1 && did_retry && errno == EBADF)
2655     return 0;
2656
2657   return rtnval;
2658 #else
2659   return close (filedes);
2660 #endif
2661 }
2662 #endif /* ENCAPSULATE_CLOSE */
2663
2664 ssize_t
2665 sys_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
2666 {
2667   ssize_t rtnval;
2668
2669   /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
2670   while ((rtnval = read (fildes, buf, nbyte)) == -1
2671          && (errno == EINTR))
2672     {
2673       if (allow_quit)
2674         REALLY_QUIT;
2675     }
2676   return rtnval;
2677 }
2678
2679 #ifdef ENCAPSULATE_READ
2680 ssize_t
2681 sys_read (int fildes, void *buf, size_t nbyte)
2682 {
2683   return sys_read_1 (fildes, buf, nbyte, 0);
2684 }
2685 #endif /* ENCAPSULATE_READ */
2686
2687 ssize_t
2688 sys_write_1 (int fildes, CONST void *buf, size_t nbyte, int allow_quit)
2689 {
2690   ssize_t bytes_written = 0;
2691   CONST char *b = (CONST char *) buf;
2692
2693   /* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
2694   while (nbyte > 0)
2695     {
2696       ssize_t rtnval = write (fildes, b, nbyte);
2697
2698       if (allow_quit)
2699         REALLY_QUIT;
2700
2701       if (rtnval == -1)
2702         {
2703           if (errno == EINTR)
2704             continue;
2705           else
2706             return bytes_written ? bytes_written : -1;
2707         }
2708       b += rtnval;
2709       nbyte -= rtnval;
2710       bytes_written += rtnval;
2711     }
2712   return bytes_written;
2713 }
2714
2715 #ifdef ENCAPSULATE_WRITE
2716 ssize_t
2717 sys_write (int fildes, CONST void *buf, size_t nbyte)
2718 {
2719   return sys_write_1 (fildes, buf, nbyte, 0);
2720 }
2721 #endif /* ENCAPSULATE_WRITE */
2722
2723
2724 /**************** stdio calls ****************/
2725
2726 /* There is at least some evidence that the stdio calls are interruptible
2727    just like the normal system calls, at least on some systems.  In any
2728    case, it doesn't hurt to encapsulate them. */
2729
2730 /* #### Should also encapsulate fflush().
2731    #### Should conceivably encapsulate getchar() etc.  What a pain! */
2732
2733 #ifdef ENCAPSULATE_FOPEN
2734 FILE *
2735 sys_fopen (CONST char *path, CONST char *type)
2736 {
2737   PATHNAME_CONVERT_OUT (path);
2738 #if defined (WINDOWSNT)
2739   {
2740     int fd;
2741     int oflag;
2742     const char * type_save = type;
2743
2744     /* Force all file handles to be non-inheritable.  This is necessary to
2745        ensure child processes don't unwittingly inherit handles that might
2746        prevent future file access. */
2747
2748     if (type[0] == 'r')
2749       oflag = O_RDONLY;
2750     else if (type[0] == 'w' || type[0] == 'a')
2751       oflag = O_WRONLY | O_CREAT | O_TRUNC;
2752     else
2753       return 0;
2754
2755     /* Only do simplistic option parsing. */
2756     while (*++type)
2757       if (type[0] == '+')
2758         {
2759           oflag &= ~(O_RDONLY | O_WRONLY);
2760           oflag |= O_RDWR;
2761         }
2762       else if (type[0] == 'b')
2763         {
2764           oflag &= ~O_TEXT;
2765           oflag |= O_BINARY;
2766         }
2767       else if (type[0] == 't')
2768         {
2769           oflag &= ~O_BINARY;
2770           oflag |= O_TEXT;
2771         }
2772       else break;
2773
2774     fd = open (path, oflag | _O_NOINHERIT, 0644);
2775     if (fd < 0)
2776       return NULL;
2777
2778     return _fdopen (fd, type_save);
2779   }
2780 #elif defined (INTERRUPTIBLE_OPEN)
2781   {
2782     FILE *rtnval;
2783     while (!(rtnval = fopen (path, type)) && (errno == EINTR))
2784       DO_NOTHING;
2785     return rtnval;
2786   }
2787 #else
2788   return fopen (path, type);
2789 #endif
2790 }
2791 #endif /* ENCAPSULATE_FOPEN */
2792
2793
2794 #ifdef ENCAPSULATE_FCLOSE
2795 int
2796 sys_fclose (FILE *stream)
2797 {
2798 #ifdef INTERRUPTIBLE_CLOSE
2799   int rtnval;
2800
2801   while ((rtnval = fclose (stream)) == EOF
2802          && (errno == EINTR))
2803     ;
2804   return rtnval;
2805 #else
2806   return fclose (stream);
2807 #endif
2808 }
2809 #endif /* ENCAPSULATE_FCLOSE */
2810
2811
2812 #ifdef ENCAPSULATE_FREAD
2813 size_t
2814 sys_fread (void *ptr, size_t size, size_t nitem, FILE *stream)
2815 {
2816 #ifdef INTERRUPTIBLE_IO
2817   size_t rtnval;
2818   size_t items_read = 0;
2819   char *b = (char *) ptr;
2820
2821   while (nitem > 0)
2822     {
2823       rtnval = fread (b, size, nitem, stream);
2824       if (rtnval == 0)
2825         {
2826           if (ferror (stream) && errno == EINTR)
2827             continue;
2828           else
2829             return items_read;
2830         }
2831       b += size*rtnval;
2832       nitem -= rtnval;
2833       items_read += rtnval;
2834     }
2835   return (items_read);
2836 #else
2837   return fread (ptr, size, nitem, stream);
2838 #endif
2839 }
2840 #endif /* ENCAPSULATE_FREAD */
2841
2842
2843 #ifdef ENCAPSULATE_FWRITE
2844 size_t
2845 sys_fwrite (CONST void *ptr, size_t size, size_t nitem, FILE *stream)
2846 {
2847 #ifdef INTERRUPTIBLE_IO
2848   size_t rtnval;
2849   size_t items_written = 0;
2850   CONST char *b = (CONST char *) ptr;
2851
2852   while (nitem > 0)
2853     {
2854       rtnval = fwrite (b, size, nitem, stream);
2855       if (rtnval == 0)
2856         {
2857           if (ferror (stream) && errno == EINTR)
2858             continue;
2859           else
2860             return items_written;
2861         }
2862       b += size*rtnval;
2863       nitem -= rtnval;
2864       items_written += rtnval;
2865     }
2866   return (items_written);
2867 #else
2868   return fwrite (ptr, size, nitem, stream);
2869 #endif
2870 }
2871 #endif /* ENCAPSULATE_FWRITE */
2872
2873
2874 /********************* directory calls *******************/
2875
2876 #ifdef ENCAPSULATE_CHDIR
2877 int
2878 sys_chdir (CONST char *path)
2879 {
2880   PATHNAME_CONVERT_OUT (path);
2881   return chdir (path);
2882 }
2883 #endif /* ENCAPSULATE_CHDIR */
2884
2885
2886 #ifdef ENCAPSULATE_MKDIR
2887 int
2888 sys_mkdir (CONST char *path, mode_t mode)
2889 {
2890   PATHNAME_CONVERT_OUT (path);
2891 #ifdef WINDOWSNT
2892   return mkdir (path);
2893 #else
2894   return mkdir (path, mode);
2895 #endif
2896 }
2897 #endif /* ENCAPSULATE_MKDIR */
2898
2899
2900 #ifdef ENCAPSULATE_OPENDIR
2901 DIR *
2902 sys_opendir (CONST char *filename)
2903 {
2904   DIR *rtnval;
2905   PATHNAME_CONVERT_OUT (filename);
2906
2907   while (!(rtnval = opendir (filename))
2908          && (errno == EINTR))
2909     ;
2910   return rtnval;
2911 }
2912 #endif /* ENCAPSULATE_OPENDIR */
2913
2914
2915 #ifdef ENCAPSULATE_READDIR
2916 DIRENTRY *
2917 sys_readdir (DIR *dirp)
2918 {
2919   DIRENTRY *rtnval;
2920
2921   /* Apparently setting errno is necessary on some systems?
2922      Maybe readdir() doesn't always set errno ?! */
2923   while (!(errno = 0, rtnval = readdir (dirp))
2924          && (errno == EINTR))
2925     ;
2926 #ifndef MULE
2927   return rtnval;
2928 #else /* MULE */
2929   if (rtnval == NULL)           /* End of directory */
2930     return NULL;
2931   {
2932     Extcount external_len;
2933     int ascii_filename_p = 1;
2934     CONST Extbyte * CONST external_name = (CONST Extbyte *) rtnval->d_name;
2935
2936     /* Optimize for the common all-ASCII case, computing len en passant */
2937     for (external_len = 0; external_name[external_len] ; external_len++)
2938       {
2939         if (!BYTE_ASCII_P (external_name[external_len]))
2940           ascii_filename_p = 0;
2941       }
2942     if (ascii_filename_p)
2943       return rtnval;
2944
2945     { /* Non-ASCII filename */
2946       static Bufbyte_dynarr *internal_DIRENTRY;
2947       CONST Bufbyte *internal_name;
2948       Bytecount internal_len;
2949       if (!internal_DIRENTRY)
2950         internal_DIRENTRY = Dynarr_new (Bufbyte);
2951       else
2952         Dynarr_reset (internal_DIRENTRY);
2953
2954       Dynarr_add_many (internal_DIRENTRY, (Bufbyte *) rtnval,
2955                        offsetof (DIRENTRY, d_name));
2956
2957       internal_name =
2958         convert_from_external_format (external_name, external_len,
2959                                       &internal_len, FORMAT_FILENAME);
2960
2961       Dynarr_add_many (internal_DIRENTRY, internal_name, internal_len);
2962       Dynarr_add (internal_DIRENTRY, 0); /* zero-terminate */
2963       return (DIRENTRY *) Dynarr_atp (internal_DIRENTRY, 0);
2964     }
2965   }
2966 #endif /* MULE */
2967 }
2968 #endif /* ENCAPSULATE_READDIR */
2969
2970
2971 #ifdef ENCAPSULATE_CLOSEDIR
2972 int
2973 sys_closedir (DIR *dirp)
2974 {
2975   int rtnval;
2976
2977   while ((rtnval = closedir (dirp)) == -1
2978          && (errno == EINTR))
2979     ;
2980   return rtnval;
2981 }
2982 #endif /* ENCAPSULATE_CLOSEDIR */
2983
2984
2985 #ifdef ENCAPSULATE_RMDIR
2986 int
2987 sys_rmdir (CONST char *path)
2988 {
2989   PATHNAME_CONVERT_OUT (path);
2990   return rmdir (path);
2991 }
2992 #endif /* ENCAPSULATE_RMDIR */
2993
2994
2995 /***************** file-information calls ******************/
2996
2997 #ifdef ENCAPSULATE_ACCESS
2998 int
2999 sys_access (CONST char *path, int mode)
3000 {
3001   PATHNAME_CONVERT_OUT (path);
3002   return access (path, mode);
3003 }
3004 #endif /* ENCAPSULATE_ACCESS */
3005
3006
3007 #ifdef HAVE_EACCESS
3008 #ifdef ENCAPSULATE_EACCESS
3009 int
3010 sys_eaccess (CONST char *path, int mode)
3011 {
3012   PATHNAME_CONVERT_OUT (path);
3013   return eaccess (path, mode);
3014 }
3015 #endif /* ENCAPSULATE_EACCESS */
3016 #endif /* HAVE_EACCESS */
3017
3018
3019 #ifdef ENCAPSULATE_LSTAT
3020 int
3021 sys_lstat (CONST char *path, struct stat *buf)
3022 {
3023   PATHNAME_CONVERT_OUT (path);
3024   return lstat (path, buf);
3025 }
3026 #endif /* ENCAPSULATE_LSTAT */
3027
3028
3029 #ifdef ENCAPSULATE_READLINK
3030 int
3031 sys_readlink (CONST char *path, char *buf, size_t bufsiz)
3032 {
3033   PATHNAME_CONVERT_OUT (path);
3034   /* #### currently we don't do conversions on the incoming data */
3035   return readlink (path, buf, bufsiz);
3036 }
3037 #endif /* ENCAPSULATE_READLINK */
3038
3039
3040 #ifdef ENCAPSULATE_STAT
3041 int
3042 sys_stat (CONST char *path, struct stat *buf)
3043 {
3044   PATHNAME_CONVERT_OUT (path);
3045   return stat (path, buf);
3046 }
3047 #endif /* ENCAPSULATE_STAT */
3048
3049
3050 /****************** file-manipulation calls *****************/
3051
3052 #ifdef ENCAPSULATE_CHMOD
3053 int
3054 sys_chmod (CONST char *path, mode_t mode)
3055 {
3056   PATHNAME_CONVERT_OUT (path);
3057   return chmod (path, mode);
3058 }
3059 #endif /* ENCAPSULATE_CHMOD */
3060
3061
3062 #ifdef ENCAPSULATE_CREAT
3063 int
3064 sys_creat (CONST char *path, mode_t mode)
3065 {
3066   PATHNAME_CONVERT_OUT (path);
3067   return creat (path, mode);
3068 }
3069 #endif /* ENCAPSULATE_CREAT */
3070
3071
3072 #ifdef ENCAPSULATE_LINK
3073 int
3074 sys_link (CONST char *existing, CONST char *new)
3075 {
3076   PATHNAME_CONVERT_OUT (existing);
3077   PATHNAME_CONVERT_OUT (new);
3078   return link (existing, new);
3079 }
3080 #endif /* ENCAPSULATE_LINK */
3081
3082
3083 #ifdef ENCAPSULATE_RENAME
3084 int
3085 sys_rename (CONST char *old, CONST char *new)
3086 {
3087   PATHNAME_CONVERT_OUT (old);
3088   PATHNAME_CONVERT_OUT (new);
3089 #ifdef WINDOWSNT
3090   /* Windows rename fails if NEW exists */
3091   if (rename (old, new) == 0)
3092     return 0;
3093   if (errno != EEXIST)
3094     return -1;
3095   unlink (new);
3096 #endif /* WINDOWSNT */
3097   return rename (old, new);
3098 }
3099 #endif /* ENCAPSULATE_RENAME */
3100
3101
3102 #ifdef ENCAPSULATE_SYMLINK
3103 int
3104 sys_symlink (CONST char *name1, CONST char *name2)
3105 {
3106   PATHNAME_CONVERT_OUT (name1);
3107   PATHNAME_CONVERT_OUT (name2);
3108   return symlink (name1, name2);
3109 }
3110 #endif /* ENCAPSULATE_SYMLINK */
3111
3112
3113 #ifdef ENCAPSULATE_UNLINK
3114 int
3115 sys_unlink (CONST char *path)
3116 {
3117   PATHNAME_CONVERT_OUT (path);
3118   return unlink (path);
3119 }
3120 #endif /* ENCAPSULATE_UNLINK */
3121
3122
3123 #ifdef ENCAPSULATE_EXECVP
3124 int
3125 sys_execvp (CONST char *path, char * CONST * argv)
3126 {
3127   int i, argc;
3128   char ** new_argv;
3129
3130   PATHNAME_CONVERT_OUT (path);
3131   for (argc = 0; argv[argc]; argc++)
3132     ;
3133   new_argv = alloca_array (char *, argc + 1);
3134   for (i = 0; i < argc; i++)
3135     {
3136       new_argv[i] = argv[i];
3137       PATHNAME_CONVERT_OUT (new_argv[i]);
3138     }
3139   new_argv[argc] = NULL;
3140   return execvp (path, new_argv);
3141 }
3142 #endif /* ENCAPSULATE_EXECVP */
3143
3144 \f
3145 /************************************************************************/
3146 /*                  Emulations of missing system calls                  */
3147 /************************************************************************/
3148
3149 /***** (these are primarily required for USG, it seems) *****/
3150
3151 #ifndef HAVE_GETCWD
3152 char *
3153 getcwd (char *pathname, int size)
3154 {
3155   return getwd (pathname);
3156 }
3157 #endif /* emulate getcwd */
3158
3159
3160 #if 0 /* mrb */
3161 /*
3162  *      Warning, this function may not duplicate BSD 4.2 action properly
3163  *      under error conditions.
3164  */
3165
3166 #ifndef HAVE_GETWD
3167 char *
3168 getwd (char *pathname)
3169 {
3170   char *npath, *spath;
3171 #if !__STDC__ && !defined(STDC_HEADERS)
3172   extern char *getcwd ();
3173 #endif
3174
3175   spath = npath = getcwd ((char *) 0, MAXPATHLEN);
3176   if (spath == 0)
3177     return spath;
3178   /* On Altos 3068, getcwd can return @hostname/dir, so discard
3179      up to first slash.  Should be harmless on other systems.  */
3180   while (*npath && *npath != '/')
3181     npath++;
3182   strcpy (pathname, npath);
3183   xfree (spath);                  /* getcwd uses malloc */
3184   return pathname;
3185 }
3186 #endif /* HAVE_GETWD */
3187 #endif /* 0 - mrb */
3188
3189 /*
3190  *      Emulate rename using unlink/link.  Note that this is
3191  *      only partially correct.  Also, doesn't enforce restriction
3192  *      that files be of same type (regular->regular, dir->dir, etc).
3193  */
3194
3195 #ifndef HAVE_RENAME
3196 int
3197 rename (CONST char *from, CONST char *to)
3198 {
3199   if (access (from, 0) == 0)
3200     {
3201       unlink (to);
3202       if (link (from, to) == 0)
3203         if (unlink (from) == 0)
3204           return (0);
3205     }
3206   return (-1);
3207 }
3208 #endif /* HAVE_RENAME */
3209
3210 #ifdef HPUX
3211 #ifndef HAVE_PERROR
3212
3213 /* HPUX curses library references perror, but as far as we know
3214    it won't be called.  Anyway this definition will do for now.  */
3215
3216 perror (void)
3217 {
3218 }
3219
3220 #endif /* not HAVE_PERROR */
3221 #endif /* HPUX */
3222
3223 #ifndef HAVE_DUP2
3224
3225 /*
3226  *      Emulate BSD dup2.  First close newd if it already exists.
3227  *      Then, attempt to dup oldd.  If not successful, call dup2 recursively
3228  *      until we are, then close the unsuccessful ones.
3229  */
3230
3231 int
3232 dup2 (int oldd, int newd)
3233 {
3234   int fd, ret;
3235
3236   sys_close (newd);
3237
3238 #ifdef F_DUPFD
3239   fd = fcntl (oldd, F_DUPFD, newd);
3240   if (fd != newd)
3241     error ("can't dup2 (%i,%i) : %s", oldd, newd, strerror (errno));
3242 #else
3243   fd = dup (old);
3244   if (fd == -1)
3245     return -1;
3246   if (fd == new)
3247     return new;
3248   ret = dup2 (old, new);
3249   sys_close (fd);
3250   return ret;
3251 #endif /*  F_DUPFD */
3252 }
3253
3254 #endif /* not HAVE_DUP2 */
3255
3256 /*
3257  *      Gettimeofday.  Simulate as much as possible.  Only accurate
3258  *      to nearest second.  Emacs doesn't use tzp so ignore it for now.
3259  */
3260
3261 #if !defined (HAVE_GETTIMEOFDAY)
3262
3263 int
3264 gettimeofday (struct timeval *tp, struct timezone *tzp)
3265 {
3266   extern long time ();
3267
3268   tp->tv_sec = time ((long *)0);
3269   tp->tv_usec = 0;
3270   if (tzp != 0)
3271     tzp->tz_minuteswest = -1;
3272   return (0);
3273 }
3274
3275 #endif /* !HAVE_GETTIMEOFDAY */
3276
3277 /* No need to encapsulate utime and utimes explicitly because all
3278    access to those functions goes through the following. */
3279
3280 int
3281 set_file_times (char *filename, EMACS_TIME atime, EMACS_TIME mtime)
3282 {
3283 #ifdef HAVE_UTIMES
3284   struct timeval tv[2];
3285   tv[0] = atime;
3286   tv[1] = mtime;
3287   return utimes (filename, tv);
3288 #else /* not HAVE_UTIMES */
3289   struct utimbuf utb;
3290   utb.actime = EMACS_SECS (atime);
3291   utb.modtime = EMACS_SECS (mtime);
3292   return utime (filename, &utb);
3293 #endif /* not HAVE_UTIMES */
3294 }
3295
3296 /* */
3297
3298 static long ticks_per_second;
3299 static long orig_user_ticks, orig_system_ticks;
3300 EMACS_TIME orig_real_time;
3301
3302 static int process_times_available;
3303
3304 /* Return the relative user and system tick count.  We try to
3305    maintain calculations in terms of integers as long as possible
3306    for increased accuracy. */
3307
3308 static int
3309 get_process_times_1 (long *user_ticks, long *system_ticks)
3310 {
3311 #if defined (_SC_CLK_TCK) || defined (CLK_TCK) && !defined(WINDOWSNT)
3312   /* We have the POSIX times() function available. */
3313   struct tms tttt;
3314   times (&tttt);
3315   *user_ticks = (long) tttt.tms_utime;
3316   *system_ticks = (long) tttt.tms_stime;
3317   return 1;
3318 #elif defined (CLOCKS_PER_SEC)
3319   *user_ticks = (long) clock ();
3320   *system_ticks = 0;
3321   return 1;
3322 #else
3323   return 0;
3324 #endif
3325 }
3326
3327 void
3328 init_process_times_very_early (void)
3329 {
3330 #if defined (_SC_CLK_TCK)
3331   ticks_per_second = sysconf (_SC_CLK_TCK);
3332 #elif defined (CLK_TCK)
3333   ticks_per_second = CLK_TCK;
3334 #elif defined (CLOCKS_PER_SEC)
3335   ticks_per_second = CLOCKS_PER_SEC;
3336 #endif
3337
3338   process_times_available = get_process_times_1 (&orig_user_ticks,
3339                                                  &orig_system_ticks);
3340   EMACS_GET_TIME (orig_real_time);
3341 }
3342
3343 /* Return the user and system times used up by this process so far. */
3344 void
3345 get_process_times (double *user_time, double *system_time, double *real_time)
3346 {
3347   EMACS_TIME curr_real_time;
3348   EMACS_TIME elapsed_time;
3349   long curr_user_ticks, curr_system_ticks;
3350
3351   EMACS_GET_TIME (curr_real_time);
3352   EMACS_SUB_TIME (elapsed_time, curr_real_time, orig_real_time);
3353   *real_time = (EMACS_SECS (elapsed_time)
3354                 + ((double) EMACS_USECS (elapsed_time)) / 1000000);
3355   if (get_process_times_1 (&curr_user_ticks, &curr_system_ticks))
3356     {
3357       *user_time = (((double) (curr_user_ticks - orig_user_ticks))
3358                     / ticks_per_second);
3359       *system_time = (((double) (curr_system_ticks - orig_system_ticks))
3360                       / ticks_per_second);
3361     }
3362   else
3363     {
3364       /* A lame OS */
3365       *user_time = *real_time;
3366       *system_time = 0;
3367     }
3368 }
3369
3370 #ifndef HAVE_RANDOM
3371 #ifdef random
3372 #define HAVE_RANDOM
3373 #endif
3374 #endif
3375
3376 /* Figure out how many bits the system's random number generator uses.
3377    `random' and `lrand48' are assumed to return 31 usable bits.
3378    BSD `rand' returns a 31 bit value but the low order bits are unusable;
3379    so we'll shift it and treat it like the 15-bit USG `rand'.  */
3380
3381 #ifndef RAND_BITS
3382 # ifdef HAVE_RANDOM
3383 #  define RAND_BITS 31
3384 # else /* !HAVE_RANDOM */
3385 #  ifdef HAVE_LRAND48
3386 #   define RAND_BITS 31
3387 #   define random lrand48
3388 #  else /* !HAVE_LRAND48 */
3389 #   define RAND_BITS 15
3390 #   if RAND_MAX == 32767
3391 #    define random rand
3392 #   else /* RAND_MAX != 32767 */
3393 #    if RAND_MAX == 2147483647
3394 #     define random() (rand () >> 16)
3395 #    else /* RAND_MAX != 2147483647 */
3396 #     ifdef USG
3397 #      define random rand
3398 #     else
3399 #      define random() (rand () >> 16)
3400 #     endif /* !BSD */
3401 #    endif /* RAND_MAX != 2147483647 */
3402 #   endif /* RAND_MAX != 32767 */
3403 #  endif /* !HAVE_LRAND48 */
3404 # endif /* !HAVE_RANDOM */
3405 #endif /* !RAND_BITS */
3406
3407 void seed_random (long arg);
3408 void
3409 seed_random (long arg)
3410 {
3411 #ifdef HAVE_RANDOM
3412   srandom ((unsigned int)arg);
3413 #else
3414 # ifdef HAVE_LRAND48
3415   srand48 (arg);
3416 # else
3417   srand ((unsigned int)arg);
3418 # endif
3419 #endif
3420 }
3421
3422 /*
3423  * Build a full Emacs-sized word out of whatever we've got.
3424  * This suffices even for a 64-bit architecture with a 15-bit rand.
3425  */
3426 long get_random (void);
3427 long
3428 get_random (void)
3429 {
3430   long val = random ();
3431 #if VALBITS > RAND_BITS
3432   val = (val << RAND_BITS) ^ random ();
3433 #if VALBITS > 2*RAND_BITS
3434   val = (val << RAND_BITS) ^ random ();
3435 #if VALBITS > 3*RAND_BITS
3436   val = (val << RAND_BITS) ^ random ();
3437 #if VALBITS > 4*RAND_BITS
3438   val = (val << RAND_BITS) ^ random ();
3439 #endif /* need at least 5 */
3440 #endif /* need at least 4 */
3441 #endif /* need at least 3 */
3442 #endif /* need at least 2 */
3443   return val & ((1L << VALBITS) - 1);
3444 }
3445
3446 \f
3447 /************************************************************************/
3448 /*               Strings corresponding to defined signals               */
3449 /************************************************************************/
3450
3451 #if !defined (SYS_SIGLIST_DECLARED) && !defined (HAVE_SYS_SIGLIST)
3452
3453 #if defined(WINDOWSNT) || defined(__CYGWIN32__)
3454 CONST char *sys_siglist[] =
3455   {
3456     "bum signal!!",
3457     "hangup",
3458     "interrupt",
3459     "quit",
3460     "illegal instruction",
3461     "trace trap",
3462     "iot instruction",
3463     "emt instruction",
3464     "floating point exception",
3465     "kill",
3466     "bus error",
3467     "segmentation violation",
3468     "bad argument to system call",
3469     "write on a pipe with no one to read it",
3470     "alarm clock",
3471     "software termination signal from kill",
3472     "status signal",
3473     "sendable stop signal not from tty",
3474     "stop signal from tty",
3475     "continue a stopped process",
3476     "child status has changed",
3477     "background read attempted from control tty",
3478     "background write attempted from control tty",
3479     "input record available at control tty",
3480     "exceeded CPU time limit",
3481     "exceeded file size limit"
3482     };
3483 #endif
3484
3485 #ifdef USG
3486 #ifdef AIX
3487 CONST char *sys_siglist[NSIG + 1] =
3488   {
3489     /* AIX has changed the signals a bit */
3490     DEFER_GETTEXT ("bogus signal"),                     /* 0 */
3491     DEFER_GETTEXT ("hangup"),                           /* 1  SIGHUP */
3492     DEFER_GETTEXT ("interrupt"),                        /* 2  SIGINT */
3493     DEFER_GETTEXT ("quit"),                             /* 3  SIGQUIT */
3494     DEFER_GETTEXT ("illegal instruction"),              /* 4  SIGILL */
3495     DEFER_GETTEXT ("trace trap"),                       /* 5  SIGTRAP */
3496     DEFER_GETTEXT ("IOT instruction"),                  /* 6  SIGIOT */
3497     DEFER_GETTEXT ("crash likely"),                     /* 7  SIGDANGER */
3498     DEFER_GETTEXT ("floating point exception"),         /* 8  SIGFPE */
3499     DEFER_GETTEXT ("kill"),                             /* 9  SIGKILL */
3500     DEFER_GETTEXT ("bus error"),                        /* 10 SIGBUS */
3501     DEFER_GETTEXT ("segmentation violation"),           /* 11 SIGSEGV */
3502     DEFER_GETTEXT ("bad argument to system call"),      /* 12 SIGSYS */
3503     DEFER_GETTEXT ("write on a pipe with no one to read it"), /* 13 SIGPIPE */
3504     DEFER_GETTEXT ("alarm clock"),                      /* 14 SIGALRM */
3505     DEFER_GETTEXT ("software termination signum"),      /* 15 SIGTERM */
3506     DEFER_GETTEXT ("user defined signal 1"),            /* 16 SIGUSR1 */
3507     DEFER_GETTEXT ("user defined signal 2"),            /* 17 SIGUSR2 */
3508     DEFER_GETTEXT ("death of a child"),                 /* 18 SIGCLD */
3509     DEFER_GETTEXT ("power-fail restart"),               /* 19 SIGPWR */
3510     DEFER_GETTEXT ("bogus signal"),                     /* 20 */
3511     DEFER_GETTEXT ("bogus signal"),                     /* 21 */
3512     DEFER_GETTEXT ("bogus signal"),                     /* 22 */
3513     DEFER_GETTEXT ("bogus signal"),                     /* 23 */
3514     DEFER_GETTEXT ("bogus signal"),                     /* 24 */
3515     DEFER_GETTEXT ("LAN I/O interrupt"),                /* 25 SIGAIO */
3516     DEFER_GETTEXT ("PTY I/O interrupt"),                /* 26 SIGPTY */
3517     DEFER_GETTEXT ("I/O intervention required"),        /* 27 SIGIOINT */
3518 #ifdef AIXHFT
3519     DEFER_GETTEXT ("HFT grant"),                        /* 28 SIGGRANT */
3520     DEFER_GETTEXT ("HFT retract"),                      /* 29 SIGRETRACT */
3521     DEFER_GETTEXT ("HFT sound done"),                   /* 30 SIGSOUND */
3522     DEFER_GETTEXT ("HFT input ready"),                  /* 31 SIGMSG */
3523 #endif
3524     0
3525   };
3526 #else /* USG, not AIX */
3527 CONST char *sys_siglist[NSIG + 1] =
3528   {
3529     DEFER_GETTEXT ("bogus signal"),                     /* 0 */
3530     DEFER_GETTEXT ("hangup"),                           /* 1  SIGHUP */
3531     DEFER_GETTEXT ("interrupt"),                        /* 2  SIGINT */
3532     DEFER_GETTEXT ("quit"),                             /* 3  SIGQUIT */
3533     DEFER_GETTEXT ("illegal instruction"),              /* 4  SIGILL */
3534     DEFER_GETTEXT ("trace trap"),                       /* 5  SIGTRAP */
3535     DEFER_GETTEXT ("IOT instruction"),                  /* 6  SIGIOT */
3536     DEFER_GETTEXT ("EMT instruction"),                  /* 7  SIGEMT */
3537     DEFER_GETTEXT ("floating point exception"),         /* 8  SIGFPE */
3538     DEFER_GETTEXT ("kill"),                             /* 9  SIGKILL */
3539     DEFER_GETTEXT ("bus error"),                        /* 10 SIGBUS */
3540     DEFER_GETTEXT ("segmentation violation"),           /* 11 SIGSEGV */
3541     DEFER_GETTEXT ("bad argument to system call"),      /* 12 SIGSYS */
3542     DEFER_GETTEXT ("write on a pipe with no one to read it"), /* 13 SIGPIPE */
3543     DEFER_GETTEXT ("alarm clock"),                      /* 14 SIGALRM */
3544     DEFER_GETTEXT ("software termination signum"),      /* 15 SIGTERM */
3545     DEFER_GETTEXT ("user defined signal 1"),            /* 16 SIGUSR1 */
3546     DEFER_GETTEXT ("user defined signal 2"),            /* 17 SIGUSR2 */
3547     DEFER_GETTEXT ("death of a child"),                 /* 18 SIGCLD */
3548     DEFER_GETTEXT ("power-fail restart"),               /* 19 SIGPWR */
3549 #ifdef sun
3550     DEFER_GETTEXT ("window size changed"),              /* 20 SIGWINCH */
3551     DEFER_GETTEXT ("urgent socket condition"),          /* 21 SIGURG */
3552     DEFER_GETTEXT ("pollable event occurred"),          /* 22 SIGPOLL */
3553     DEFER_GETTEXT ("stop (cannot be caught or ignored)"), /*  23 SIGSTOP */
3554     DEFER_GETTEXT ("user stop requested from tty"),     /* 24 SIGTSTP */
3555     DEFER_GETTEXT ("stopped process has been continued"), /* 25 SIGCONT */
3556     DEFER_GETTEXT ("background tty read attempted"),    /* 26 SIGTTIN */
3557     DEFER_GETTEXT ("background tty write attempted"),   /* 27 SIGTTOU */
3558     DEFER_GETTEXT ("virtual timer expired"),            /* 28 SIGVTALRM */
3559     DEFER_GETTEXT ("profiling timer expired"),          /* 29 SIGPROF */
3560     DEFER_GETTEXT ("exceeded cpu limit"),               /* 30 SIGXCPU */
3561     DEFER_GETTEXT ("exceeded file size limit"),         /* 31 SIGXFSZ */
3562     DEFER_GETTEXT ("process's lwps are blocked"),       /* 32 SIGWAITING */
3563     DEFER_GETTEXT ("special signal used by thread library"), /* 33 SIGLWP */
3564 #ifdef SIGFREEZE
3565     DEFER_GETTEXT ("special signal used by CPR"),        /* 34 SIGFREEZE */
3566 #endif
3567 #ifdef SIGTHAW
3568     DEFER_GETTEXT ("special signal used by CPR"),        /* 35 SIGTHAW */
3569 #endif
3570 #endif /* sun */
3571     0
3572   };
3573 #endif /* not AIX */
3574 #endif /* USG */
3575 #ifdef DGUX
3576 CONST char *sys_siglist[NSIG + 1] =
3577   {
3578     DEFER_GETTEXT ("null signal"),                       /*  0 SIGNULL   */
3579     DEFER_GETTEXT ("hangup"),                            /*  1 SIGHUP    */
3580     DEFER_GETTEXT ("interrupt"),                         /*  2 SIGINT    */
3581     DEFER_GETTEXT ("quit"),                              /*  3 SIGQUIT   */
3582     DEFER_GETTEXT ("illegal instruction"),               /*  4 SIGILL    */
3583     DEFER_GETTEXT ("trace trap"),                        /*  5 SIGTRAP   */
3584     DEFER_GETTEXT ("abort termination"),                 /*  6 SIGABRT   */
3585     DEFER_GETTEXT ("SIGEMT"),                            /*  7 SIGEMT    */
3586     DEFER_GETTEXT ("floating point exception"),          /*  8 SIGFPE    */
3587     DEFER_GETTEXT ("kill"),                              /*  9 SIGKILL   */
3588     DEFER_GETTEXT ("bus error"),                         /* 10 SIGBUS    */
3589     DEFER_GETTEXT ("segmentation violation"),            /* 11 SIGSEGV   */
3590     DEFER_GETTEXT ("bad argument to system call"),       /* 12 SIGSYS    */
3591     DEFER_GETTEXT ("write on a pipe with no reader"),    /* 13 SIGPIPE   */
3592     DEFER_GETTEXT ("alarm clock"),                       /* 14 SIGALRM   */
3593     DEFER_GETTEXT ("software termination signal"),       /* 15 SIGTERM   */
3594     DEFER_GETTEXT ("user defined signal 1"),             /* 16 SIGUSR1   */
3595     DEFER_GETTEXT ("user defined signal 2"),             /* 17 SIGUSR2   */
3596     DEFER_GETTEXT ("child stopped or terminated"),       /* 18 SIGCLD    */
3597     DEFER_GETTEXT ("power-fail restart"),                /* 19 SIGPWR    */
3598     DEFER_GETTEXT ("window size changed"),               /* 20 SIGWINCH  */
3599     DEFER_GETTEXT ("undefined"),                         /* 21           */
3600     DEFER_GETTEXT ("pollable event occurred"),           /* 22 SIGPOLL   */
3601     DEFER_GETTEXT ("sendable stop signal not from tty"), /* 23 SIGSTOP   */
3602     DEFER_GETTEXT ("stop signal from tty"),              /* 24 SIGSTP    */
3603     DEFER_GETTEXT ("continue a stopped process"),        /* 25 SIGCONT   */
3604     DEFER_GETTEXT ("attempted background tty read"),     /* 26 SIGTTIN   */
3605     DEFER_GETTEXT ("attempted background tty write"),    /* 27 SIGTTOU   */
3606     DEFER_GETTEXT ("undefined"),                         /* 28           */
3607     DEFER_GETTEXT ("undefined"),                         /* 29           */
3608     DEFER_GETTEXT ("undefined"),                         /* 30           */
3609     DEFER_GETTEXT ("undefined"),                         /* 31           */
3610     DEFER_GETTEXT ("undefined"),                         /* 32           */
3611     DEFER_GETTEXT ("socket (TCP/IP) urgent data arrival"), /* 33 SIGURG    */
3612     DEFER_GETTEXT ("I/O is possible"),                   /* 34 SIGIO     */
3613     DEFER_GETTEXT ("exceeded cpu time limit"),           /* 35 SIGXCPU   */
3614     DEFER_GETTEXT ("exceeded file size limit"),          /* 36 SIGXFSZ   */
3615     DEFER_GETTEXT ("virtual time alarm"),                /* 37 SIGVTALRM */
3616     DEFER_GETTEXT ("profiling time alarm"),              /* 38 SIGPROF   */
3617     DEFER_GETTEXT ("undefined"),                         /* 39           */
3618     DEFER_GETTEXT ("file record locks revoked"),         /* 40 SIGLOST   */
3619     DEFER_GETTEXT ("undefined"),                         /* 41           */
3620     DEFER_GETTEXT ("undefined"),                         /* 42           */
3621     DEFER_GETTEXT ("undefined"),                         /* 43           */
3622     DEFER_GETTEXT ("undefined"),                         /* 44           */
3623     DEFER_GETTEXT ("undefined"),                         /* 45           */
3624     DEFER_GETTEXT ("undefined"),                         /* 46           */
3625     DEFER_GETTEXT ("undefined"),                         /* 47           */
3626     DEFER_GETTEXT ("undefined"),                         /* 48           */
3627     DEFER_GETTEXT ("undefined"),                         /* 49           */
3628     DEFER_GETTEXT ("undefined"),                         /* 50           */
3629     DEFER_GETTEXT ("undefined"),                         /* 51           */
3630     DEFER_GETTEXT ("undefined"),                         /* 52           */
3631     DEFER_GETTEXT ("undefined"),                         /* 53           */
3632     DEFER_GETTEXT ("undefined"),                         /* 54           */
3633     DEFER_GETTEXT ("undefined"),                         /* 55           */
3634     DEFER_GETTEXT ("undefined"),                         /* 56           */
3635     DEFER_GETTEXT ("undefined"),                         /* 57           */
3636     DEFER_GETTEXT ("undefined"),                         /* 58           */
3637     DEFER_GETTEXT ("undefined"),                         /* 59           */
3638     DEFER_GETTEXT ("undefined"),                         /* 60           */
3639     DEFER_GETTEXT ("undefined"),                         /* 61           */
3640     DEFER_GETTEXT ("undefined"),                         /* 62           */
3641     DEFER_GETTEXT ("undefined"),                         /* 63           */
3642     DEFER_GETTEXT ("notification message in mess. queue"), /* 64 SIGDGNOTIFY */
3643     0
3644   };
3645 #endif /* DGUX */
3646
3647 #endif /* ! SYS_SIGLIST_DECLARED && ! HAVE_SYS_SIGLIST */
3648
3649 \f
3650 /************************************************************************/
3651 /*         Directory routines for systems that don't have them          */
3652 /************************************************************************/
3653
3654 #ifdef SYSV_SYSTEM_DIR
3655
3656 #include <dirent.h>
3657
3658 #if defined(BROKEN_CLOSEDIR) || !defined(HAVE_CLOSEDIR)
3659 int
3660 closedir (DIR *dirp)  /* stream from opendir */
3661 {
3662   int rtnval;
3663
3664   rtnval = sys_close (dirp->dd_fd);
3665
3666   /* Some systems (like Solaris) allocate the buffer and the DIR all
3667      in one block.  Why in the world are we freeing this ourselves
3668      anyway?  */
3669 #if ! (defined (sun) && defined (USG5_4))
3670   xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
3671 #endif
3672   xfree ((char *) dirp);
3673   return (rtnval);
3674 }
3675 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3676 #endif /* SYSV_SYSTEM_DIR */
3677
3678 #ifdef NONSYSTEM_DIR_LIBRARY
3679
3680 DIR *
3681 opendir (CONST char *filename)  /* name of directory */
3682 {
3683   DIR *dirp;            /* -> malloc'ed storage */
3684   int fd;               /* file descriptor for read */
3685   struct stat sbuf;             /* result of fstat */
3686
3687   fd = sys_open (filename, O_RDONLY);
3688   if (fd < 0)
3689     return 0;
3690
3691   if (fstat (fd, &sbuf) < 0
3692       || (sbuf.st_mode & S_IFMT) != S_IFDIR
3693       || (dirp = (DIR *) malloc (sizeof (DIR))) == 0)
3694     {
3695       sys_close (fd);
3696       return 0;         /* bad luck today */
3697     }
3698
3699   dirp->dd_fd = fd;
3700   dirp->dd_loc = dirp->dd_size = 0;     /* refill needed */
3701
3702   return dirp;
3703 }
3704
3705 void
3706 closedir (DIR *dirp)            /* stream from opendir */
3707 {
3708   sys_close (dirp->dd_fd);
3709   xfree (dirp);
3710 }
3711
3712
3713 #define DIRSIZ  14
3714 struct olddir
3715   {
3716     ino_t od_ino;               /* inode */
3717     char od_name[DIRSIZ];       /* filename */
3718   };
3719
3720 static struct direct dir_static; /* simulated directory contents */
3721
3722 /* ARGUSED */
3723 struct direct *
3724 readdir (DIR *dirp)     /* stream from opendir */
3725 {
3726   struct olddir *dp;    /* -> directory data */
3727
3728   for (; ;)
3729     {
3730       if (dirp->dd_loc >= dirp->dd_size)
3731         dirp->dd_loc = dirp->dd_size = 0;
3732
3733       if (dirp->dd_size == 0    /* refill buffer */
3734           && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3735         return 0;
3736
3737       dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
3738       dirp->dd_loc += sizeof (struct olddir);
3739
3740       if (dp->od_ino != 0)      /* not deleted entry */
3741         {
3742           dir_static.d_ino = dp->od_ino;
3743           strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
3744           dir_static.d_name[DIRSIZ] = '\0';
3745           dir_static.d_namlen = strlen (dir_static.d_name);
3746           dir_static.d_reclen = sizeof (struct direct)
3747             - MAXNAMLEN + 3
3748               + dir_static.d_namlen - dir_static.d_namlen % 4;
3749           return &dir_static;   /* -> simulated structure */
3750         }
3751     }
3752 }
3753
3754
3755 #endif /* NONSYSTEM_DIR_LIBRARY */
3756
3757 \f
3758 /* mkdir and rmdir functions, for systems which don't have them.  */
3759
3760 #ifndef HAVE_MKDIR
3761 /*
3762  * Written by Robert Rother, Mariah Corporation, August 1985.
3763  *
3764  * If you want it, it's yours.  All I ask in return is that if you
3765  * figure out how to do this in a Bourne Shell script you send me
3766  * a copy.
3767  *                                      sdcsvax!rmr or rmr@uscd
3768  *
3769  * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3770  * subroutine.  11Mar86; hoptoad!gnu
3771  *
3772  * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3773  * subroutine didn't return EEXIST.  It does now.
3774  */
3775
3776 /*
3777  * Make a directory.
3778  */
3779 #ifdef MKDIR_PROTOTYPE
3780 MKDIR_PROTOTYPE
3781 #else
3782 int
3783 mkdir (CONST char *dpath, int dmode)
3784 #endif
3785 {
3786   int cpid, status, fd;
3787   struct stat statbuf;
3788
3789   if (stat (dpath, &statbuf) == 0)
3790     {
3791       errno = EEXIST;           /* Stat worked, so it already exists */
3792       return -1;
3793     }
3794
3795   /* If stat fails for a reason other than non-existence, return error */
3796   if (errno != ENOENT)
3797     return -1;
3798
3799   synch_process_alive = 1;
3800   switch (cpid = fork ())
3801     {
3802
3803     case -1:                    /* Error in fork() */
3804       return -1;                /* Errno is set already */
3805
3806     case 0:                     /* Child process */
3807     {
3808       /*
3809        * Cheap hack to set mode of new directory.  Since this
3810        * child process is going away anyway, we zap its umask.
3811        * ####, this won't suffice to set SUID, SGID, etc. on this
3812        * directory.  Does anybody care?
3813        */
3814       status = umask (0);       /* Get current umask */
3815       status = umask (status | (0777 & ~dmode));        /* Set for mkdir */
3816       fd = sys_open ("/dev/null", O_RDWR);
3817       if (fd >= 0)
3818         {
3819           if (fd != STDIN_FILENO)  dup2 (fd, STDIN_FILENO);
3820           if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
3821           if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);
3822         }
3823       execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
3824       _exit (-1);               /* Can't exec /bin/mkdir */
3825     }
3826
3827     default:                    /* Parent process */
3828       wait_for_termination (cpid);
3829     }
3830
3831   if (synch_process_death != 0 || synch_process_retcode != 0)
3832     {
3833       errno = EIO;              /* We don't know why, but */
3834       return -1;                /* /bin/mkdir failed */
3835     }
3836
3837   return 0;
3838 }
3839 #endif /* not HAVE_MKDIR */
3840
3841 #ifndef HAVE_RMDIR
3842 int
3843 rmdir (CONST char *dpath)
3844 {
3845   int cpid, status, fd;
3846   struct stat statbuf;
3847
3848   if (stat (dpath, &statbuf) != 0)
3849     {
3850       /* Stat just set errno.  We don't have to */
3851       return -1;
3852     }
3853
3854   synch_process_alive = 1;
3855   switch (cpid = fork ())
3856     {
3857
3858     case -1:                    /* Error in fork() */
3859       return (-1);              /* Errno is set already */
3860
3861     case 0:                     /* Child process */
3862       fd = sys_open("/dev/null", O_RDWR);
3863       if (fd >= 0)
3864         {
3865           if (fd != STDIN_FILENO)  dup2 (fd, STDIN_FILENO);
3866           if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
3867           if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);
3868         }
3869       execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
3870       _exit (-1);               /* Can't exec /bin/mkdir */
3871
3872     default:                    /* Parent process */
3873       wait_for_termination (cpid);
3874     }
3875
3876   if (synch_process_death   != 0 ||
3877       synch_process_retcode != 0)
3878     {
3879       errno = EIO;              /* We don't know why, but */
3880       return -1;                /* /bin/rmdir failed */
3881     }
3882
3883   return 0;
3884 }
3885 #endif /* !HAVE_RMDIR */
3886
3887 \f
3888 /************************************************************************/
3889 /*                            Misc. SunOS crap                          */
3890 /************************************************************************/
3891
3892 #ifdef USE_DL_STUBS
3893
3894 /* These are included on Sunos 4.1 when we do not use shared libraries.
3895    X11 libraries may refer to these functions but (we hope) do not
3896    actually call them.  */
3897
3898 void *
3899 dlopen (void)
3900 {
3901   return 0;
3902 }
3903
3904 void *
3905 dlsym (void)
3906 {
3907   return 0;
3908 }
3909
3910 int
3911 dlclose (void)
3912 {
3913   return -1;
3914 }
3915
3916 #endif /* USE_DL_STUBS */
3917
3918 \f
3919
3920 #ifndef HAVE_STRCASECMP
3921 /*
3922  * From BSD
3923  */
3924 static unsigned char charmap[] = {
3925         '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
3926         '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
3927         '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
3928         '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
3929         '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
3930         '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
3931         '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
3932         '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
3933         '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
3934         '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
3935         '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
3936         '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
3937         '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
3938         '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
3939         '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
3940         '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
3941         '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
3942         '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
3943         '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
3944         '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
3945         '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
3946         '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
3947         '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
3948         '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
3949         '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
3950         '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
3951         '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
3952         '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
3953         '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
3954         '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
3955         '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
3956         '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
3957 };
3958
3959 int
3960 strcasecmp (char *s1, char *s2)
3961 {
3962   unsigned char *cm = charmap;
3963   unsigned char *us1 = (unsigned char *) s1;
3964   unsigned char *us2 = (unsigned char *)s2;
3965
3966   while (cm[*us1] == cm[*us2++])
3967     if (*us1++ == '\0')
3968       return (0);
3969
3970   return (cm[*us1] - cm[*--us2]);
3971 }
3972 #endif /* !HAVE_STRCASECMP */