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