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