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