comparison src/sysdep.c @ 428:3ecd8885ac67 r21-2-22

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