Don't compile sys_select on systems that don't need it.
[emacs.git] / src / sysdep.c
blobcc5ef0c5511222458b3abfc5a653a378a1a3d8e2
1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 86,87,88,93,94,95,1999,2000,01,2003
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; 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. */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include <signal.h>
27 #include <setjmp.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #include "lisp.h"
32 /* Including stdlib.h isn't necessarily enough to get srandom
33 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
34 #ifdef HAVE_RANDOM
35 #if 0 /* It turns out that defining _OSF_SOURCE in osf5-0.h gets
36 random prototyped as returning `int'. It looks to me as
37 though the best way to DTRT is to prefer the rand48 functions
38 (per libc.info). -- fx */
39 extern long int random P_ ((void));
40 #endif
41 #if 0 /* Don't prototype srandom; it takes an unsigned argument on
42 some systems, and an unsigned long on others, like FreeBSD
43 4.1. */
44 extern void srandom P_ ((unsigned int));
45 #endif
46 #endif
48 #include "blockinput.h"
49 #undef NULL
51 #ifdef MAC_OS8
52 /* It is essential to include stdlib.h so that this file picks up
53 the correct definitions of rand, srand, and RAND_MAX.
54 Otherwise random numbers will not work correctly. */
55 #include <stdlib.h>
57 #ifndef subprocesses
58 /* Nonzero means delete a process right away if it exits (process.c). */
59 static int delete_exited_processes;
60 #endif
61 #endif /* MAC_OS8 */
63 #ifdef WINDOWSNT
64 #define read sys_read
65 #define write sys_write
66 #include <windows.h>
67 #ifndef NULL
68 #define NULL 0
69 #endif
70 #endif /* not WINDOWSNT */
72 #ifdef HAVE_CARBON
73 #define read sys_read
74 #endif
76 /* Does anyone other than VMS need this? */
77 #ifndef fwrite
78 #define sys_fwrite fwrite
79 #else
80 #undef fwrite
81 #endif
83 #include <stdio.h>
84 #include <sys/types.h>
85 #include <sys/stat.h>
86 #include <errno.h>
88 #ifdef HAVE_SETPGID
89 #if !defined (USG) || defined (BSD_PGRPS)
90 #undef setpgrp
91 #define setpgrp setpgid
92 #endif
93 #endif
95 /* Get SI_SRPC_DOMAIN, if it is available. */
96 #ifdef HAVE_SYS_SYSTEMINFO_H
97 #include <sys/systeminfo.h>
98 #endif
100 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
101 #include <dos.h>
102 #include "dosfns.h"
103 #include "msdos.h"
104 #include <sys/param.h>
106 #if __DJGPP__ > 1
107 extern int etext;
108 extern unsigned start __asm__ ("start");
109 #endif
110 #endif
112 #ifndef USE_CRT_DLL
113 #ifndef errno
114 extern int errno;
115 #endif
116 #endif
118 #ifdef VMS
119 #include <rms.h>
120 #include <ttdef.h>
121 #include <tt2def.h>
122 #include <iodef.h>
123 #include <ssdef.h>
124 #include <descrip.h>
125 #include <fibdef.h>
126 #include <atrdef.h>
127 #include <ctype.h>
128 #include <string.h>
129 #ifdef __GNUC__
130 #include <sys/file.h>
131 #else
132 #include <file.h>
133 #endif
134 #undef F_SETFL
135 #ifndef RAB$C_BID
136 #include <rab.h>
137 #endif
138 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
139 #endif /* VMS */
141 #ifndef VMS
142 #include <sys/file.h>
143 #endif /* not VMS */
145 #ifdef HAVE_FCNTL_H
146 #include <fcntl.h>
147 #endif
149 #ifndef MSDOS
150 #include <sys/ioctl.h>
151 #endif
153 #include "systty.h"
154 #include "syswait.h"
156 #ifdef BROKEN_TIOCGWINSZ
157 #undef TIOCGWINSZ
158 #undef TIOCSWINSZ
159 #endif
161 #if defined (USG) || defined (DGUX)
162 #include <sys/utsname.h>
163 #ifndef MEMORY_IN_STRING_H
164 #include <memory.h>
165 #endif
166 #if defined (TIOCGWINSZ) || defined (ISC4_0)
167 #ifdef NEED_SIOCTL
168 #include <sys/sioctl.h>
169 #endif
170 #ifdef NEED_PTEM_H
171 #include <sys/stream.h>
172 #include <sys/ptem.h>
173 #endif
174 #endif /* TIOCGWINSZ or ISC4_0 */
175 #endif /* USG or DGUX */
177 extern int quit_char;
179 #include "keyboard.h"
180 #include "frame.h"
181 #include "window.h"
182 #include "termhooks.h"
183 #include "termchar.h"
184 #include "termopts.h"
185 #include "dispextern.h"
186 #include "process.h"
187 #include "cm.h" /* for reset_sys_modes */
189 #ifdef WINDOWSNT
190 #include <direct.h>
191 /* In process.h which conflicts with the local copy. */
192 #define _P_WAIT 0
193 int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
194 int _CRTAPI1 _getpid (void);
195 #endif
197 #ifdef NONSYSTEM_DIR_LIBRARY
198 #include "ndir.h"
199 #endif /* NONSYSTEM_DIR_LIBRARY */
201 #include "syssignal.h"
202 #include "systime.h"
203 #ifdef HAVE_UTIME_H
204 #include <utime.h>
205 #endif
207 #ifndef HAVE_UTIMES
208 #ifndef HAVE_STRUCT_UTIMBUF
209 /* We want to use utime rather than utimes, but we couldn't find the
210 structure declaration. We'll use the traditional one. */
211 struct utimbuf {
212 long actime;
213 long modtime;
215 #endif
216 #endif
218 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
219 #ifndef LPASS8
220 #define LPASS8 0
221 #endif
223 #ifdef BSD4_1
224 #define LNOFLSH 0100000
225 #endif
227 static int baud_convert[] =
228 #ifdef BAUD_CONVERT
229 BAUD_CONVERT;
230 #else
232 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
233 1800, 2400, 4800, 9600, 19200, 38400
235 #endif
237 #ifdef HAVE_SPEED_T
238 #include <termios.h>
239 #else
240 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
241 #else
242 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
243 #include <termios.h>
244 #endif
245 #endif
246 #endif
248 int emacs_ospeed;
250 void croak P_ ((char *));
252 #ifdef AIXHFT
253 void hft_init P_ ((struct tty_output *));
254 void hft_reset P_ ((struct tty_output *));
255 #endif
257 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
259 SIGMASKTYPE sigprocmask_set;
262 /* Discard pending input on all input descriptors. */
264 void
265 discard_tty_input ()
267 #ifndef WINDOWSNT
268 struct emacs_tty buf;
270 if (noninteractive)
271 return;
273 /* Discarding input is not safe when the input could contain
274 replies from the X server. So don't do it. */
275 if (read_socket_hook)
276 return;
278 #ifdef VMS
279 end_kbd_input ();
280 SYS$QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
281 &buf.main, 0, 0, terminator_mask, 0, 0);
282 queue_kbd_input ();
283 #else /* not VMS */
284 #ifdef APOLLO
286 struct tty_output *tty;
287 for (tty = tty_list; tty; tty = tty->next)
289 int zero = 0;
290 ioctl (fileno (TTY_INPUT (tty)), TIOCFLUSH, &zero);
293 #else /* not Apollo */
294 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
295 while (dos_keyread () != -1)
297 #else /* not MSDOS */
299 struct tty_output *tty;
300 for (tty = tty_list; tty; tty = tty->next)
302 EMACS_GET_TTY (fileno (TTY_INPUT (tty)), &buf);
303 EMACS_SET_TTY (fileno (TTY_INPUT (tty)), &buf, 0);
306 #endif /* not MSDOS */
307 #endif /* not Apollo */
308 #endif /* not VMS */
309 #endif /* not WINDOWSNT */
312 #ifdef SIGTSTP
314 /* Arrange for character C to be read as the next input from
315 the terminal. */
317 void
318 stuff_char (char c)
320 if (read_socket_hook)
321 return;
323 /* Should perhaps error if in batch mode */
324 #ifdef TIOCSTI
325 ioctl (fileno (TTY_INPUT (CURTTY())), TIOCSTI, &c);
326 #else /* no TIOCSTI */
327 error ("Cannot stuff terminal input characters in this version of Unix");
328 #endif /* no TIOCSTI */
331 #endif /* SIGTSTP */
333 void
334 init_baud_rate (struct tty_output *tty)
336 if (noninteractive)
337 emacs_ospeed = 0;
338 else
340 #ifdef INIT_BAUD_RATE
341 INIT_BAUD_RATE ();
342 #else
343 #ifdef DOS_NT
344 emacs_ospeed = 15;
345 #else /* not DOS_NT */
346 #ifdef VMS
347 struct sensemode sg;
349 SYS$QIOW (0, fileno (TTY_INPUT (tty)), IO$_SENSEMODE, &sg, 0, 0,
350 &sg.class, 12, 0, 0, 0, 0 );
351 emacs_ospeed = sg.xmit_baud;
352 #else /* not VMS */
353 #ifdef HAVE_TERMIOS
354 struct termios sg;
356 sg.c_cflag = B9600;
357 tcgetattr (fileno (TTY_INPUT (tty)), &sg);
358 emacs_ospeed = cfgetospeed (&sg);
359 #if defined (USE_GETOBAUD) && defined (getobaud)
360 /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
361 if (emacs_ospeed == 0)
362 emacs_ospeed = getobaud (sg.c_cflag);
363 #endif
364 #else /* neither VMS nor TERMIOS */
365 #ifdef HAVE_TERMIO
366 struct termio sg;
368 sg.c_cflag = B9600;
369 #ifdef HAVE_TCATTR
370 tcgetattr (fileno (TTY_INPUT (tty)), &sg);
371 #else
372 ioctl (fileno (TTY_INPUT (tty)), TCGETA, &sg);
373 #endif
374 emacs_ospeed = sg.c_cflag & CBAUD;
375 #else /* neither VMS nor TERMIOS nor TERMIO */
376 struct sgttyb sg;
378 sg.sg_ospeed = B9600;
379 if (ioctl (fileno (TTY_INPUT (tty)), TIOCGETP, &sg) < 0)
380 abort ();
381 emacs_ospeed = sg.sg_ospeed;
382 #endif /* not HAVE_TERMIO */
383 #endif /* not HAVE_TERMIOS */
384 #endif /* not VMS */
385 #endif /* not DOS_NT */
386 #endif /* not INIT_BAUD_RATE */
389 baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
390 ? baud_convert[emacs_ospeed] : 9600);
391 if (baud_rate == 0)
392 baud_rate = 1200;
395 /*ARGSUSED*/
396 void
397 set_exclusive_use (fd)
398 int fd;
400 #ifdef FIOCLEX
401 ioctl (fd, FIOCLEX, 0);
402 #endif
403 /* Ok to do nothing if this feature does not exist */
406 #ifndef subprocesses
408 wait_without_blocking ()
410 #ifdef BSD_SYSTEM
411 wait3 (0, WNOHANG | WUNTRACED, 0);
412 #else
413 croak ("wait_without_blocking");
414 #endif
415 synch_process_alive = 0;
418 #endif /* not subprocesses */
420 int wait_debugging; /* Set nonzero to make following function work under dbx
421 (at least for bsd). */
423 SIGTYPE
424 wait_for_termination_signal ()
427 /* Wait for subprocess with process id `pid' to terminate and
428 make sure it will get eliminated (not remain forever as a zombie) */
430 void
431 wait_for_termination (pid)
432 int pid;
434 while (1)
436 #ifdef subprocesses
437 #ifdef VMS
438 int status;
440 status = SYS$FORCEX (&pid, 0, 0);
441 break;
442 #else /* not VMS */
443 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
444 /* Note that kill returns -1 even if the process is just a zombie now.
445 But inevitably a SIGCHLD interrupt should be generated
446 and child_sig will do wait3 and make the process go away. */
447 /* There is some indication that there is a bug involved with
448 termination of subprocesses, perhaps involving a kernel bug too,
449 but no idea what it is. Just as a hunch we signal SIGCHLD to see
450 if that causes the problem to go away or get worse. */
451 sigsetmask (sigmask (SIGCHLD));
452 if (0 > kill (pid, 0))
454 sigsetmask (SIGEMPTYMASK);
455 kill (getpid (), SIGCHLD);
456 break;
458 if (wait_debugging)
459 sleep (1);
460 else
461 sigpause (SIGEMPTYMASK);
462 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
463 #if defined (UNIPLUS)
464 if (0 > kill (pid, 0))
465 break;
466 wait (0);
467 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
468 #ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */
469 sigblock (sigmask (SIGCHLD));
470 errno = 0;
471 if (kill (pid, 0) == -1 && errno == ESRCH)
473 sigunblock (sigmask (SIGCHLD));
474 break;
477 sigsuspend (&empty_mask);
478 #else /* not POSIX_SIGNALS */
479 #ifdef HAVE_SYSV_SIGPAUSE
480 sighold (SIGCHLD);
481 if (0 > kill (pid, 0))
483 sigrelse (SIGCHLD);
484 break;
486 sigpause (SIGCHLD);
487 #else /* not HAVE_SYSV_SIGPAUSE */
488 #ifdef WINDOWSNT
489 wait (0);
490 break;
491 #else /* not WINDOWSNT */
492 if (0 > kill (pid, 0))
493 break;
494 /* Using sleep instead of pause avoids timing error.
495 If the inferior dies just before the sleep,
496 we lose just one second. */
497 sleep (1);
498 #endif /* not WINDOWSNT */
499 #endif /* not HAVE_SYSV_SIGPAUSE */
500 #endif /* not POSIX_SIGNALS */
501 #endif /* not UNIPLUS */
502 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
503 #endif /* not VMS */
504 #else /* not subprocesses */
505 #if __DJGPP__ > 1
506 break;
507 #else /* not __DJGPP__ > 1 */
508 #ifndef BSD4_1
509 if (kill (pid, 0) < 0)
510 break;
511 wait (0);
512 #else /* BSD4_1 */
513 int status;
514 status = wait (0);
515 if (status == pid || status == -1)
516 break;
517 #endif /* BSD4_1 */
518 #endif /* not __DJGPP__ > 1*/
519 #endif /* not subprocesses */
523 #ifdef subprocesses
526 * flush any pending output
527 * (may flush input as well; it does not matter the way we use it)
530 void
531 flush_pending_output (channel)
532 int channel;
534 #ifdef HAVE_TERMIOS
535 /* If we try this, we get hit with SIGTTIN, because
536 the child's tty belongs to the child's pgrp. */
537 #else
538 #ifdef TCFLSH
539 ioctl (channel, TCFLSH, 1);
540 #else
541 #ifdef TIOCFLUSH
542 int zero = 0;
543 /* 3rd arg should be ignored
544 but some 4.2 kernels actually want the address of an int
545 and nonzero means something different. */
546 ioctl (channel, TIOCFLUSH, &zero);
547 #endif
548 #endif
549 #endif
552 #ifndef VMS
553 /* Set up the terminal at the other end of a pseudo-terminal that
554 we will be controlling an inferior through.
555 It should not echo or do line-editing, since that is done
556 in Emacs. No padding needed for insertion into an Emacs buffer. */
558 void
559 child_setup_tty (out)
560 int out;
562 #ifndef DOS_NT
563 struct emacs_tty s;
565 EMACS_GET_TTY (out, &s);
567 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
568 s.main.c_oflag |= OPOST; /* Enable output postprocessing */
569 s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */
570 #ifdef NLDLY
571 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
572 /* No output delays */
573 #endif
574 s.main.c_lflag &= ~ECHO; /* Disable echo */
575 s.main.c_lflag |= ISIG; /* Enable signals */
576 #if 0 /* This causes bugs in (for instance) telnet to certain sites. */
577 s.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
578 #ifdef INLCR /* Just being cautious, since I can't check how
579 widespread INLCR is--rms. */
580 s.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
581 #endif
582 #endif
583 #ifdef IUCLC
584 s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */
585 #endif
586 #ifdef ISTRIP
587 s.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
588 #endif
589 #ifdef OLCUC
590 s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */
591 #endif
592 s.main.c_oflag &= ~TAB3; /* Disable tab expansion */
593 s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
594 #if 0
595 /* Said to be unnecessary: */
596 s.main.c_cc[VMIN] = 1; /* minimum number of characters to accept */
597 s.main.c_cc[VTIME] = 0; /* wait forever for at least 1 character */
598 #endif
600 s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */
601 s.main.c_cc[VEOF] = 04; /* insure that EOF is Control-D */
602 s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
603 s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
605 #ifdef HPUX
606 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
607 #endif /* HPUX */
609 #ifdef AIX
610 /* AIX enhanced edit loses NULs, so disable it */
611 #ifndef IBMR2AIX
612 s.main.c_line = 0;
613 s.main.c_iflag &= ~ASCEDIT;
614 #endif
615 /* Also, PTY overloads NUL and BREAK.
616 don't ignore break, but don't signal either, so it looks like NUL. */
617 s.main.c_iflag &= ~IGNBRK;
618 s.main.c_iflag &= ~BRKINT;
619 /* QUIT and INTR work better as signals, so disable character forms */
620 s.main.c_cc[VINTR] = 0377;
621 #ifdef SIGNALS_VIA_CHARACTERS
622 /* the QUIT and INTR character are used in process_send_signal
623 so set them here to something useful. */
624 if (s.main.c_cc[VQUIT] == 0377)
625 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
626 if (s.main.c_cc[VINTR] == 0377)
627 s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
628 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
629 /* QUIT and INTR work better as signals, so disable character forms */
630 s.main.c_cc[VQUIT] = 0377;
631 s.main.c_cc[VINTR] = 0377;
632 s.main.c_lflag &= ~ISIG;
633 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
634 s.main.c_cc[VEOL] = 0377;
635 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
636 #endif /* AIX */
638 #else /* not HAVE_TERMIO */
640 s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
641 | CBREAK | TANDEM);
642 s.main.sg_flags |= LPASS8;
643 s.main.sg_erase = 0377;
644 s.main.sg_kill = 0377;
645 s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */
647 #endif /* not HAVE_TERMIO */
649 EMACS_SET_TTY (out, &s, 0);
651 #ifdef BSD4_1
652 if (interrupt_input)
653 reset_sigio (0);
654 #endif /* BSD4_1 */
655 #ifdef RTU
657 int zero = 0;
658 ioctl (out, FIOASYNC, &zero);
660 #endif /* RTU */
661 #endif /* not DOS_NT */
663 #endif /* not VMS */
665 #endif /* subprocesses */
667 /* Record a signal code and the handler for it. */
668 struct save_signal
670 int code;
671 SIGTYPE (*handler) P_ ((int));
674 static void save_signal_handlers P_ ((struct save_signal *));
675 static void restore_signal_handlers P_ ((struct save_signal *));
677 /* Suspend the Emacs process; give terminal to its superior. */
679 void
680 sys_suspend ()
682 #ifdef VMS
683 /* "Foster" parentage allows emacs to return to a subprocess that attached
684 to the current emacs as a cheaper than starting a whole new process. This
685 is set up by KEPTEDITOR.COM. */
686 unsigned long parent_id, foster_parent_id;
687 char *fpid_string;
689 fpid_string = getenv ("EMACS_PARENT_PID");
690 if (fpid_string != NULL)
692 sscanf (fpid_string, "%x", &foster_parent_id);
693 if (foster_parent_id != 0)
694 parent_id = foster_parent_id;
695 else
696 parent_id = getppid ();
698 else
699 parent_id = getppid ();
701 xfree (fpid_string); /* On VMS, this was malloc'd */
703 if (parent_id && parent_id != 0xffffffff)
705 SIGTYPE (*oldsig)() = (int) signal (SIGINT, SIG_IGN);
706 int status = LIB$ATTACH (&parent_id) & 1;
707 signal (SIGINT, oldsig);
708 return status;
710 else
712 struct {
713 int l;
714 char *a;
715 } d_prompt;
716 d_prompt.l = sizeof ("Emacs: "); /* Our special prompt */
717 d_prompt.a = "Emacs: "; /* Just a reminder */
718 LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0);
719 return 1;
721 return -1;
722 #else
723 #if defined (SIGTSTP) && !defined (MSDOS)
726 int pgrp = EMACS_GETPGRP (0);
727 EMACS_KILLPG (pgrp, SIGTSTP);
730 #else /* No SIGTSTP */
731 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
732 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
733 kill (getpid (), SIGQUIT);
735 #else /* No SIGTSTP or USG_JOBCTRL */
737 /* On a system where suspending is not implemented,
738 instead fork a subshell and let it talk directly to the terminal
739 while we wait. */
740 sys_subshell ();
742 #endif /* no USG_JOBCTRL */
743 #endif /* no SIGTSTP */
744 #endif /* not VMS */
747 /* Fork a subshell. */
749 #ifndef MAC_OS8
750 void
751 sys_subshell ()
753 #ifndef VMS
754 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
755 int st;
756 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
757 #endif
758 int pid;
759 struct save_signal saved_handlers[5];
760 Lisp_Object dir;
761 unsigned char *str = 0;
762 int len;
764 saved_handlers[0].code = SIGINT;
765 saved_handlers[1].code = SIGQUIT;
766 saved_handlers[2].code = SIGTERM;
767 #ifdef SIGIO
768 saved_handlers[3].code = SIGIO;
769 saved_handlers[4].code = 0;
770 #else
771 saved_handlers[3].code = 0;
772 #endif
774 /* Mentioning current_buffer->buffer would mean including buffer.h,
775 which somehow wedges the hp compiler. So instead... */
777 dir = intern ("default-directory");
778 if (NILP (Fboundp (dir)))
779 goto xyzzy;
780 dir = Fsymbol_value (dir);
781 if (!STRINGP (dir))
782 goto xyzzy;
784 dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
785 str = (unsigned char *) alloca (SCHARS (dir) + 2);
786 len = SCHARS (dir);
787 bcopy (SDATA (dir), str, len);
788 if (str[len - 1] != '/') str[len++] = '/';
789 str[len] = 0;
790 xyzzy:
792 #ifdef DOS_NT
793 pid = 0;
794 #if __DJGPP__ > 1
795 save_signal_handlers (saved_handlers);
796 synch_process_alive = 1;
797 #endif /* __DJGPP__ > 1 */
798 #else
799 pid = vfork ();
800 if (pid == -1)
801 error ("Can't spawn subshell");
802 #endif
804 if (pid == 0)
806 char *sh = 0;
808 #ifdef DOS_NT /* MW, Aug 1993 */
809 getwd (oldwd);
810 if (sh == 0)
811 sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
812 #endif
813 if (sh == 0)
814 sh = (char *) egetenv ("SHELL");
815 if (sh == 0)
816 sh = "sh";
818 /* Use our buffer's default directory for the subshell. */
819 if (str)
820 chdir ((char *) str);
822 #ifdef subprocesses
823 close_process_descs (); /* Close Emacs's pipes/ptys */
824 #endif
826 #ifdef SET_EMACS_PRIORITY
828 extern EMACS_INT emacs_priority;
830 if (emacs_priority < 0)
831 nice (-emacs_priority);
833 #endif
835 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
837 char *epwd = getenv ("PWD");
838 char old_pwd[MAXPATHLEN+1+4];
840 /* If PWD is set, pass it with corrected value. */
841 if (epwd)
843 strcpy (old_pwd, epwd);
844 if (str[len - 1] == '/')
845 str[len - 1] = '\0';
846 setenv ("PWD", str, 1);
848 st = system (sh);
849 chdir (oldwd);
850 if (epwd)
851 putenv (old_pwd); /* restore previous value */
853 #if 0 /* This is also reported if last command executed in subshell failed, KFS */
854 if (st)
855 report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
856 #endif
857 #else /* not MSDOS */
858 #ifdef WINDOWSNT
859 /* Waits for process completion */
860 pid = _spawnlp (_P_WAIT, sh, sh, NULL);
861 chdir (oldwd);
862 if (pid == -1)
863 write (1, "Can't execute subshell", 22);
864 #else /* not WINDOWSNT */
865 execlp (sh, sh, 0);
866 write (1, "Can't execute subshell", 22);
867 _exit (1);
868 #endif /* not WINDOWSNT */
869 #endif /* not MSDOS */
872 /* Do this now if we did not do it before. */
873 #if !defined (MSDOS) || __DJGPP__ == 1
874 save_signal_handlers (saved_handlers);
875 synch_process_alive = 1;
876 #endif
878 #ifndef DOS_NT
879 wait_for_termination (pid);
880 #endif
881 restore_signal_handlers (saved_handlers);
882 synch_process_alive = 0;
883 #endif /* !VMS */
885 #endif /* !MAC_OS8 */
887 static void
888 save_signal_handlers (saved_handlers)
889 struct save_signal *saved_handlers;
891 while (saved_handlers->code)
893 saved_handlers->handler
894 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
895 saved_handlers++;
899 static void
900 restore_signal_handlers (saved_handlers)
901 struct save_signal *saved_handlers;
903 while (saved_handlers->code)
905 signal (saved_handlers->code, saved_handlers->handler);
906 saved_handlers++;
910 #ifdef F_SETFL
912 int old_fcntl_flags;
914 void
915 init_sigio (fd)
916 int fd;
918 #ifdef FASYNC
919 /* XXX What if we get called with more than one fds? */
920 old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
921 fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
922 #endif
923 interrupts_deferred = 0;
926 void
927 reset_sigio (fd)
928 int fd;
930 fcntl (fd, F_SETFL, old_fcntl_flags);
933 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
935 void
936 request_sigio ()
938 if (read_socket_hook)
939 return;
941 #ifdef SIGWINCH
942 sigunblock (sigmask (SIGWINCH));
943 #endif
944 sigunblock (sigmask (SIGIO));
946 interrupts_deferred = 0;
949 void
950 unrequest_sigio (void)
952 if (read_socket_hook)
953 return;
955 #ifdef SIGWINCH
956 sigblock (sigmask (SIGWINCH));
957 #endif
958 sigblock (sigmask (SIGIO));
959 interrupts_deferred = 1;
962 #else /* no FASYNC */
963 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
965 void
966 request_sigio ()
968 int on = 1;
970 if (read_socket_hook)
971 return;
973 /* XXX CURTTY() is bogus here. */
974 ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &on);
975 interrupts_deferred = 0;
978 void
979 unrequest_sigio (struct tty_output *tty)
981 int off = 0;
983 if (read_socket_hook)
984 return;
986 /* XXX CURTTY() is bogus here. */
987 ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC, &off);
988 interrupts_deferred = 1;
991 #else /* not FASYNC, not STRIDE */
993 #ifdef _CX_UX
995 #include <termios.h>
997 void
998 request_sigio ()
1000 int on = 1;
1001 sigset_t st;
1003 if (read_socket_hook)
1004 return;
1006 sigemptyset (&st);
1007 sigaddset (&st, SIGIO);
1008 ioctl (0, FIOASYNC, &on); /* XXX This fails for multiple ttys. */
1009 interrupts_deferred = 0;
1010 sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
1013 void
1014 unrequest_sigio ()
1016 int off = 0;
1018 if (read_socket_hook)
1019 return;
1021 ioctl (0, FIOASYNC, &off); /* XXX This fails for multiple ttys. */
1022 interrupts_deferred = 1;
1025 #else /* ! _CX_UX */
1026 #ifndef MSDOS
1028 void
1029 request_sigio ()
1031 if (read_socket_hook)
1032 return;
1034 croak ("request_sigio");
1037 void
1038 unrequest_sigio ()
1040 if (read_socket_hook)
1041 return;
1043 croak ("unrequest_sigio");
1046 #endif /* MSDOS */
1047 #endif /* _CX_UX */
1048 #endif /* STRIDE */
1049 #endif /* FASYNC */
1050 #endif /* F_SETFL */
1052 /* Saving and restoring the process group of Emacs's terminal. */
1054 #ifdef BSD_PGRPS
1056 /* The process group of which Emacs was a member when it initially
1057 started.
1059 If Emacs was in its own process group (i.e. inherited_pgroup ==
1060 getpid ()), then we know we're running under a shell with job
1061 control (Emacs would never be run as part of a pipeline).
1062 Everything is fine.
1064 If Emacs was not in its own process group, then we know we're
1065 running under a shell (or a caller) that doesn't know how to
1066 separate itself from Emacs (like sh). Emacs must be in its own
1067 process group in order to receive SIGIO correctly. In this
1068 situation, we put ourselves in our own pgroup, forcibly set the
1069 tty's pgroup to our pgroup, and make sure to restore and reinstate
1070 the tty's pgroup just like any other terminal setting. If
1071 inherited_group was not the tty's pgroup, then we'll get a
1072 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1073 it goes foreground in the future, which is what should happen. */
1074 int inherited_pgroup;
1076 /* Split off the foreground process group to Emacs alone.
1077 When we are in the foreground, but not started in our own process
1078 group, redirect the TTY to point to our own process group. We need
1079 to be in our own process group to receive SIGIO properly. */
1080 void
1081 narrow_foreground_group (struct tty_output *tty)
1083 int me = getpid ();
1085 setpgrp (0, inherited_pgroup);
1086 /* XXX This only works on the controlling tty. */
1087 if (inherited_pgroup != me)
1088 EMACS_SET_TTY_PGRP (fileno (TTY_INPUT (tty)), &me);
1089 setpgrp (0, me);
1092 /* Set the tty to our original foreground group. */
1093 void
1094 widen_foreground_group (struct tty_output *tty)
1096 if (inherited_pgroup != getpid ())
1097 EMACS_SET_TTY_PGRP (fileno (TTY_INPUT (tty)), &inherited_pgroup);
1098 setpgrp (0, inherited_pgroup);
1101 #endif /* BSD_PGRPS */
1103 /* Getting and setting emacs_tty structures. */
1105 /* Set *TC to the parameters associated with the terminal FD.
1106 Return zero if all's well, or -1 if we ran into an error we
1107 couldn't deal with. */
1109 emacs_get_tty (fd, settings)
1110 int fd;
1111 struct emacs_tty *settings;
1113 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1114 #ifdef HAVE_TCATTR
1115 /* We have those nifty POSIX tcmumbleattr functions. */
1116 bzero (&settings->main, sizeof (settings->main));
1117 if (tcgetattr (fd, &settings->main) < 0)
1118 return -1;
1120 #else
1121 #ifdef HAVE_TERMIO
1122 /* The SYSV-style interface? */
1123 if (ioctl (fd, TCGETA, &settings->main) < 0)
1124 return -1;
1126 #else
1127 #ifdef VMS
1128 /* Vehemently Monstrous System? :-) */
1129 if (! (SYS$QIOW (0, fd, IO$_SENSEMODE, settings, 0, 0,
1130 &settings->main.class, 12, 0, 0, 0, 0)
1131 & 1))
1132 return -1;
1134 #else
1135 #ifndef DOS_NT
1136 /* I give up - I hope you have the BSD ioctls. */
1137 if (ioctl (fd, TIOCGETP, &settings->main) < 0)
1138 return -1;
1139 #endif /* not DOS_NT */
1140 #endif
1141 #endif
1142 #endif
1144 /* Suivant - Do we have to get struct ltchars data? */
1145 #ifdef HAVE_LTCHARS
1146 if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
1147 return -1;
1148 #endif
1150 /* How about a struct tchars and a wordful of lmode bits? */
1151 #ifdef HAVE_TCHARS
1152 if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
1153 || ioctl (fd, TIOCLGET, &settings->lmode) < 0)
1154 return -1;
1155 #endif
1157 /* We have survived the tempest. */
1158 return 0;
1162 /* Set the parameters of the tty on FD according to the contents of
1163 *SETTINGS. If FLUSHP is non-zero, we discard input.
1164 Return 0 if all went well, and -1 if anything failed. */
1167 emacs_set_tty (fd, settings, flushp)
1168 int fd;
1169 struct emacs_tty *settings;
1170 int flushp;
1172 /* Set the primary parameters - baud rate, character size, etcetera. */
1173 #ifdef HAVE_TCATTR
1174 int i;
1175 /* We have those nifty POSIX tcmumbleattr functions.
1176 William J. Smith <wjs@wiis.wang.com> writes:
1177 "POSIX 1003.1 defines tcsetattr to return success if it was
1178 able to perform any of the requested actions, even if some
1179 of the requested actions could not be performed.
1180 We must read settings back to ensure tty setup properly.
1181 AIX requires this to keep tty from hanging occasionally." */
1182 /* This make sure that we don't loop indefinitely in here. */
1183 for (i = 0 ; i < 10 ; i++)
1184 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
1186 if (errno == EINTR)
1187 continue;
1188 else
1189 return -1;
1191 else
1193 struct termios new;
1195 bzero (&new, sizeof (new));
1196 /* Get the current settings, and see if they're what we asked for. */
1197 tcgetattr (fd, &new);
1198 /* We cannot use memcmp on the whole structure here because under
1199 * aix386 the termios structure has some reserved field that may
1200 * not be filled in.
1202 if ( new.c_iflag == settings->main.c_iflag
1203 && new.c_oflag == settings->main.c_oflag
1204 && new.c_cflag == settings->main.c_cflag
1205 && new.c_lflag == settings->main.c_lflag
1206 && memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
1207 break;
1208 else
1209 continue;
1212 #else
1213 #ifdef HAVE_TERMIO
1214 /* The SYSV-style interface? */
1215 if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
1216 return -1;
1218 #else
1219 #ifdef VMS
1220 /* Vehemently Monstrous System? :-) */
1221 if (! (SYS$QIOW (0, fd, IO$_SETMODE, &input_iosb, 0, 0,
1222 &settings->main.class, 12, 0, 0, 0, 0)
1223 & 1))
1224 return -1;
1226 #else
1227 #ifndef DOS_NT
1228 /* I give up - I hope you have the BSD ioctls. */
1229 if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
1230 return -1;
1231 #endif /* not DOS_NT */
1233 #endif
1234 #endif
1235 #endif
1237 /* Suivant - Do we have to get struct ltchars data? */
1238 #ifdef HAVE_LTCHARS
1239 if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
1240 return -1;
1241 #endif
1243 /* How about a struct tchars and a wordful of lmode bits? */
1244 #ifdef HAVE_TCHARS
1245 if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
1246 || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
1247 return -1;
1248 #endif
1250 /* We have survived the tempest. */
1251 return 0;
1256 #ifdef BSD4_1
1257 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1258 sigio. */
1259 int lmode;
1260 #endif
1262 #ifndef F_SETOWN_BUG
1263 #ifdef F_SETOWN
1264 int old_fcntl_owner;
1265 #endif /* F_SETOWN */
1266 #endif /* F_SETOWN_BUG */
1268 /* This may also be defined in stdio,
1269 but if so, this does no harm,
1270 and using the same name avoids wasting the other one's space. */
1272 #ifdef nec_ews_svr4
1273 extern char *_sobuf ;
1274 #else
1275 #if defined (USG) || defined (DGUX)
1276 unsigned char _sobuf[BUFSIZ+8];
1277 #else
1278 char _sobuf[BUFSIZ];
1279 #endif
1280 #endif
1282 #ifdef HAVE_LTCHARS
1283 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
1284 #endif
1285 #ifdef HAVE_TCHARS
1286 static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
1287 #endif
1289 void
1290 init_all_sys_modes (void)
1292 struct tty_output *tty = tty_list;
1293 while (tty) {
1294 init_sys_modes (tty);
1295 tty = tty->next;
1299 void
1300 init_sys_modes (tty_out)
1301 struct tty_output *tty_out;
1303 struct emacs_tty tty;
1305 #ifdef MAC_OS8
1306 /* cus-start.el complains if delete-exited-processes is not defined */
1307 #ifndef subprocesses
1308 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
1309 doc: /* *Non-nil means delete processes immediately when they exit.
1310 nil means don't delete them until `list-processes' is run. */);
1311 delete_exited_processes = 0;
1312 #endif
1313 #endif /* MAC_OS8 */
1315 #ifdef VMS
1316 #if 0
1317 static int oob_chars[2] = {0, 1 << 7}; /* catch C-g's */
1318 extern int (*interrupt_signal) ();
1319 #endif
1320 #endif
1322 Vtty_erase_char = Qnil;
1324 if (noninteractive)
1325 return;
1327 #ifdef VMS
1328 if (!input_ef)
1329 input_ef = get_kbd_event_flag ();
1330 /* LIB$GET_EF (&input_ef); */
1331 SYS$CLREF (input_ef);
1332 waiting_for_ast = 0;
1333 if (!timer_ef)
1334 timer_ef = get_timer_event_flag ();
1335 /* LIB$GET_EF (&timer_ef); */
1336 SYS$CLREF (timer_ef);
1337 #if 0
1338 if (!process_ef)
1340 LIB$GET_EF (&process_ef);
1341 SYS$CLREF (process_ef);
1343 if (input_ef / 32 != process_ef / 32)
1344 croak ("Input and process event flags in different clusters.");
1345 #endif
1346 if (input_ef / 32 != timer_ef / 32)
1347 croak ("Input and timer event flags in different clusters.");
1348 #if 0
1349 input_eflist = ((unsigned) 1 << (input_ef % 32)) |
1350 ((unsigned) 1 << (process_ef % 32));
1351 #endif
1352 timer_eflist = ((unsigned) 1 << (input_ef % 32)) |
1353 ((unsigned) 1 << (timer_ef % 32));
1354 #ifndef VMS4_4
1355 sys_access_reinit ();
1356 #endif
1357 #endif /* VMS */
1359 #ifdef BSD_PGRPS
1360 if (! read_socket_hook && EQ (Vwindow_system, Qnil))
1361 narrow_foreground_group (tty_out);
1362 #endif
1364 #ifdef HAVE_WINDOW_SYSTEM
1365 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1366 needs the initialization code below. */
1367 if (!read_socket_hook && EQ (Vwindow_system, Qnil))
1368 #endif
1370 if (! tty_out->old_tty)
1371 tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
1373 EMACS_GET_TTY (fileno (TTY_INPUT (tty_out)), tty_out->old_tty);
1375 tty = *tty_out->old_tty;
1377 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1378 XSETINT (Vtty_erase_char, tty.main.c_cc[VERASE]);
1380 #ifdef DGUX
1381 /* This allows meta to be sent on 8th bit. */
1382 tty.main.c_iflag &= ~INPCK; /* don't check input for parity */
1383 #endif
1384 tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
1385 tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
1386 #ifdef INLCR /* I'm just being cautious,
1387 since I can't check how widespread INLCR is--rms. */
1388 tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
1389 #endif
1390 #ifdef ISTRIP
1391 tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
1392 #endif
1393 tty.main.c_lflag &= ~ECHO; /* Disable echo */
1394 tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */
1395 #ifdef IEXTEN
1396 tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
1397 #endif
1398 tty.main.c_lflag |= ISIG; /* Enable signals */
1399 if (flow_control)
1401 tty.main.c_iflag |= IXON; /* Enable start/stop output control */
1402 #ifdef IXANY
1403 tty.main.c_iflag &= ~IXANY;
1404 #endif /* IXANY */
1406 else
1407 tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
1408 tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
1409 on output */
1410 tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */
1411 #ifdef CS8
1412 if (tty_out->meta_key)
1414 tty.main.c_cflag |= CS8; /* allow 8th bit on input */
1415 tty.main.c_cflag &= ~PARENB;/* Don't check parity */
1417 #endif
1418 tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
1419 /* Set up C-g for both SIGQUIT and SIGINT.
1420 We don't know which we will get, but we handle both alike
1421 so which one it really gives us does not matter. */
1422 tty.main.c_cc[VQUIT] = quit_char;
1423 tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
1424 tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
1425 #ifdef VSWTCH
1426 tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
1427 of C-z */
1428 #endif /* VSWTCH */
1430 #if defined (mips) || defined (HAVE_TCATTR)
1431 #ifdef VSUSP
1432 tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
1433 #endif /* VSUSP */
1434 #ifdef V_DSUSP
1435 tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
1436 #endif /* V_DSUSP */
1437 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1438 tty.main.c_cc[VDSUSP] = CDISABLE;
1439 #endif /* VDSUSP */
1440 #ifdef VLNEXT
1441 tty.main.c_cc[VLNEXT] = CDISABLE;
1442 #endif /* VLNEXT */
1443 #ifdef VREPRINT
1444 tty.main.c_cc[VREPRINT] = CDISABLE;
1445 #endif /* VREPRINT */
1446 #ifdef VWERASE
1447 tty.main.c_cc[VWERASE] = CDISABLE;
1448 #endif /* VWERASE */
1449 #ifdef VDISCARD
1450 tty.main.c_cc[VDISCARD] = CDISABLE;
1451 #endif /* VDISCARD */
1453 if (flow_control)
1455 #ifdef VSTART
1456 tty.main.c_cc[VSTART] = '\021';
1457 #endif /* VSTART */
1458 #ifdef VSTOP
1459 tty.main.c_cc[VSTOP] = '\023';
1460 #endif /* VSTOP */
1462 else
1464 #ifdef VSTART
1465 tty.main.c_cc[VSTART] = CDISABLE;
1466 #endif /* VSTART */
1467 #ifdef VSTOP
1468 tty.main.c_cc[VSTOP] = CDISABLE;
1469 #endif /* VSTOP */
1471 #endif /* mips or HAVE_TCATTR */
1473 #ifdef SET_LINE_DISCIPLINE
1474 /* Need to explicitly request TERMIODISC line discipline or
1475 Ultrix's termios does not work correctly. */
1476 tty.main.c_line = SET_LINE_DISCIPLINE;
1477 #endif
1478 #ifdef AIX
1479 #ifndef IBMR2AIX
1480 /* AIX enhanced edit loses NULs, so disable it. */
1481 tty.main.c_line = 0;
1482 tty.main.c_iflag &= ~ASCEDIT;
1483 #else
1484 tty.main.c_cc[VSTRT] = 255;
1485 tty.main.c_cc[VSTOP] = 255;
1486 tty.main.c_cc[VSUSP] = 255;
1487 tty.main.c_cc[VDSUSP] = 255;
1488 #endif /* IBMR2AIX */
1489 if (flow_control)
1491 #ifdef VSTART
1492 tty.main.c_cc[VSTART] = '\021';
1493 #endif /* VSTART */
1494 #ifdef VSTOP
1495 tty.main.c_cc[VSTOP] = '\023';
1496 #endif /* VSTOP */
1498 /* Also, PTY overloads NUL and BREAK.
1499 don't ignore break, but don't signal either, so it looks like NUL.
1500 This really serves a purpose only if running in an XTERM window
1501 or via TELNET or the like, but does no harm elsewhere. */
1502 tty.main.c_iflag &= ~IGNBRK;
1503 tty.main.c_iflag &= ~BRKINT;
1504 #endif
1505 #else /* if not HAVE_TERMIO */
1506 #ifdef VMS
1507 tty.main.tt_char |= TT$M_NOECHO;
1508 if (meta_key)
1509 tty.main.tt_char |= TT$M_EIGHTBIT;
1510 if (flow_control)
1511 tty.main.tt_char |= TT$M_TTSYNC;
1512 else
1513 tty.main.tt_char &= ~TT$M_TTSYNC;
1514 tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
1515 #else /* not VMS (BSD, that is) */
1516 #ifndef DOS_NT
1517 XSETINT (Vtty_erase_char, tty.main.sg_erase);
1518 tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1519 if (meta_key)
1520 tty.main.sg_flags |= ANYP;
1521 tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
1522 #endif /* not DOS_NT */
1523 #endif /* not VMS (BSD, that is) */
1524 #endif /* not HAVE_TERMIO */
1526 /* If going to use CBREAK mode, we must request C-g to interrupt
1527 and turn off start and stop chars, etc. If not going to use
1528 CBREAK mode, do this anyway so as to turn off local flow
1529 control for user coming over network on 4.2; in this case,
1530 only t_stopc and t_startc really matter. */
1531 #ifndef HAVE_TERMIO
1532 #ifdef HAVE_TCHARS
1533 /* Note: if not using CBREAK mode, it makes no difference how we
1534 set this */
1535 tty.tchars = new_tchars;
1536 tty.tchars.t_intrc = quit_char;
1537 if (flow_control)
1539 tty.tchars.t_startc = '\021';
1540 tty.tchars.t_stopc = '\023';
1543 tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | tty_out->old_tty.lmode;
1544 #ifdef ultrix
1545 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1546 anything, and leaving it in breaks the meta key. Go figure. */
1547 tty.lmode &= ~LLITOUT;
1548 #endif
1550 #ifdef BSD4_1
1551 lmode = tty.lmode;
1552 #endif
1554 #endif /* HAVE_TCHARS */
1555 #endif /* not HAVE_TERMIO */
1557 #ifdef HAVE_LTCHARS
1558 tty.ltchars = new_ltchars;
1559 #endif /* HAVE_LTCHARS */
1560 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1561 if (!tty_out->term_initted)
1562 internal_terminal_init ();
1563 dos_ttraw ();
1564 #endif
1566 EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)), &tty, 0);
1568 /* This code added to insure that, if flow-control is not to be used,
1569 we have an unlocked terminal at the start. */
1571 #ifdef TCXONC
1572 if (!flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TCXONC, 1);
1573 #endif
1574 #ifndef APOLLO
1575 #ifdef TIOCSTART
1576 if (!flow_control) ioctl (fileno (TTY_INPUT (tty_out)), TIOCSTART, 0);
1577 #endif
1578 #endif
1580 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1581 #ifdef TCOON
1582 if (!flow_control) tcflow (fileno (TTY_INPUT (tty_out)), TCOON);
1583 #endif
1584 #endif
1586 #ifdef AIXHFT
1587 hft_init (tty_out);
1588 #ifdef IBMR2AIX
1590 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1591 to be only LF. This is the way that is done. */
1592 struct termio tty;
1594 if (ioctl (1, HFTGETID, &tty) != -1)
1595 write (1, "\033[20l", 5);
1597 #endif
1598 #endif /* AIXHFT */
1600 #ifdef VMS
1601 /* Appears to do nothing when in PASTHRU mode.
1602 SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1603 interrupt_signal, oob_chars, 0, 0, 0, 0);
1605 queue_kbd_input (0);
1606 #endif /* VMS */
1609 #ifdef F_SETFL
1610 #ifndef F_SETOWN_BUG
1611 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1612 if (interrupt_input
1613 && ! read_socket_hook && EQ (Vwindow_system, Qnil))
1615 old_fcntl_owner = fcntl (fileno (TTY_INPUT (tty_out)), F_GETOWN, 0);
1616 fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN, getpid ());
1617 init_sigio (fileno (TTY_INPUT (tty_out)));
1619 #endif /* F_GETOWN */
1620 #endif /* F_SETOWN_BUG */
1621 #endif /* F_SETFL */
1623 #ifdef BSD4_1
1624 if (interrupt_input)
1625 init_sigio (fileno (TTY_INPUT (tty_out)));
1626 #endif
1628 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1629 #undef _IOFBF
1630 #endif
1631 #ifdef _IOFBF
1632 /* This symbol is defined on recent USG systems.
1633 Someone says without this call USG won't really buffer the file
1634 even with a call to setbuf. */
1635 setvbuf (TTY_OUTPUT (tty_out), (char *) _sobuf, _IOFBF, sizeof _sobuf);
1636 #else
1637 setbuf (TTY_OUTPUT (tty_out), (char *) _sobuf);
1638 #endif
1639 #ifdef HAVE_WINDOW_SYSTEM
1640 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1641 needs the initialization code below. */
1642 if (EQ (Vwindow_system, Qnil)
1643 #ifndef WINDOWSNT
1644 /* When running in tty mode on NT/Win95, we have a read_socket
1645 hook, but still need the rest of the initialization code below. */
1646 && (! read_socket_hook)
1647 #endif
1649 #endif
1651 if (!tty_out->term_initted)
1653 Lisp_Object tail, frame;
1654 FOR_EACH_FRAME (tail, frame)
1656 if (FRAME_TERMCAP_P (XFRAME (frame))
1657 && FRAME_TTY (XFRAME (frame)) == tty_out)
1658 init_frame_faces (XFRAME (frame));
1662 if (tty_out->term_initted && no_redraw_on_reenter)
1664 if (display_completed)
1665 direct_output_forward_char (0);
1667 else
1669 Lisp_Object tail, frame;
1670 frame_garbaged = 1;
1671 FOR_EACH_FRAME (tail, frame)
1673 if (FRAME_TERMCAP_P (XFRAME (frame))
1674 && FRAME_TTY (XFRAME (frame)) == tty_out)
1675 FRAME_GARBAGED_P (XFRAME (frame)) = 1;
1679 tty_out->term_initted = 1;
1682 /* Return nonzero if safe to use tabs in output.
1683 At the time this is called, init_sys_modes has not been done yet. */
1686 tabs_safe_p (struct tty_output *tty)
1688 struct emacs_tty etty;
1690 EMACS_GET_TTY (fileno (TTY_INPUT (tty)), &etty);
1691 return EMACS_TTY_TABS_OK (&etty);
1694 /* Get terminal size from system.
1695 Store number of lines into *HEIGHTP and width into *WIDTHP.
1696 We store 0 if there's no valid information. */
1698 void
1699 get_tty_size (tty_out, widthp, heightp)
1700 struct tty_output *tty_out;
1701 int *widthp, *heightp;
1704 #ifdef TIOCGWINSZ
1706 /* BSD-style. */
1707 struct winsize size;
1709 if (ioctl (fileno (TTY_INPUT (tty_out)), TIOCGWINSZ, &size) == -1)
1710 *widthp = *heightp = 0;
1711 else
1713 *widthp = size.ws_col;
1714 *heightp = size.ws_row;
1717 #else
1718 #ifdef TIOCGSIZE
1720 /* SunOS - style. */
1721 struct ttysize size;
1723 if (ioctl (fileno (TTY_INPUT (tty_out)), TIOCGSIZE, &size) == -1)
1724 *widthp = *heightp = 0;
1725 else
1727 *widthp = size.ts_cols;
1728 *heightp = size.ts_lines;
1731 #else
1732 #ifdef VMS
1734 struct sensemode tty;
1736 SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SENSEMODE, &tty, 0, 0,
1737 &tty.class, 12, 0, 0, 0, 0);
1738 *widthp = tty.scr_wid;
1739 *heightp = tty.scr_len;
1741 #else
1742 #ifdef MSDOS
1743 *widthp = ScreenCols ();
1744 *heightp = ScreenRows ();
1745 #else /* system doesn't know size */
1746 *widthp = 0;
1747 *heightp = 0;
1748 #endif
1750 #endif /* not VMS */
1751 #endif /* not SunOS-style */
1752 #endif /* not BSD-style */
1755 /* Set the logical window size associated with descriptor FD
1756 to HEIGHT and WIDTH. This is used mainly with ptys. */
1759 set_window_size (fd, height, width)
1760 int fd, height, width;
1762 #ifdef TIOCSWINSZ
1764 /* BSD-style. */
1765 struct winsize size;
1766 size.ws_row = height;
1767 size.ws_col = width;
1769 if (ioctl (fd, TIOCSWINSZ, &size) == -1)
1770 return 0; /* error */
1771 else
1772 return 1;
1774 #else
1775 #ifdef TIOCSSIZE
1777 /* SunOS - style. */
1778 struct ttysize size;
1779 size.ts_lines = height;
1780 size.ts_cols = width;
1782 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1783 return 0;
1784 else
1785 return 1;
1786 #else
1787 return -1;
1788 #endif /* not SunOS-style */
1789 #endif /* not BSD-style */
1793 void
1794 reset_all_sys_modes (void)
1796 struct tty_output *tty = tty_list;
1797 while (tty) {
1798 reset_sys_modes (tty);
1799 tty = tty->next;
1803 /* Prepare the terminal for closing it; move the cursor to the
1804 bottom of the frame, turn off interrupt-driven I/O, etc. */
1805 void
1806 reset_sys_modes (tty_out)
1807 struct tty_output *tty_out;
1809 if (noninteractive)
1811 fflush (stdout);
1812 return;
1814 if (!tty_out->term_initted)
1815 return;
1816 #ifdef HAVE_WINDOW_SYSTEM
1817 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1818 needs the clean-up code below. */
1819 if (!EQ (Vwindow_system, Qnil)
1820 #ifndef WINDOWSNT
1821 /* When running in tty mode on NT/Win95, we have a read_socket
1822 hook, but still need the rest of the clean-up code below. */
1823 || read_socket_hook
1824 #endif
1826 return;
1827 #endif
1828 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1829 tty_clear_end_of_line (tty_out, FrameCols (tty_out));
1830 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1831 #if defined (IBMR2AIX) && defined (AIXHFT)
1833 /* HFT devices normally use ^J as a LF/CR. We forced it to
1834 do the LF only. Now, we need to reset it. */
1835 struct termio tty;
1837 if (ioctl (1, HFTGETID, &tty) != -1)
1838 write (1, "\033[20h", 5);
1840 #endif
1842 tty_reset_terminal_modes (tty_out);
1843 fflush (TTY_OUTPUT (tty_out));
1844 #ifdef BSD_SYSTEM
1845 #ifndef BSD4_1
1846 /* Avoid possible loss of output when changing terminal modes. */
1847 fsync (TTY_OUTPUT (tty_out));
1848 #endif
1849 #endif
1851 #ifdef F_SETFL
1852 #ifndef F_SETOWN_BUG
1853 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1854 if (interrupt_input)
1856 reset_sigio (tty_out);
1857 fcntl (fileno (TTY_INPUT (tty_out)), F_SETOWN, old_fcntl_owner);
1859 #endif /* F_SETOWN */
1860 #endif /* F_SETOWN_BUG */
1861 #ifdef O_NDELAY
1862 fcntl (fileno (TTY_INPUT (tty_out)), F_SETFL,
1863 fcntl (fileno (TTY_INPUT (tty_out)), F_GETFL, 0) & ~O_NDELAY);
1864 #endif
1865 #endif /* F_SETFL */
1866 #ifdef BSD4_1
1867 if (interrupt_input)
1868 reset_sigio (tty_out);
1869 #endif /* BSD4_1 */
1871 if (tty_out->old_tty)
1872 while (EMACS_SET_TTY (fileno (TTY_INPUT (tty_out)),
1873 tty_out->old_tty, 0) < 0 && errno == EINTR)
1876 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1877 dos_ttcooked ();
1878 #endif
1880 #ifdef SET_LINE_DISCIPLINE
1881 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1882 A different old line discipline is therefore not restored, yet.
1883 Restore the old line discipline by hand. */
1884 ioctl (0, TIOCSETD, &tty_out->old_tty.main.c_line);
1885 #endif
1887 #ifdef AIXHFT
1888 hft_reset ();
1889 #endif
1891 #ifdef BSD_PGRPS
1892 widen_foreground_group (tty_out);
1893 #endif
1896 #ifdef HAVE_PTYS
1898 /* Set up the proper status flags for use of a pty. */
1900 void
1901 setup_pty (fd)
1902 int fd;
1904 /* I'm told that TOICREMOTE does not mean control chars
1905 "can't be sent" but rather that they don't have
1906 input-editing or signaling effects.
1907 That should be good, because we have other ways
1908 to do those things in Emacs.
1909 However, telnet mode seems not to work on 4.2.
1910 So TIOCREMOTE is turned off now. */
1912 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1913 will hang. In particular, the "timeout" feature (which
1914 causes a read to return if there is no data available)
1915 does this. Also it is known that telnet mode will hang
1916 in such a way that Emacs must be stopped (perhaps this
1917 is the same problem).
1919 If TIOCREMOTE is turned off, then there is a bug in
1920 hp-ux which sometimes loses data. Apparently the
1921 code which blocks the master process when the internal
1922 buffer fills up does not work. Other than this,
1923 though, everything else seems to work fine.
1925 Since the latter lossage is more benign, we may as well
1926 lose that way. -- cph */
1927 #ifdef FIONBIO
1928 #if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
1930 int on = 1;
1931 ioctl (fd, FIONBIO, &on);
1933 #endif
1934 #endif
1935 #ifdef IBMRTAIX
1936 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1937 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1938 /* cause EMACS not to die when it should, i.e., when its own controlling */
1939 /* tty goes away. I've complained to the AIX developers, and they may */
1940 /* change this behavior, but I'm not going to hold my breath. */
1941 signal (SIGHUP, SIG_IGN);
1942 #endif
1944 #endif /* HAVE_PTYS */
1946 #ifdef VMS
1948 /* Assigning an input channel is done at the start of Emacs execution.
1949 This is called each time Emacs is resumed, also, but does nothing
1950 because input_chain is no longer zero. */
1952 void
1953 init_vms_input ()
1955 int status;
1957 if (fileno (TTY_INPUT (CURTTY())) == 0)
1959 status = SYS$ASSIGN (&input_dsc, &fileno (TTY_INPUT (CURTTY())), 0, 0);
1960 if (! (status & 1))
1961 LIB$STOP (status);
1965 /* Deassigning the input channel is done before exiting. */
1967 void
1968 stop_vms_input ()
1970 return SYS$DASSGN (fileno (TTY_INPUT (CURTTY())));
1973 short input_buffer;
1975 /* Request reading one character into the keyboard buffer.
1976 This is done as soon as the buffer becomes empty. */
1978 void
1979 queue_kbd_input ()
1981 int status;
1982 extern kbd_input_ast ();
1984 waiting_for_ast = 0;
1985 stop_input = 0;
1986 status = SYS$QIO (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK,
1987 &input_iosb, kbd_input_ast, 1,
1988 &input_buffer, 1, 0, terminator_mask, 0, 0);
1991 int input_count;
1993 /* Ast routine that is called when keyboard input comes in
1994 in accord with the SYS$QIO above. */
1996 void
1997 kbd_input_ast ()
1999 register int c = -1;
2000 int old_errno = errno;
2001 extern EMACS_TIME *input_available_clear_time;
2003 if (waiting_for_ast)
2004 SYS$SETEF (input_ef);
2005 waiting_for_ast = 0;
2006 input_count++;
2007 #ifdef ASTDEBUG
2008 if (input_count == 25)
2009 exit (1);
2010 printf ("Ast # %d,", input_count);
2011 printf (" iosb = %x, %x, %x, %x",
2012 input_iosb.offset, input_iosb.status, input_iosb.termlen,
2013 input_iosb.term);
2014 #endif
2015 if (input_iosb.offset)
2017 c = input_buffer;
2018 #ifdef ASTDEBUG
2019 printf (", char = 0%o", c);
2020 #endif
2022 #ifdef ASTDEBUG
2023 printf ("\n");
2024 fflush (stdout);
2025 sleep (1);
2026 #endif
2027 if (! stop_input)
2028 queue_kbd_input ();
2029 if (c >= 0)
2031 struct input_event e;
2032 EVENT_INIT (e);
2034 e.kind = ASCII_KEYSTROKE_EVENT;
2035 XSETINT (e.code, c);
2036 e.frame_or_window = selected_frame;
2037 kbd_buffer_store_event (&e);
2039 if (input_available_clear_time)
2040 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
2041 errno = old_errno;
2044 /* Wait until there is something in kbd_buffer. */
2046 void
2047 wait_for_kbd_input ()
2049 extern int have_process_input, process_exited;
2051 /* If already something, avoid doing system calls. */
2052 if (detect_input_pending ())
2054 return;
2056 /* Clear a flag, and tell ast routine above to set it. */
2057 SYS$CLREF (input_ef);
2058 waiting_for_ast = 1;
2059 /* Check for timing error: ast happened while we were doing that. */
2060 if (!detect_input_pending ())
2062 /* No timing error: wait for flag to be set. */
2063 set_waiting_for_input (0);
2064 SYS$WFLOR (input_ef, input_eflist);
2065 clear_waiting_for_input ();
2066 if (!detect_input_pending ())
2067 /* Check for subprocess input availability */
2069 int dsp = have_process_input || process_exited;
2071 SYS$CLREF (process_ef);
2072 if (have_process_input)
2073 process_command_input ();
2074 if (process_exited)
2075 process_exit ();
2076 if (dsp)
2078 update_mode_lines++;
2079 prepare_menu_bars ();
2080 redisplay_preserve_echo_area (18);
2084 waiting_for_ast = 0;
2087 /* Get rid of any pending QIO, when we are about to suspend
2088 or when we want to throw away pending input.
2089 We wait for a positive sign that the AST routine has run
2090 and therefore there is no I/O request queued when we return.
2091 SYS$SETAST is used to avoid a timing error. */
2093 void
2094 end_kbd_input ()
2096 #ifdef ASTDEBUG
2097 printf ("At end_kbd_input.\n");
2098 fflush (stdout);
2099 sleep (1);
2100 #endif
2101 if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2103 SYS$CANCEL (fileno (TTY_INPUT (CURTTY())));
2104 return;
2107 SYS$SETAST (0);
2108 /* Clear a flag, and tell ast routine above to set it. */
2109 SYS$CLREF (input_ef);
2110 waiting_for_ast = 1;
2111 stop_input = 1;
2112 SYS$CANCEL (fileno (TTY_INPUT (CURTTY())));
2113 SYS$SETAST (1);
2114 SYS$WAITFR (input_ef);
2115 waiting_for_ast = 0;
2118 /* Wait for either input available or time interval expiry. */
2120 void
2121 input_wait_timeout (timeval)
2122 int timeval; /* Time to wait, in seconds */
2124 int time [2];
2125 static int zero = 0;
2126 static int large = -10000000;
2128 LIB$EMUL (&timeval, &large, &zero, time); /* Convert to VMS format */
2130 /* If already something, avoid doing system calls. */
2131 if (detect_input_pending ())
2133 return;
2135 /* Clear a flag, and tell ast routine above to set it. */
2136 SYS$CLREF (input_ef);
2137 waiting_for_ast = 1;
2138 /* Check for timing error: ast happened while we were doing that. */
2139 if (!detect_input_pending ())
2141 /* No timing error: wait for flag to be set. */
2142 SYS$CANTIM (1, 0);
2143 if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
2144 SYS$WFLOR (timer_ef, timer_eflist); /* Wait for timer expiry or input */
2146 waiting_for_ast = 0;
2149 /* The standard `sleep' routine works some other way
2150 and it stops working if you have ever quit out of it.
2151 This one continues to work. */
2153 sys_sleep (timeval)
2154 int timeval;
2156 int time [2];
2157 static int zero = 0;
2158 static int large = -10000000;
2160 LIB$EMUL (&timeval, &large, &zero, time); /* Convert to VMS format */
2162 SYS$CANTIM (1, 0);
2163 if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
2164 SYS$WAITFR (timer_ef); /* Wait for timer expiry only */
2167 void
2168 init_sigio (fd)
2169 int fd;
2171 request_sigio ();
2174 reset_sigio (fd)
2175 int fd;
2177 unrequest_sigio ();
2180 void
2181 request_sigio ()
2183 croak ("request sigio");
2186 void
2187 unrequest_sigio ()
2189 croak ("unrequest sigio");
2192 #endif /* VMS */
2194 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2195 #ifndef CANNOT_DUMP
2196 #define NEED_STARTS
2197 #endif
2199 #ifndef SYSTEM_MALLOC
2200 #ifndef NEED_STARTS
2201 #define NEED_STARTS
2202 #endif
2203 #endif
2205 #ifdef NEED_STARTS
2206 /* Some systems that cannot dump also cannot implement these. */
2209 * Return the address of the start of the text segment prior to
2210 * doing an unexec. After unexec the return value is undefined.
2211 * See crt0.c for further explanation and _start.
2215 #if !(defined (__NetBSD__) && defined (__ELF__))
2216 #ifndef HAVE_TEXT_START
2217 char *
2218 start_of_text ()
2220 #ifdef TEXT_START
2221 return ((char *) TEXT_START);
2222 #else
2223 #ifdef GOULD
2224 extern csrt ();
2225 return ((char *) csrt);
2226 #else /* not GOULD */
2227 extern int _start ();
2228 return ((char *) _start);
2229 #endif /* GOULD */
2230 #endif /* TEXT_START */
2232 #endif /* not HAVE_TEXT_START */
2233 #endif
2236 * Return the address of the start of the data segment prior to
2237 * doing an unexec. After unexec the return value is undefined.
2238 * See crt0.c for further information and definition of data_start.
2240 * Apparently, on BSD systems this is etext at startup. On
2241 * USG systems (swapping) this is highly mmu dependent and
2242 * is also dependent on whether or not the program is running
2243 * with shared text. Generally there is a (possibly large)
2244 * gap between end of text and start of data with shared text.
2246 * On Uniplus+ systems with shared text, data starts at a
2247 * fixed address. Each port (from a given oem) is generally
2248 * different, and the specific value of the start of data can
2249 * be obtained via the UniPlus+ specific "uvar" system call,
2250 * however the method outlined in crt0.c seems to be more portable.
2252 * Probably what will have to happen when a USG unexec is available,
2253 * at least on UniPlus, is temacs will have to be made unshared so
2254 * that text and data are contiguous. Then once loadup is complete,
2255 * unexec will produce a shared executable where the data can be
2256 * at the normal shared text boundary and the startofdata variable
2257 * will be patched by unexec to the correct value.
2261 #ifndef start_of_data
2262 char *
2263 start_of_data ()
2265 #ifdef DATA_START
2266 return ((char *) DATA_START);
2267 #else
2268 #ifdef ORDINARY_LINK
2270 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2271 * data_start isn't defined. We take the address of environ, which
2272 * is known to live at or near the start of the system crt0.c, and
2273 * we don't sweat the handful of bytes that might lose.
2275 extern char **environ;
2277 return ((char *) &environ);
2278 #else
2279 extern int data_start;
2280 return ((char *) &data_start);
2281 #endif /* ORDINARY_LINK */
2282 #endif /* DATA_START */
2284 #endif /* start_of_data */
2285 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2287 /* init_system_name sets up the string for the Lisp function
2288 system-name to return. */
2290 #ifdef BSD4_1
2291 #include <whoami.h>
2292 #endif
2294 extern Lisp_Object Vsystem_name;
2296 #ifndef BSD4_1
2297 #ifndef VMS
2298 #ifdef HAVE_SOCKETS
2299 #include <sys/socket.h>
2300 #include <netdb.h>
2301 #endif /* HAVE_SOCKETS */
2302 #endif /* not VMS */
2303 #endif /* not BSD4_1 */
2305 #ifdef TRY_AGAIN
2306 #ifndef HAVE_H_ERRNO
2307 extern int h_errno;
2308 #endif
2309 #endif /* TRY_AGAIN */
2311 void
2312 init_system_name ()
2314 #ifdef BSD4_1
2315 Vsystem_name = build_string (sysname);
2316 #else
2317 #ifdef VMS
2318 char *sp, *end;
2319 if ((sp = egetenv ("SYS$NODE")) == 0)
2320 Vsystem_name = build_string ("vax-vms");
2321 else if ((end = index (sp, ':')) == 0)
2322 Vsystem_name = build_string (sp);
2323 else
2324 Vsystem_name = make_string (sp, end - sp);
2325 #else
2326 #ifndef HAVE_GETHOSTNAME
2327 struct utsname uts;
2328 uname (&uts);
2329 Vsystem_name = build_string (uts.nodename);
2330 #else /* HAVE_GETHOSTNAME */
2331 unsigned int hostname_size = 256;
2332 char *hostname = (char *) alloca (hostname_size);
2334 /* Try to get the host name; if the buffer is too short, try
2335 again. Apparently, the only indication gethostname gives of
2336 whether the buffer was large enough is the presence or absence
2337 of a '\0' in the string. Eech. */
2338 for (;;)
2340 gethostname (hostname, hostname_size - 1);
2341 hostname[hostname_size - 1] = '\0';
2343 /* Was the buffer large enough for the '\0'? */
2344 if (strlen (hostname) < hostname_size - 1)
2345 break;
2347 hostname_size <<= 1;
2348 hostname = (char *) alloca (hostname_size);
2350 #ifdef HAVE_SOCKETS
2351 /* Turn the hostname into the official, fully-qualified hostname.
2352 Don't do this if we're going to dump; this can confuse system
2353 libraries on some machines and make the dumped emacs core dump. */
2354 #ifndef CANNOT_DUMP
2355 if (initialized)
2356 #endif /* not CANNOT_DUMP */
2357 if (! index (hostname, '.'))
2359 struct hostent *hp;
2360 int count;
2361 for (count = 0;; count++)
2363 #ifdef TRY_AGAIN
2364 h_errno = 0;
2365 #endif
2366 hp = gethostbyname (hostname);
2367 #ifdef TRY_AGAIN
2368 if (! (hp == 0 && h_errno == TRY_AGAIN))
2369 #endif
2370 break;
2371 if (count >= 5)
2372 break;
2373 Fsleep_for (make_number (1), Qnil);
2375 if (hp)
2377 char *fqdn = (char *) hp->h_name;
2378 #if 0
2379 char *p;
2380 #endif
2382 if (!index (fqdn, '.'))
2384 /* We still don't have a fully qualified domain name.
2385 Try to find one in the list of alternate names */
2386 char **alias = hp->h_aliases;
2387 while (*alias && !index (*alias, '.'))
2388 alias++;
2389 if (*alias)
2390 fqdn = *alias;
2392 hostname = fqdn;
2393 #if 0
2394 /* Convert the host name to lower case. */
2395 /* Using ctype.h here would introduce a possible locale
2396 dependence that is probably wrong for hostnames. */
2397 p = hostname;
2398 while (*p)
2400 if (*p >= 'A' && *p <= 'Z')
2401 *p += 'a' - 'A';
2402 p++;
2404 #endif
2407 #endif /* HAVE_SOCKETS */
2408 /* We used to try using getdomainname here,
2409 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2410 getdomainname gets the NIS/YP domain which often is not the same
2411 as in Internet domain name. */
2412 #if 0 /* Turned off because sysinfo is not really likely to return the
2413 correct Internet domain. */
2414 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2415 if (! index (hostname, '.'))
2417 /* The hostname is not fully qualified. Append the domain name. */
2419 int hostlen = strlen (hostname);
2420 int domain_size = 256;
2422 for (;;)
2424 char *domain = (char *) alloca (domain_size + 1);
2425 char *fqdn = (char *) alloca (hostlen + 1 + domain_size + 1);
2426 int sys_domain_size = sysinfo (SI_SRPC_DOMAIN, domain, domain_size);
2427 if (sys_domain_size <= 0)
2428 break;
2429 if (domain_size < sys_domain_size)
2431 domain_size = sys_domain_size;
2432 continue;
2434 strcpy (fqdn, hostname);
2435 if (domain[0] == '.')
2436 strcpy (fqdn + hostlen, domain);
2437 else if (domain[0] != 0)
2439 fqdn[hostlen] = '.';
2440 strcpy (fqdn + hostlen + 1, domain);
2442 hostname = fqdn;
2443 break;
2446 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2447 #endif /* 0 */
2448 Vsystem_name = build_string (hostname);
2449 #endif /* HAVE_GETHOSTNAME */
2450 #endif /* VMS */
2451 #endif /* BSD4_1 */
2453 unsigned char *p;
2454 for (p = SDATA (Vsystem_name); *p; p++)
2455 if (*p == ' ' || *p == '\t')
2456 *p = '-';
2460 #ifndef MSDOS
2461 #ifndef VMS
2462 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2464 #include "sysselect.h"
2465 #undef select
2467 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2468 /* Cause explanatory error message at compile time,
2469 since the select emulation is not good enough for X. */
2470 int *x = &x_windows_lose_if_no_select_system_call;
2471 #endif
2473 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2474 * Only checks read descriptors.
2476 /* How long to wait between checking fds in select */
2477 #define SELECT_PAUSE 1
2478 int select_alarmed;
2480 /* For longjmp'ing back to read_input_waiting. */
2482 jmp_buf read_alarm_throw;
2484 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2485 The read_socket_hook function sets this to 1 while it is waiting. */
2487 int read_alarm_should_throw;
2489 SIGTYPE
2490 select_alarm ()
2492 select_alarmed = 1;
2493 #ifdef BSD4_1
2494 sigrelse (SIGALRM);
2495 #else /* not BSD4_1 */
2496 signal (SIGALRM, SIG_IGN);
2497 #endif /* not BSD4_1 */
2498 if (read_alarm_should_throw)
2499 longjmp (read_alarm_throw, 1);
2502 #if (!defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)) && !defined (WINDOWSNT)
2503 /* Only rfds are checked. */
2505 sys_select (nfds, rfds, wfds, efds, timeout)
2506 int nfds;
2507 SELECT_TYPE *rfds, *wfds, *efds;
2508 EMACS_TIME *timeout;
2510 int ravail = 0;
2511 SELECT_TYPE orfds;
2512 int timeoutval;
2513 int *local_timeout;
2514 extern int proc_buffered_char[];
2515 #ifndef subprocesses
2516 int process_tick = 0, update_tick = 0;
2517 #else
2518 extern int process_tick, update_tick;
2519 #endif
2520 unsigned char buf;
2522 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2523 /* If we're using X, then the native select will work; we only need the
2524 emulation for non-X usage. */
2525 if (!NILP (Vwindow_system))
2526 return select (nfds, rfds, wfds, efds, timeout);
2527 #endif
2528 timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
2529 local_timeout = &timeoutval;
2530 FD_ZERO (&orfds);
2531 if (rfds)
2533 orfds = *rfds;
2534 FD_ZERO (rfds);
2536 if (wfds)
2537 FD_ZERO (wfds);
2538 if (efds)
2539 FD_ZERO (efds);
2541 /* If we are looking only for the terminal, with no timeout,
2542 just read it and wait -- that's more efficient. */
2543 if (*local_timeout == 100000 && process_tick == update_tick
2544 && FD_ISSET (0, &orfds))
2546 int fd;
2547 for (fd = 1; fd < nfds; ++fd)
2548 if (FD_ISSET (fd, &orfds))
2549 goto hardway;
2550 if (! detect_input_pending ())
2551 read_input_waiting ();
2552 FD_SET (0, rfds);
2553 return 1;
2556 hardway:
2557 /* Once a second, till the timer expires, check all the flagged read
2558 * descriptors to see if any input is available. If there is some then
2559 * set the corresponding bit in the return copy of rfds.
2561 while (1)
2563 register int to_check, fd;
2565 if (rfds)
2567 for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
2569 if (FD_ISSET (fd, &orfds))
2571 int avail = 0, status = 0;
2573 if (fd == 0)
2574 avail = detect_input_pending (); /* Special keyboard handler */
2575 else
2577 #ifdef FIONREAD
2578 status = ioctl (fd, FIONREAD, &avail);
2579 #else /* no FIONREAD */
2580 /* Hoping it will return -1 if nothing available
2581 or 0 if all 0 chars requested are read. */
2582 if (proc_buffered_char[fd] >= 0)
2583 avail = 1;
2584 else
2586 avail = read (fd, &buf, 1);
2587 if (avail > 0)
2588 proc_buffered_char[fd] = buf;
2590 #endif /* no FIONREAD */
2592 if (status >= 0 && avail > 0)
2594 FD_SET (fd, rfds);
2595 ravail++;
2600 if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
2601 break;
2603 turn_on_atimers (0);
2604 signal (SIGALRM, select_alarm);
2605 select_alarmed = 0;
2606 alarm (SELECT_PAUSE);
2608 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2609 while (select_alarmed == 0 && *local_timeout != 0
2610 && process_tick == update_tick)
2612 /* If we are interested in terminal input,
2613 wait by reading the terminal.
2614 That makes instant wakeup for terminal input at least. */
2615 if (FD_ISSET (0, &orfds))
2617 read_input_waiting ();
2618 if (detect_input_pending ())
2619 select_alarmed = 1;
2621 else
2622 pause ();
2624 (*local_timeout) -= SELECT_PAUSE;
2626 /* Reset the old alarm if there was one. */
2627 turn_on_atimers (1);
2629 if (*local_timeout == 0) /* Stop on timer being cleared */
2630 break;
2632 return ravail;
2634 #endif /* (!defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)) && !defined (WINDOWSNT) */
2636 /* Read keyboard input into the standard buffer,
2637 waiting for at least one character. */
2639 /* Make all keyboard buffers much bigger when using a window system. */
2640 #ifdef HAVE_WINDOW_SYSTEM
2641 #define BUFFER_SIZE_FACTOR 16
2642 #else
2643 #define BUFFER_SIZE_FACTOR 1
2644 #endif
2646 void
2647 read_input_waiting ()
2649 int nread, i;
2650 extern int quit_char;
2652 if (read_socket_hook)
2654 struct input_event buf[256];
2655 for (i = 0; i < 256; i++)
2656 EVENT_INIT (buf[i]);
2658 read_alarm_should_throw = 0;
2659 if (! setjmp (read_alarm_throw))
2660 nread = (*read_socket_hook) (0, buf, 256, 1);
2661 else
2662 nread = -1;
2664 /* Scan the chars for C-g and store them in kbd_buffer. */
2665 for (i = 0; i < nread; i++)
2667 kbd_buffer_store_event (&buf[i]);
2668 /* Don't look at input that follows a C-g too closely.
2669 This reduces lossage due to autorepeat on C-g. */
2670 if (buf[i].kind == ASCII_KEYSTROKE_EVENT
2671 && buf[i].code == quit_char)
2672 break;
2675 else
2677 struct input_event e;
2678 char buf[3];
2679 nread = read (fileno (stdin), buf, 1);
2680 EVENT_INIT (e);
2682 /* Scan the chars for C-g and store them in kbd_buffer. */
2683 e.kind = ASCII_KEYSTROKE_EVENT;
2684 e.frame_or_window = selected_frame;
2685 e.modifiers = 0;
2686 for (i = 0; i < nread; i++)
2688 /* Convert chars > 0177 to meta events if desired.
2689 We do this under the same conditions that read_avail_input does. */
2690 if (read_socket_hook == 0)
2692 /* If the user says she has a meta key, then believe her. */
2693 if (meta_key == 1 && (buf[i] & 0x80))
2694 e.modifiers = meta_modifier;
2695 if (meta_key != 2)
2696 buf[i] &= ~0x80;
2699 XSETINT (e.code, buf[i]);
2700 kbd_buffer_store_event (&e);
2701 /* Don't look at input that follows a C-g too closely.
2702 This reduces lossage due to autorepeat on C-g. */
2703 if (buf[i] == quit_char)
2704 break;
2709 #endif /* not HAVE_SELECT */
2710 #endif /* not VMS */
2711 #endif /* not MSDOS */
2713 #ifdef BSD4_1
2714 void
2715 init_sigio (fd)
2716 int fd;
2718 if (noninteractive)
2719 return;
2720 lmode = LINTRUP | lmode;
2721 ioctl (fd, TIOCLSET, &lmode);
2724 void
2725 reset_sigio (fd)
2726 int fd;
2728 if (noninteractive)
2729 return;
2730 lmode = ~LINTRUP & lmode;
2731 ioctl (fd, TIOCLSET, &lmode);
2734 void
2735 request_sigio ()
2737 sigrelse (SIGTINT);
2739 interrupts_deferred = 0;
2742 void
2743 unrequest_sigio ()
2745 sighold (SIGTINT);
2747 interrupts_deferred = 1;
2750 /* still inside #ifdef BSD4_1 */
2751 #ifdef subprocesses
2753 int sigheld; /* Mask of held signals */
2755 void
2756 sigholdx (signum)
2757 int signum;
2759 sigheld |= sigbit (signum);
2760 sighold (signum);
2763 void
2764 sigisheld (signum)
2765 int signum;
2767 sigheld |= sigbit (signum);
2770 void
2771 sigunhold (signum)
2772 int signum;
2774 sigheld &= ~sigbit (signum);
2775 sigrelse (signum);
2778 void
2779 sigfree () /* Free all held signals */
2781 int i;
2782 for (i = 0; i < NSIG; i++)
2783 if (sigheld & sigbit (i))
2784 sigrelse (i);
2785 sigheld = 0;
2789 sigbit (i)
2791 return 1 << (i - 1);
2793 #endif /* subprocesses */
2794 #endif /* BSD4_1 */
2796 /* POSIX signals support - DJB */
2797 /* Anyone with POSIX signals should have ANSI C declarations */
2799 #ifdef POSIX_SIGNALS
2801 sigset_t empty_mask, full_mask;
2803 signal_handler_t
2804 sys_signal (int signal_number, signal_handler_t action)
2806 struct sigaction new_action, old_action;
2807 sigemptyset (&new_action.sa_mask);
2808 new_action.sa_handler = action;
2809 #if defined (SA_RESTART) && ! defined (BROKEN_SA_RESTART)
2810 /* Emacs mostly works better with restartable system services. If this
2811 flag exists, we probably want to turn it on here.
2812 However, on some systems this resets the timeout of `select'
2813 which means that `select' never finishes if it keeps getting signals.
2814 BROKEN_SA_RESTART is defined on those systems. */
2815 new_action.sa_flags = SA_RESTART;
2816 #else
2817 new_action.sa_flags = 0;
2818 #endif
2819 sigaction (signal_number, &new_action, &old_action);
2820 return (old_action.sa_handler);
2823 #ifndef __GNUC__
2824 /* If we're compiling with GCC, we don't need this function, since it
2825 can be written as a macro. */
2826 sigset_t
2827 sys_sigmask (int sig)
2829 sigset_t mask;
2830 sigemptyset (&mask);
2831 sigaddset (&mask, sig);
2832 return mask;
2834 #endif
2836 /* I'd like to have these guys return pointers to the mask storage in here,
2837 but there'd be trouble if the code was saving multiple masks. I'll be
2838 safe and pass the structure. It normally won't be more than 2 bytes
2839 anyhow. - DJB */
2841 sigset_t
2842 sys_sigblock (sigset_t new_mask)
2844 sigset_t old_mask;
2845 sigprocmask (SIG_BLOCK, &new_mask, &old_mask);
2846 return (old_mask);
2849 sigset_t
2850 sys_sigunblock (sigset_t new_mask)
2852 sigset_t old_mask;
2853 sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask);
2854 return (old_mask);
2857 sigset_t
2858 sys_sigsetmask (sigset_t new_mask)
2860 sigset_t old_mask;
2861 sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
2862 return (old_mask);
2865 #endif /* POSIX_SIGNALS */
2867 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2868 static char *my_sys_siglist[NSIG];
2869 # ifdef sys_siglist
2870 # undef sys_siglist
2871 # endif
2872 # define sys_siglist my_sys_siglist
2873 #endif
2875 void
2876 init_signals ()
2878 #ifdef POSIX_SIGNALS
2879 sigemptyset (&empty_mask);
2880 sigfillset (&full_mask);
2881 #endif
2883 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2884 if (! initialized)
2886 # ifdef SIGABRT
2887 sys_siglist[SIGABRT] = "Aborted";
2888 # endif
2889 # ifdef SIGAIO
2890 sys_siglist[SIGAIO] = "LAN I/O interrupt";
2891 # endif
2892 # ifdef SIGALRM
2893 sys_siglist[SIGALRM] = "Alarm clock";
2894 # endif
2895 # ifdef SIGBUS
2896 sys_siglist[SIGBUS] = "Bus error";
2897 # endif
2898 # ifdef SIGCLD
2899 sys_siglist[SIGCLD] = "Child status changed";
2900 # endif
2901 # ifdef SIGCHLD
2902 sys_siglist[SIGCHLD] = "Child status changed";
2903 # endif
2904 # ifdef SIGCONT
2905 sys_siglist[SIGCONT] = "Continued";
2906 # endif
2907 # ifdef SIGDANGER
2908 sys_siglist[SIGDANGER] = "Swap space dangerously low";
2909 # endif
2910 # ifdef SIGDGNOTIFY
2911 sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
2912 # endif
2913 # ifdef SIGEMT
2914 sys_siglist[SIGEMT] = "Emulation trap";
2915 # endif
2916 # ifdef SIGFPE
2917 sys_siglist[SIGFPE] = "Arithmetic exception";
2918 # endif
2919 # ifdef SIGFREEZE
2920 sys_siglist[SIGFREEZE] = "SIGFREEZE";
2921 # endif
2922 # ifdef SIGGRANT
2923 sys_siglist[SIGGRANT] = "Monitor mode granted";
2924 # endif
2925 # ifdef SIGHUP
2926 sys_siglist[SIGHUP] = "Hangup";
2927 # endif
2928 # ifdef SIGILL
2929 sys_siglist[SIGILL] = "Illegal instruction";
2930 # endif
2931 # ifdef SIGINT
2932 sys_siglist[SIGINT] = "Interrupt";
2933 # endif
2934 # ifdef SIGIO
2935 sys_siglist[SIGIO] = "I/O possible";
2936 # endif
2937 # ifdef SIGIOINT
2938 sys_siglist[SIGIOINT] = "I/O intervention required";
2939 # endif
2940 # ifdef SIGIOT
2941 sys_siglist[SIGIOT] = "IOT trap";
2942 # endif
2943 # ifdef SIGKILL
2944 sys_siglist[SIGKILL] = "Killed";
2945 # endif
2946 # ifdef SIGLOST
2947 sys_siglist[SIGLOST] = "Resource lost";
2948 # endif
2949 # ifdef SIGLWP
2950 sys_siglist[SIGLWP] = "SIGLWP";
2951 # endif
2952 # ifdef SIGMSG
2953 sys_siglist[SIGMSG] = "Monitor mode data available";
2954 # endif
2955 # ifdef SIGPHONE
2956 sys_siglist[SIGWIND] = "SIGPHONE";
2957 # endif
2958 # ifdef SIGPIPE
2959 sys_siglist[SIGPIPE] = "Broken pipe";
2960 # endif
2961 # ifdef SIGPOLL
2962 sys_siglist[SIGPOLL] = "Pollable event occurred";
2963 # endif
2964 # ifdef SIGPROF
2965 sys_siglist[SIGPROF] = "Profiling timer expired";
2966 # endif
2967 # ifdef SIGPTY
2968 sys_siglist[SIGPTY] = "PTY I/O interrupt";
2969 # endif
2970 # ifdef SIGPWR
2971 sys_siglist[SIGPWR] = "Power-fail restart";
2972 # endif
2973 # ifdef SIGQUIT
2974 sys_siglist[SIGQUIT] = "Quit";
2975 # endif
2976 # ifdef SIGRETRACT
2977 sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode";
2978 # endif
2979 # ifdef SIGSAK
2980 sys_siglist[SIGSAK] = "Secure attention";
2981 # endif
2982 # ifdef SIGSEGV
2983 sys_siglist[SIGSEGV] = "Segmentation violation";
2984 # endif
2985 # ifdef SIGSOUND
2986 sys_siglist[SIGSOUND] = "Sound completed";
2987 # endif
2988 # ifdef SIGSTOP
2989 sys_siglist[SIGSTOP] = "Stopped (signal)";
2990 # endif
2991 # ifdef SIGSTP
2992 sys_siglist[SIGSTP] = "Stopped (user)";
2993 # endif
2994 # ifdef SIGSYS
2995 sys_siglist[SIGSYS] = "Bad argument to system call";
2996 # endif
2997 # ifdef SIGTERM
2998 sys_siglist[SIGTERM] = "Terminated";
2999 # endif
3000 # ifdef SIGTHAW
3001 sys_siglist[SIGTHAW] = "SIGTHAW";
3002 # endif
3003 # ifdef SIGTRAP
3004 sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
3005 # endif
3006 # ifdef SIGTSTP
3007 sys_siglist[SIGTSTP] = "Stopped (user)";
3008 # endif
3009 # ifdef SIGTTIN
3010 sys_siglist[SIGTTIN] = "Stopped (tty input)";
3011 # endif
3012 # ifdef SIGTTOU
3013 sys_siglist[SIGTTOU] = "Stopped (tty output)";
3014 # endif
3015 # ifdef SIGURG
3016 sys_siglist[SIGURG] = "Urgent I/O condition";
3017 # endif
3018 # ifdef SIGUSR1
3019 sys_siglist[SIGUSR1] = "User defined signal 1";
3020 # endif
3021 # ifdef SIGUSR2
3022 sys_siglist[SIGUSR2] = "User defined signal 2";
3023 # endif
3024 # ifdef SIGVTALRM
3025 sys_siglist[SIGVTALRM] = "Virtual timer expired";
3026 # endif
3027 # ifdef SIGWAITING
3028 sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
3029 # endif
3030 # ifdef SIGWINCH
3031 sys_siglist[SIGWINCH] = "Window size changed";
3032 # endif
3033 # ifdef SIGWIND
3034 sys_siglist[SIGWIND] = "SIGWIND";
3035 # endif
3036 # ifdef SIGXCPU
3037 sys_siglist[SIGXCPU] = "CPU time limit exceeded";
3038 # endif
3039 # ifdef SIGXFSZ
3040 sys_siglist[SIGXFSZ] = "File size limit exceeded";
3041 # endif
3043 #endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
3046 #ifndef HAVE_RANDOM
3047 #ifdef random
3048 #define HAVE_RANDOM
3049 #endif
3050 #endif
3052 /* Figure out how many bits the system's random number generator uses.
3053 `random' and `lrand48' are assumed to return 31 usable bits.
3054 BSD `rand' returns a 31 bit value but the low order bits are unusable;
3055 so we'll shift it and treat it like the 15-bit USG `rand'. */
3057 #ifndef RAND_BITS
3058 # ifdef HAVE_RANDOM
3059 # define RAND_BITS 31
3060 # else /* !HAVE_RANDOM */
3061 # ifdef HAVE_LRAND48
3062 # define RAND_BITS 31
3063 # define random lrand48
3064 # else /* !HAVE_LRAND48 */
3065 # define RAND_BITS 15
3066 # if RAND_MAX == 32767
3067 # define random rand
3068 # else /* RAND_MAX != 32767 */
3069 # if RAND_MAX == 2147483647
3070 # define random() (rand () >> 16)
3071 # else /* RAND_MAX != 2147483647 */
3072 # ifdef USG
3073 # define random rand
3074 # else
3075 # define random() (rand () >> 16)
3076 # endif /* !USG */
3077 # endif /* RAND_MAX != 2147483647 */
3078 # endif /* RAND_MAX != 32767 */
3079 # endif /* !HAVE_LRAND48 */
3080 # endif /* !HAVE_RANDOM */
3081 #endif /* !RAND_BITS */
3083 void
3084 seed_random (arg)
3085 long arg;
3087 #ifdef HAVE_RANDOM
3088 srandom ((unsigned int)arg);
3089 #else
3090 # ifdef HAVE_LRAND48
3091 srand48 (arg);
3092 # else
3093 srand ((unsigned int)arg);
3094 # endif
3095 #endif
3099 * Build a full Emacs-sized word out of whatever we've got.
3100 * This suffices even for a 64-bit architecture with a 15-bit rand.
3102 long
3103 get_random ()
3105 long val = random ();
3106 #if VALBITS > RAND_BITS
3107 val = (val << RAND_BITS) ^ random ();
3108 #if VALBITS > 2*RAND_BITS
3109 val = (val << RAND_BITS) ^ random ();
3110 #if VALBITS > 3*RAND_BITS
3111 val = (val << RAND_BITS) ^ random ();
3112 #if VALBITS > 4*RAND_BITS
3113 val = (val << RAND_BITS) ^ random ();
3114 #endif /* need at least 5 */
3115 #endif /* need at least 4 */
3116 #endif /* need at least 3 */
3117 #endif /* need at least 2 */
3118 return val & ((1L << VALBITS) - 1);
3121 #ifdef WRONG_NAME_INSQUE
3123 insque (q,p)
3124 caddr_t q,p;
3126 _insque (q,p);
3129 #endif
3131 #ifdef VMS
3133 #ifdef getenv
3134 /* If any place else asks for the TERM variable,
3135 allow it to be overridden with the EMACS_TERM variable
3136 before attempting to translate the logical name TERM. As a last
3137 resort, ask for VAX C's special idea of the TERM variable. */
3138 #undef getenv
3139 char *
3140 sys_getenv (name)
3141 char *name;
3143 register char *val;
3144 static char buf[256];
3145 static struct dsc$descriptor_s equiv
3146 = {sizeof (buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf};
3147 static struct dsc$descriptor_s d_name
3148 = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
3149 short eqlen;
3151 if (!strcmp (name, "TERM"))
3153 val = (char *) getenv ("EMACS_TERM");
3154 if (val)
3155 return val;
3158 d_name.dsc$w_length = strlen (name);
3159 d_name.dsc$a_pointer = name;
3160 if (LIB$SYS_TRNLOG (&d_name, &eqlen, &equiv) == 1)
3162 char *str = (char *) xmalloc (eqlen + 1);
3163 bcopy (buf, str, eqlen);
3164 str[eqlen] = '\0';
3165 /* This is a storage leak, but a pain to fix. With luck,
3166 no one will ever notice. */
3167 return str;
3169 return (char *) getenv (name);
3171 #endif /* getenv */
3173 #ifdef abort
3174 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
3175 to force a call on the debugger from within the image. */
3176 #undef abort
3177 sys_abort ()
3179 reset_all_sys_modes ();
3180 LIB$SIGNAL (SS$_DEBUG);
3182 #endif /* abort */
3183 #endif /* VMS */
3185 #ifdef VMS
3186 #ifdef LINK_CRTL_SHARE
3187 #ifdef SHARABLE_LIB_BUG
3188 /* Variables declared noshare and initialized in sharable libraries
3189 cannot be shared. The VMS linker incorrectly forces you to use a private
3190 version which is uninitialized... If not for this "feature", we
3191 could use the C library definition of sys_nerr and sys_errlist. */
3192 int sys_nerr = 35;
3193 char *sys_errlist[] =
3195 "error 0",
3196 "not owner",
3197 "no such file or directory",
3198 "no such process",
3199 "interrupted system call",
3200 "i/o error",
3201 "no such device or address",
3202 "argument list too long",
3203 "exec format error",
3204 "bad file number",
3205 "no child process",
3206 "no more processes",
3207 "not enough memory",
3208 "permission denied",
3209 "bad address",
3210 "block device required",
3211 "mount devices busy",
3212 "file exists",
3213 "cross-device link",
3214 "no such device",
3215 "not a directory",
3216 "is a directory",
3217 "invalid argument",
3218 "file table overflow",
3219 "too many open files",
3220 "not a typewriter",
3221 "text file busy",
3222 "file too big",
3223 "no space left on device",
3224 "illegal seek",
3225 "read-only file system",
3226 "too many links",
3227 "broken pipe",
3228 "math argument",
3229 "result too large",
3230 "I/O stream empty",
3231 "vax/vms specific error code nontranslatable error"
3233 #endif /* SHARABLE_LIB_BUG */
3234 #endif /* LINK_CRTL_SHARE */
3235 #endif /* VMS */
3237 #ifndef HAVE_STRERROR
3238 #ifndef WINDOWSNT
3239 char *
3240 strerror (errnum)
3241 int errnum;
3243 extern char *sys_errlist[];
3244 extern int sys_nerr;
3246 if (errnum >= 0 && errnum < sys_nerr)
3247 return sys_errlist[errnum];
3248 return (char *) "Unknown error";
3250 #endif /* not WINDOWSNT */
3251 #endif /* ! HAVE_STRERROR */
3254 emacs_open (path, oflag, mode)
3255 const char *path;
3256 int oflag, mode;
3258 register int rtnval;
3260 #ifdef BSD4_1
3261 if (oflag & O_CREAT)
3262 return creat (path, mode);
3263 #endif
3265 while ((rtnval = open (path, oflag, mode)) == -1
3266 && (errno == EINTR));
3267 return (rtnval);
3271 emacs_close (fd)
3272 int fd;
3274 int did_retry = 0;
3275 register int rtnval;
3277 while ((rtnval = close (fd)) == -1
3278 && (errno == EINTR))
3279 did_retry = 1;
3281 /* If close is interrupted SunOS 4.1 may or may not have closed the
3282 file descriptor. If it did the second close will fail with
3283 errno = EBADF. That means we have succeeded. */
3284 if (rtnval == -1 && did_retry && errno == EBADF)
3285 return 0;
3287 return rtnval;
3291 emacs_read (fildes, buf, nbyte)
3292 int fildes;
3293 char *buf;
3294 unsigned int nbyte;
3296 register int rtnval;
3298 while ((rtnval = read (fildes, buf, nbyte)) == -1
3299 && (errno == EINTR));
3300 return (rtnval);
3304 emacs_write (fildes, buf, nbyte)
3305 int fildes;
3306 const char *buf;
3307 unsigned int nbyte;
3309 register int rtnval, bytes_written;
3311 bytes_written = 0;
3313 while (nbyte > 0)
3315 rtnval = write (fildes, buf, nbyte);
3317 if (rtnval == -1)
3319 if (errno == EINTR)
3320 continue;
3321 else
3322 return (bytes_written ? bytes_written : -1);
3325 buf += rtnval;
3326 nbyte -= rtnval;
3327 bytes_written += rtnval;
3329 return (bytes_written);
3332 #ifdef USG
3334 * All of the following are for USG.
3336 * On USG systems the system calls are INTERRUPTIBLE by signals
3337 * that the user program has elected to catch. Thus the system call
3338 * must be retried in these cases. To handle this without massive
3339 * changes in the source code, we remap the standard system call names
3340 * to names for our own functions in sysdep.c that do the system call
3341 * with retries. Actually, for portability reasons, it is good
3342 * programming practice, as this example shows, to limit all actual
3343 * system calls to a single occurrence in the source. Sure, this
3344 * adds an extra level of function call overhead but it is almost
3345 * always negligible. Fred Fish, Unisoft Systems Inc.
3349 * Warning, this function may not duplicate 4.2 action properly
3350 * under error conditions.
3353 #ifndef MAXPATHLEN
3354 /* In 4.1, param.h fails to define this. */
3355 #define MAXPATHLEN 1024
3356 #endif
3358 #ifndef HAVE_GETWD
3360 char *
3361 getwd (pathname)
3362 char *pathname;
3364 char *npath, *spath;
3365 extern char *getcwd ();
3367 BLOCK_INPUT; /* getcwd uses malloc */
3368 spath = npath = getcwd ((char *) 0, MAXPATHLEN);
3369 if (spath == 0)
3371 UNBLOCK_INPUT;
3372 return spath;
3374 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3375 up to first slash. Should be harmless on other systems. */
3376 while (*npath && *npath != '/')
3377 npath++;
3378 strcpy (pathname, npath);
3379 free (spath); /* getcwd uses malloc */
3380 UNBLOCK_INPUT;
3381 return pathname;
3384 #endif /* HAVE_GETWD */
3387 * Emulate rename using unlink/link. Note that this is
3388 * only partially correct. Also, doesn't enforce restriction
3389 * that files be of same type (regular->regular, dir->dir, etc).
3392 #ifndef HAVE_RENAME
3394 rename (from, to)
3395 const char *from;
3396 const char *to;
3398 if (access (from, 0) == 0)
3400 unlink (to);
3401 if (link (from, to) == 0)
3402 if (unlink (from) == 0)
3403 return (0);
3405 return (-1);
3408 #endif
3411 #ifdef HPUX
3412 #ifndef HAVE_PERROR
3414 /* HPUX curses library references perror, but as far as we know
3415 it won't be called. Anyway this definition will do for now. */
3417 perror ()
3421 #endif /* not HAVE_PERROR */
3422 #endif /* HPUX */
3424 #ifndef HAVE_DUP2
3427 * Emulate BSD dup2. First close newd if it already exists.
3428 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3429 * until we are, then close the unsuccessful ones.
3432 dup2 (oldd, newd)
3433 int oldd;
3434 int newd;
3436 register int fd, ret;
3438 emacs_close (newd);
3440 #ifdef F_DUPFD
3441 return fcntl (oldd, F_DUPFD, newd);
3442 #else
3443 fd = dup (old);
3444 if (fd == -1)
3445 return -1;
3446 if (fd == new)
3447 return new;
3448 ret = dup2 (old,new);
3449 emacs_close (fd);
3450 return ret;
3451 #endif
3454 #endif /* not HAVE_DUP2 */
3457 * Gettimeofday. Simulate as much as possible. Only accurate
3458 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3459 * Only needed when subprocesses are defined.
3462 #ifdef subprocesses
3463 #ifndef VMS
3464 #ifndef HAVE_GETTIMEOFDAY
3465 #ifdef HAVE_TIMEVAL
3467 /* ARGSUSED */
3469 gettimeofday (tp, tzp)
3470 struct timeval *tp;
3471 struct timezone *tzp;
3473 extern long time ();
3475 tp->tv_sec = time ((long *)0);
3476 tp->tv_usec = 0;
3477 if (tzp != 0)
3478 tzp->tz_minuteswest = -1;
3479 return 0;
3482 #endif
3483 #endif
3484 #endif
3485 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3488 * This function will go away as soon as all the stubs fixed. (fnf)
3491 void
3492 croak (badfunc)
3493 char *badfunc;
3495 printf ("%s not yet implemented\r\n", badfunc);
3496 reset_all_sys_modes ();
3497 exit (1);
3500 #endif /* USG */
3502 /* Directory routines for systems that don't have them. */
3504 #ifdef SYSV_SYSTEM_DIR
3506 #include <dirent.h>
3508 #if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
3511 closedir (dirp)
3512 register DIR *dirp; /* stream from opendir */
3514 int rtnval;
3516 rtnval = emacs_close (dirp->dd_fd);
3518 /* Some systems (like Solaris) allocate the buffer and the DIR all
3519 in one block. Why in the world are we freeing this ourselves
3520 anyway? */
3521 #if ! (defined (sun) && defined (USG5_4))
3522 xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
3523 #endif
3524 xfree ((char *) dirp);
3526 return rtnval;
3528 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3529 #endif /* SYSV_SYSTEM_DIR */
3531 #ifdef NONSYSTEM_DIR_LIBRARY
3533 DIR *
3534 opendir (filename)
3535 char *filename; /* name of directory */
3537 register DIR *dirp; /* -> malloc'ed storage */
3538 register int fd; /* file descriptor for read */
3539 struct stat sbuf; /* result of fstat */
3541 fd = emacs_open (filename, O_RDONLY, 0);
3542 if (fd < 0)
3543 return 0;
3545 BLOCK_INPUT;
3546 if (fstat (fd, &sbuf) < 0
3547 || (sbuf.st_mode & S_IFMT) != S_IFDIR
3548 || (dirp = (DIR *) xmalloc (sizeof (DIR))) == 0)
3550 emacs_close (fd);
3551 UNBLOCK_INPUT;
3552 return 0; /* bad luck today */
3554 UNBLOCK_INPUT;
3556 dirp->dd_fd = fd;
3557 dirp->dd_loc = dirp->dd_size = 0; /* refill needed */
3559 return dirp;
3562 void
3563 closedir (dirp)
3564 register DIR *dirp; /* stream from opendir */
3566 emacs_close (dirp->dd_fd);
3567 xfree ((char *) dirp);
3571 #ifndef VMS
3572 #define DIRSIZ 14
3573 struct olddir
3575 ino_t od_ino; /* inode */
3576 char od_name[DIRSIZ]; /* filename */
3578 #endif /* not VMS */
3580 struct direct dir_static; /* simulated directory contents */
3582 /* ARGUSED */
3583 struct direct *
3584 readdir (dirp)
3585 register DIR *dirp; /* stream from opendir */
3587 #ifndef VMS
3588 register struct olddir *dp; /* -> directory data */
3589 #else /* VMS */
3590 register struct dir$_name *dp; /* -> directory data */
3591 register struct dir$_version *dv; /* -> version data */
3592 #endif /* VMS */
3594 for (; ;)
3596 if (dirp->dd_loc >= dirp->dd_size)
3597 dirp->dd_loc = dirp->dd_size = 0;
3599 if (dirp->dd_size == 0 /* refill buffer */
3600 && (dirp->dd_size = emacs_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3601 return 0;
3603 #ifndef VMS
3604 dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
3605 dirp->dd_loc += sizeof (struct olddir);
3607 if (dp->od_ino != 0) /* not deleted entry */
3609 dir_static.d_ino = dp->od_ino;
3610 strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
3611 dir_static.d_name[DIRSIZ] = '\0';
3612 dir_static.d_namlen = strlen (dir_static.d_name);
3613 dir_static.d_reclen = sizeof (struct direct)
3614 - MAXNAMLEN + 3
3615 + dir_static.d_namlen - dir_static.d_namlen % 4;
3616 return &dir_static; /* -> simulated structure */
3618 #else /* VMS */
3619 dp = (struct dir$_name *) dirp->dd_buf;
3620 if (dirp->dd_loc == 0)
3621 dirp->dd_loc = (dp->dir$b_namecount&1) ? dp->dir$b_namecount + 1
3622 : dp->dir$b_namecount;
3623 dv = (struct dir$_version *)&dp->dir$t_name[dirp->dd_loc];
3624 dir_static.d_ino = dv->dir$w_fid_num;
3625 dir_static.d_namlen = dp->dir$b_namecount;
3626 dir_static.d_reclen = sizeof (struct direct)
3627 - MAXNAMLEN + 3
3628 + dir_static.d_namlen - dir_static.d_namlen % 4;
3629 strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
3630 dir_static.d_name[dir_static.d_namlen] = '\0';
3631 dirp->dd_loc = dirp->dd_size; /* only one record at a time */
3632 return &dir_static;
3633 #endif /* VMS */
3637 #ifdef VMS
3638 /* readdirver is just like readdir except it returns all versions of a file
3639 as separate entries. */
3641 /* ARGUSED */
3642 struct direct *
3643 readdirver (dirp)
3644 register DIR *dirp; /* stream from opendir */
3646 register struct dir$_name *dp; /* -> directory data */
3647 register struct dir$_version *dv; /* -> version data */
3649 if (dirp->dd_loc >= dirp->dd_size - sizeof (struct dir$_name))
3650 dirp->dd_loc = dirp->dd_size = 0;
3652 if (dirp->dd_size == 0 /* refill buffer */
3653 && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3654 return 0;
3656 dp = (struct dir$_name *) dirp->dd_buf;
3657 if (dirp->dd_loc == 0)
3658 dirp->dd_loc = (dp->dir$b_namecount & 1) ? dp->dir$b_namecount + 1
3659 : dp->dir$b_namecount;
3660 dv = (struct dir$_version *) &dp->dir$t_name[dirp->dd_loc];
3661 strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
3662 sprintf (&dir_static.d_name[dp->dir$b_namecount], ";%d", dv->dir$w_version);
3663 dir_static.d_namlen = strlen (dir_static.d_name);
3664 dir_static.d_ino = dv->dir$w_fid_num;
3665 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3
3666 + dir_static.d_namlen - dir_static.d_namlen % 4;
3667 dirp->dd_loc = ((char *) (++dv) - dp->dir$t_name);
3668 return &dir_static;
3671 #endif /* VMS */
3673 #endif /* NONSYSTEM_DIR_LIBRARY */
3677 set_file_times (filename, atime, mtime)
3678 const char *filename;
3679 EMACS_TIME atime, mtime;
3681 #ifdef HAVE_UTIMES
3682 struct timeval tv[2];
3683 tv[0] = atime;
3684 tv[1] = mtime;
3685 return utimes (filename, tv);
3686 #else /* not HAVE_UTIMES */
3687 struct utimbuf utb;
3688 utb.actime = EMACS_SECS (atime);
3689 utb.modtime = EMACS_SECS (mtime);
3690 return utime (filename, &utb);
3691 #endif /* not HAVE_UTIMES */
3694 /* mkdir and rmdir functions, for systems which don't have them. */
3696 #ifndef HAVE_MKDIR
3698 * Written by Robert Rother, Mariah Corporation, August 1985.
3700 * If you want it, it's yours. All I ask in return is that if you
3701 * figure out how to do this in a Bourne Shell script you send me
3702 * a copy.
3703 * sdcsvax!rmr or rmr@uscd
3705 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3706 * subroutine. 11Mar86; hoptoad!gnu
3708 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3709 * subroutine didn't return EEXIST. It does now.
3713 * Make a directory.
3715 #ifdef MKDIR_PROTOTYPE
3716 MKDIR_PROTOTYPE
3717 #else
3719 mkdir (dpath, dmode)
3720 char *dpath;
3721 int dmode;
3722 #endif
3724 int cpid, status, fd;
3725 struct stat statbuf;
3727 if (stat (dpath, &statbuf) == 0)
3729 errno = EEXIST; /* Stat worked, so it already exists */
3730 return -1;
3733 /* If stat fails for a reason other than non-existence, return error */
3734 if (errno != ENOENT)
3735 return -1;
3737 synch_process_alive = 1;
3738 switch (cpid = fork ())
3741 case -1: /* Error in fork */
3742 return (-1); /* Errno is set already */
3744 case 0: /* Child process */
3746 * Cheap hack to set mode of new directory. Since this
3747 * child process is going away anyway, we zap its umask.
3748 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3749 * directory. Does anybody care?
3751 status = umask (0); /* Get current umask */
3752 status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
3753 fd = emacs_open ("/dev/null", O_RDWR, 0);
3754 if (fd >= 0)
3756 dup2 (fd, 0);
3757 dup2 (fd, 1);
3758 dup2 (fd, 2);
3760 execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
3761 _exit (-1); /* Can't exec /bin/mkdir */
3763 default: /* Parent process */
3764 wait_for_termination (cpid);
3767 if (synch_process_death != 0 || synch_process_retcode != 0)
3769 errno = EIO; /* We don't know why, but */
3770 return -1; /* /bin/mkdir failed */
3773 return 0;
3775 #endif /* not HAVE_MKDIR */
3777 #ifndef HAVE_RMDIR
3779 rmdir (dpath)
3780 char *dpath;
3782 int cpid, status, fd;
3783 struct stat statbuf;
3785 if (stat (dpath, &statbuf) != 0)
3787 /* Stat just set errno. We don't have to */
3788 return -1;
3791 synch_process_alive = 1;
3792 switch (cpid = fork ())
3795 case -1: /* Error in fork */
3796 return (-1); /* Errno is set already */
3798 case 0: /* Child process */
3799 fd = emacs_open ("/dev/null", O_RDWR, 0);
3800 if (fd >= 0)
3802 dup2 (fd, 0);
3803 dup2 (fd, 1);
3804 dup2 (fd, 2);
3806 execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
3807 _exit (-1); /* Can't exec /bin/rmdir */
3809 default: /* Parent process */
3810 wait_for_termination (cpid);
3813 if (synch_process_death != 0 || synch_process_retcode != 0)
3815 errno = EIO; /* We don't know why, but */
3816 return -1; /* /bin/rmdir failed */
3819 return 0;
3821 #endif /* !HAVE_RMDIR */
3825 /* Functions for VMS */
3826 #ifdef VMS
3827 #include "vms-pwd.h"
3828 #include <acldef.h>
3829 #include <chpdef.h>
3830 #include <jpidef.h>
3832 /* Return as a string the VMS error string pertaining to STATUS.
3833 Reuses the same static buffer each time it is called. */
3835 char *
3836 vmserrstr (status)
3837 int status; /* VMS status code */
3839 int bufadr[2];
3840 short len;
3841 static char buf[257];
3843 bufadr[0] = sizeof buf - 1;
3844 bufadr[1] = (int) buf;
3845 if (! (SYS$GETMSG (status, &len, bufadr, 0x1, 0) & 1))
3846 return "untranslatable VMS error status";
3847 buf[len] = '\0';
3848 return buf;
3851 #ifdef access
3852 #undef access
3854 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3855 * not work correctly. (It also doesn't work well in version 2.3.)
3858 #ifdef VMS4_4
3860 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3861 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3863 typedef union {
3864 struct {
3865 unsigned short s_buflen;
3866 unsigned short s_code;
3867 char *s_bufadr;
3868 unsigned short *s_retlenadr;
3869 } s;
3870 int end;
3871 } item;
3872 #define buflen s.s_buflen
3873 #define code s.s_code
3874 #define bufadr s.s_bufadr
3875 #define retlenadr s.s_retlenadr
3877 #define R_OK 4 /* test for read permission */
3878 #define W_OK 2 /* test for write permission */
3879 #define X_OK 1 /* test for execute (search) permission */
3880 #define F_OK 0 /* test for presence of file */
3883 sys_access (path, mode)
3884 char *path;
3885 int mode;
3887 static char *user = NULL;
3888 char dir_fn[512];
3890 /* translate possible directory spec into .DIR file name, so brain-dead
3891 * access can treat the directory like a file. */
3892 if (directory_file_name (path, dir_fn))
3893 path = dir_fn;
3895 if (mode == F_OK)
3896 return access (path, mode);
3897 if (user == NULL && (user = (char *) getenv ("USER")) == NULL)
3898 return -1;
3900 int stat;
3901 int flags;
3902 int acces;
3903 unsigned short int dummy;
3904 item itemlst[3];
3905 static int constant = ACL$C_FILE;
3906 DESCRIPTOR (path_desc, path);
3907 DESCRIPTOR (user_desc, user);
3909 flags = 0;
3910 acces = 0;
3911 if ((mode & X_OK) && ((stat = access (path, mode)) < 0 || mode == X_OK))
3912 return stat;
3913 if (mode & R_OK)
3914 acces |= CHP$M_READ;
3915 if (mode & W_OK)
3916 acces |= CHP$M_WRITE;
3917 itemlst[0].buflen = sizeof (int);
3918 itemlst[0].code = CHP$_FLAGS;
3919 itemlst[0].bufadr = (char *) &flags;
3920 itemlst[0].retlenadr = &dummy;
3921 itemlst[1].buflen = sizeof (int);
3922 itemlst[1].code = CHP$_ACCESS;
3923 itemlst[1].bufadr = (char *) &acces;
3924 itemlst[1].retlenadr = &dummy;
3925 itemlst[2].end = CHP$_END;
3926 stat = SYS$CHECK_ACCESS (&constant, &path_desc, &user_desc, itemlst);
3927 return stat == SS$_NORMAL ? 0 : -1;
3931 #else /* not VMS4_4 */
3933 #include <prvdef.h>
3934 #define ACE$M_WRITE 2
3935 #define ACE$C_KEYID 1
3937 static unsigned short memid, grpid;
3938 static unsigned int uic;
3940 /* Called from init_sys_modes, so it happens not very often
3941 but at least each time Emacs is loaded. */
3942 void
3943 sys_access_reinit ()
3945 uic = 0;
3949 sys_access (filename, type)
3950 char * filename;
3951 int type;
3953 struct FAB fab;
3954 struct XABPRO xab;
3955 int status, size, i, typecode, acl_controlled;
3956 unsigned int *aclptr, *aclend, aclbuf[60];
3957 union prvdef prvmask;
3959 /* Get UIC and GRP values for protection checking. */
3960 if (uic == 0)
3962 status = LIB$GETJPI (&JPI$_UIC, 0, 0, &uic, 0, 0);
3963 if (! (status & 1))
3964 return -1;
3965 memid = uic & 0xFFFF;
3966 grpid = uic >> 16;
3969 if (type != 2) /* not checking write access */
3970 return access (filename, type);
3972 /* Check write protection. */
3974 #define CHECKPRIV(bit) (prvmask.bit)
3975 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3977 /* Find privilege bits */
3978 status = SYS$SETPRV (0, 0, 0, prvmask);
3979 if (! (status & 1))
3980 error ("Unable to find privileges: %s", vmserrstr (status));
3981 if (CHECKPRIV (PRV$V_BYPASS))
3982 return 0; /* BYPASS enabled */
3983 fab = cc$rms_fab;
3984 fab.fab$b_fac = FAB$M_GET;
3985 fab.fab$l_fna = filename;
3986 fab.fab$b_fns = strlen (filename);
3987 fab.fab$l_xab = &xab;
3988 xab = cc$rms_xabpro;
3989 xab.xab$l_aclbuf = aclbuf;
3990 xab.xab$w_aclsiz = sizeof (aclbuf);
3991 status = SYS$OPEN (&fab, 0, 0);
3992 if (! (status & 1))
3993 return -1;
3994 SYS$CLOSE (&fab, 0, 0);
3995 /* Check system access */
3996 if (CHECKPRIV (PRV$V_SYSPRV) && WRITABLE (XAB$V_SYS))
3997 return 0;
3998 /* Check ACL entries, if any */
3999 acl_controlled = 0;
4000 if (xab.xab$w_acllen > 0)
4002 aclptr = aclbuf;
4003 aclend = &aclbuf[xab.xab$w_acllen / 4];
4004 while (*aclptr && aclptr < aclend)
4006 size = (*aclptr & 0xff) / 4;
4007 typecode = (*aclptr >> 8) & 0xff;
4008 if (typecode == ACE$C_KEYID)
4009 for (i = size - 1; i > 1; i--)
4010 if (aclptr[i] == uic)
4012 acl_controlled = 1;
4013 if (aclptr[1] & ACE$M_WRITE)
4014 return 0; /* Write access through ACL */
4016 aclptr = &aclptr[size];
4018 if (acl_controlled) /* ACL specified, prohibits write access */
4019 return -1;
4021 /* No ACL entries specified, check normal protection */
4022 if (WRITABLE (XAB$V_WLD)) /* World writable */
4023 return 0;
4024 if (WRITABLE (XAB$V_GRP) &&
4025 (unsigned short) (xab.xab$l_uic >> 16) == grpid)
4026 return 0; /* Group writable */
4027 if (WRITABLE (XAB$V_OWN) &&
4028 (xab.xab$l_uic & 0xFFFF) == memid)
4029 return 0; /* Owner writable */
4031 return -1; /* Not writable */
4033 #endif /* not VMS4_4 */
4034 #endif /* access */
4036 static char vtbuf[NAM$C_MAXRSS+1];
4038 /* translate a vms file spec to a unix path */
4039 char *
4040 sys_translate_vms (vfile)
4041 char * vfile;
4043 char * p;
4044 char * targ;
4046 if (!vfile)
4047 return 0;
4049 targ = vtbuf;
4051 /* leading device or logical name is a root directory */
4052 if (p = strchr (vfile, ':'))
4054 *targ++ = '/';
4055 while (vfile < p)
4056 *targ++ = *vfile++;
4057 vfile++;
4058 *targ++ = '/';
4060 p = vfile;
4061 if (*p == '[' || *p == '<')
4063 while (*++vfile != *p + 2)
4064 switch (*vfile)
4066 case '.':
4067 if (vfile[-1] == *p)
4068 *targ++ = '.';
4069 *targ++ = '/';
4070 break;
4072 case '-':
4073 *targ++ = '.';
4074 *targ++ = '.';
4075 break;
4077 default:
4078 *targ++ = *vfile;
4079 break;
4081 vfile++;
4082 *targ++ = '/';
4084 while (*vfile)
4085 *targ++ = *vfile++;
4087 return vtbuf;
4090 static char utbuf[NAM$C_MAXRSS+1];
4092 /* translate a unix path to a VMS file spec */
4093 char *
4094 sys_translate_unix (ufile)
4095 char * ufile;
4097 int slash_seen = 0;
4098 char *p;
4099 char * targ;
4101 if (!ufile)
4102 return 0;
4104 targ = utbuf;
4106 if (*ufile == '/')
4108 ufile++;
4111 while (*ufile)
4113 switch (*ufile)
4115 case '/':
4116 if (slash_seen)
4117 if (index (&ufile[1], '/'))
4118 *targ++ = '.';
4119 else
4120 *targ++ = ']';
4121 else
4123 *targ++ = ':';
4124 if (index (&ufile[1], '/'))
4125 *targ++ = '[';
4126 slash_seen = 1;
4128 break;
4130 case '.':
4131 if (strncmp (ufile, "./", 2) == 0)
4133 if (!slash_seen)
4135 *targ++ = '[';
4136 slash_seen = 1;
4138 ufile++; /* skip the dot */
4139 if (index (&ufile[1], '/'))
4140 *targ++ = '.';
4141 else
4142 *targ++ = ']';
4144 else if (strncmp (ufile, "../", 3) == 0)
4146 if (!slash_seen)
4148 *targ++ = '[';
4149 slash_seen = 1;
4151 *targ++ = '-';
4152 ufile += 2; /* skip the dots */
4153 if (index (&ufile[1], '/'))
4154 *targ++ = '.';
4155 else
4156 *targ++ = ']';
4158 else
4159 *targ++ = *ufile;
4160 break;
4162 default:
4163 *targ++ = *ufile;
4164 break;
4166 ufile++;
4168 *targ = '\0';
4170 return utbuf;
4173 char *
4174 getwd (pathname)
4175 char *pathname;
4177 char *ptr, *val;
4178 extern char *getcwd ();
4180 #define MAXPATHLEN 1024
4182 ptr = xmalloc (MAXPATHLEN);
4183 val = getcwd (ptr, MAXPATHLEN);
4184 if (val == 0)
4186 xfree (ptr);
4187 return val;
4189 strcpy (pathname, ptr);
4190 xfree (ptr);
4192 return pathname;
4196 getppid ()
4198 long item_code = JPI$_OWNER;
4199 unsigned long parent_id;
4200 int status;
4202 if (((status = LIB$GETJPI (&item_code, 0, 0, &parent_id)) & 1) == 0)
4204 errno = EVMSERR;
4205 vaxc$errno = status;
4206 return -1;
4208 return parent_id;
4211 #undef getuid
4212 unsigned
4213 sys_getuid ()
4215 return (getgid () << 16) | getuid ();
4218 #undef read
4220 sys_read (fildes, buf, nbyte)
4221 int fildes;
4222 char *buf;
4223 unsigned int nbyte;
4225 return read (fildes, buf, (nbyte < MAXIOSIZE ? nbyte : MAXIOSIZE));
4228 #if 0
4230 sys_write (fildes, buf, nbyte)
4231 int fildes;
4232 char *buf;
4233 unsigned int nbyte;
4235 register int nwrote, rtnval = 0;
4237 while (nbyte > MAXIOSIZE && (nwrote = write (fildes, buf, MAXIOSIZE)) > 0) {
4238 nbyte -= nwrote;
4239 buf += nwrote;
4240 rtnval += nwrote;
4242 if (nwrote < 0)
4243 return rtnval ? rtnval : -1;
4244 if ((nwrote = write (fildes, buf, nbyte)) < 0)
4245 return rtnval ? rtnval : -1;
4246 return (rtnval + nwrote);
4248 #endif /* 0 */
4251 * VAX/VMS VAX C RTL really loses. It insists that records
4252 * end with a newline (carriage return) character, and if they
4253 * don't it adds one (nice of it isn't it!)
4255 * Thus we do this stupidity below.
4258 #undef write
4260 sys_write (fildes, buf, nbytes)
4261 int fildes;
4262 char *buf;
4263 unsigned int nbytes;
4265 register char *p;
4266 register char *e;
4267 int sum = 0;
4268 struct stat st;
4270 fstat (fildes, &st);
4271 p = buf;
4272 while (nbytes > 0)
4274 int len, retval;
4276 /* Handle fixed-length files with carriage control. */
4277 if (st.st_fab_rfm == FAB$C_FIX
4278 && ((st.st_fab_rat & (FAB$M_FTN | FAB$M_CR)) != 0))
4280 len = st.st_fab_mrs;
4281 retval = write (fildes, p, min (len, nbytes));
4282 if (retval != len)
4283 return -1;
4284 retval++; /* This skips the implied carriage control */
4286 else
4288 e = p + min (MAXIOSIZE, nbytes) - 1;
4289 while (*e != '\n' && e > p) e--;
4290 if (p == e) /* Ok.. so here we add a newline... sigh. */
4291 e = p + min (MAXIOSIZE, nbytes) - 1;
4292 len = e + 1 - p;
4293 retval = write (fildes, p, len);
4294 if (retval != len)
4295 return -1;
4297 p += retval;
4298 sum += retval;
4299 nbytes -= retval;
4301 return sum;
4304 /* Create file NEW copying its attributes from file OLD. If
4305 OLD is 0 or does not exist, create based on the value of
4306 vms_stmlf_recfm. */
4308 /* Protection value the file should ultimately have.
4309 Set by create_copy_attrs, and use by rename_sansversions. */
4310 static unsigned short int fab_final_pro;
4313 creat_copy_attrs (old, new)
4314 char *old, *new;
4316 struct FAB fab = cc$rms_fab;
4317 struct XABPRO xabpro;
4318 char aclbuf[256]; /* Choice of size is arbitrary. See below. */
4319 extern int vms_stmlf_recfm;
4321 if (old)
4323 fab.fab$b_fac = FAB$M_GET;
4324 fab.fab$l_fna = old;
4325 fab.fab$b_fns = strlen (old);
4326 fab.fab$l_xab = (char *) &xabpro;
4327 xabpro = cc$rms_xabpro;
4328 xabpro.xab$l_aclbuf = aclbuf;
4329 xabpro.xab$w_aclsiz = sizeof aclbuf;
4330 /* Call $OPEN to fill in the fab & xabpro fields. */
4331 if (SYS$OPEN (&fab, 0, 0) & 1)
4333 SYS$CLOSE (&fab, 0, 0);
4334 fab.fab$l_alq = 0; /* zero the allocation quantity */
4335 if (xabpro.xab$w_acllen > 0)
4337 if (xabpro.xab$w_acllen > sizeof aclbuf)
4338 /* If the acl buffer was too short, redo open with longer one.
4339 Wouldn't need to do this if there were some system imposed
4340 limit on the size of an ACL, but I can't find any such. */
4342 xabpro.xab$l_aclbuf = (char *) alloca (xabpro.xab$w_acllen);
4343 xabpro.xab$w_aclsiz = xabpro.xab$w_acllen;
4344 if (SYS$OPEN (&fab, 0, 0) & 1)
4345 SYS$CLOSE (&fab, 0, 0);
4346 else
4347 old = 0;
4350 else
4351 xabpro.xab$l_aclbuf = 0;
4353 else
4354 old = 0;
4356 fab.fab$l_fna = new;
4357 fab.fab$b_fns = strlen (new);
4358 if (!old)
4360 fab.fab$l_xab = 0;
4361 fab.fab$b_rfm = vms_stmlf_recfm ? FAB$C_STMLF : FAB$C_VAR;
4362 fab.fab$b_rat = FAB$M_CR;
4365 /* Set the file protections such that we will be able to manipulate
4366 this file. Once we are done writing and renaming it, we will set
4367 the protections back. */
4368 if (old)
4369 fab_final_pro = xabpro.xab$w_pro;
4370 else
4371 SYS$SETDFPROT (0, &fab_final_pro);
4372 xabpro.xab$w_pro &= 0xff0f; /* set O:rewd for now. This is set back later. */
4374 /* Create the new file with either default attrs or attrs copied
4375 from old file. */
4376 if (!(SYS$CREATE (&fab, 0, 0) & 1))
4377 return -1;
4378 SYS$CLOSE (&fab, 0, 0);
4379 /* As this is a "replacement" for creat, return a file descriptor
4380 opened for writing. */
4381 return open (new, O_WRONLY);
4384 #ifdef creat
4385 #undef creat
4386 #include <varargs.h>
4387 #ifdef __GNUC__
4388 #ifndef va_count
4389 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4390 #endif
4391 #endif
4394 sys_creat (va_alist)
4395 va_dcl
4397 va_list list_incrementer;
4398 char *name;
4399 int mode;
4400 int rfd; /* related file descriptor */
4401 int fd; /* Our new file descriptor */
4402 int count;
4403 struct stat st_buf;
4404 char rfm[12];
4405 char rat[15];
4406 char mrs[13];
4407 char fsz[13];
4408 extern int vms_stmlf_recfm;
4410 va_count (count);
4411 va_start (list_incrementer);
4412 name = va_arg (list_incrementer, char *);
4413 mode = va_arg (list_incrementer, int);
4414 if (count > 2)
4415 rfd = va_arg (list_incrementer, int);
4416 va_end (list_incrementer);
4417 if (count > 2)
4419 /* Use information from the related file descriptor to set record
4420 format of the newly created file. */
4421 fstat (rfd, &st_buf);
4422 switch (st_buf.st_fab_rfm)
4424 case FAB$C_FIX:
4425 strcpy (rfm, "rfm = fix");
4426 sprintf (mrs, "mrs = %d", st_buf.st_fab_mrs);
4427 strcpy (rat, "rat = ");
4428 if (st_buf.st_fab_rat & FAB$M_CR)
4429 strcat (rat, "cr");
4430 else if (st_buf.st_fab_rat & FAB$M_FTN)
4431 strcat (rat, "ftn");
4432 else if (st_buf.st_fab_rat & FAB$M_PRN)
4433 strcat (rat, "prn");
4434 if (st_buf.st_fab_rat & FAB$M_BLK)
4435 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4436 strcat (rat, ", blk");
4437 else
4438 strcat (rat, "blk");
4439 return creat (name, 0, rfm, rat, mrs);
4441 case FAB$C_VFC:
4442 strcpy (rfm, "rfm = vfc");
4443 sprintf (fsz, "fsz = %d", st_buf.st_fab_fsz);
4444 strcpy (rat, "rat = ");
4445 if (st_buf.st_fab_rat & FAB$M_CR)
4446 strcat (rat, "cr");
4447 else if (st_buf.st_fab_rat & FAB$M_FTN)
4448 strcat (rat, "ftn");
4449 else if (st_buf.st_fab_rat & FAB$M_PRN)
4450 strcat (rat, "prn");
4451 if (st_buf.st_fab_rat & FAB$M_BLK)
4452 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4453 strcat (rat, ", blk");
4454 else
4455 strcat (rat, "blk");
4456 return creat (name, 0, rfm, rat, fsz);
4458 case FAB$C_STM:
4459 strcpy (rfm, "rfm = stm");
4460 break;
4462 case FAB$C_STMCR:
4463 strcpy (rfm, "rfm = stmcr");
4464 break;
4466 case FAB$C_STMLF:
4467 strcpy (rfm, "rfm = stmlf");
4468 break;
4470 case FAB$C_UDF:
4471 strcpy (rfm, "rfm = udf");
4472 break;
4474 case FAB$C_VAR:
4475 strcpy (rfm, "rfm = var");
4476 break;
4478 strcpy (rat, "rat = ");
4479 if (st_buf.st_fab_rat & FAB$M_CR)
4480 strcat (rat, "cr");
4481 else if (st_buf.st_fab_rat & FAB$M_FTN)
4482 strcat (rat, "ftn");
4483 else if (st_buf.st_fab_rat & FAB$M_PRN)
4484 strcat (rat, "prn");
4485 if (st_buf.st_fab_rat & FAB$M_BLK)
4486 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4487 strcat (rat, ", blk");
4488 else
4489 strcat (rat, "blk");
4491 else
4493 strcpy (rfm, vms_stmlf_recfm ? "rfm = stmlf" : "rfm=var");
4494 strcpy (rat, "rat=cr");
4496 /* Until the VAX C RTL fixes the many bugs with modes, always use
4497 mode 0 to get the user's default protection. */
4498 fd = creat (name, 0, rfm, rat);
4499 if (fd < 0 && errno == EEXIST)
4501 if (unlink (name) < 0)
4502 report_file_error ("delete", build_string (name));
4503 fd = creat (name, 0, rfm, rat);
4505 return fd;
4507 #endif /* creat */
4509 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4511 sys_fwrite (ptr, size, num, fp)
4512 register char * ptr;
4513 FILE * fp;
4515 register int tot = num * size;
4517 while (tot--)
4518 fputc (*ptr++, fp);
4519 return num;
4523 * The VMS C library routine creat actually creates a new version of an
4524 * existing file rather than truncating the old version. There are times
4525 * when this is not the desired behavior, for instance, when writing an
4526 * auto save file (you only want one version), or when you don't have
4527 * write permission in the directory containing the file (but the file
4528 * itself is writable). Hence this routine, which is equivalent to
4529 * "close (creat (fn, 0));" on Unix if fn already exists.
4532 vms_truncate (fn)
4533 char *fn;
4535 struct FAB xfab = cc$rms_fab;
4536 struct RAB xrab = cc$rms_rab;
4537 int status;
4539 xfab.fab$l_fop = FAB$M_TEF; /* free allocated but unused blocks on close */
4540 xfab.fab$b_fac = FAB$M_TRN | FAB$M_GET; /* allow truncate and get access */
4541 xfab.fab$b_shr = FAB$M_NIL; /* allow no sharing - file must be locked */
4542 xfab.fab$l_fna = fn;
4543 xfab.fab$b_fns = strlen (fn);
4544 xfab.fab$l_dna = ";0"; /* default to latest version of the file */
4545 xfab.fab$b_dns = 2;
4546 xrab.rab$l_fab = &xfab;
4548 /* This gibberish opens the file, positions to the first record, and
4549 deletes all records from there until the end of file. */
4550 if ((SYS$OPEN (&xfab) & 01) == 01)
4552 if ((SYS$CONNECT (&xrab) & 01) == 01 &&
4553 (SYS$FIND (&xrab) & 01) == 01 &&
4554 (SYS$TRUNCATE (&xrab) & 01) == 01)
4555 status = 0;
4556 else
4557 status = -1;
4559 else
4560 status = -1;
4561 SYS$CLOSE (&xfab);
4562 return status;
4565 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4566 SYSPRV or a readable SYSUAF.DAT. */
4568 #ifdef READ_SYSUAF
4570 * getuaf.c
4572 * Routine to read the VMS User Authorization File and return
4573 * a specific user's record.
4576 static struct UAF retuaf;
4578 struct UAF *
4579 get_uaf_name (uname)
4580 char * uname;
4582 register status;
4583 struct FAB uaf_fab;
4584 struct RAB uaf_rab;
4586 uaf_fab = cc$rms_fab;
4587 uaf_rab = cc$rms_rab;
4588 /* initialize fab fields */
4589 uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
4590 uaf_fab.fab$b_fns = 21;
4591 uaf_fab.fab$b_fac = FAB$M_GET;
4592 uaf_fab.fab$b_org = FAB$C_IDX;
4593 uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
4594 /* initialize rab fields */
4595 uaf_rab.rab$l_fab = &uaf_fab;
4596 /* open the User Authorization File */
4597 status = SYS$OPEN (&uaf_fab);
4598 if (!(status&1))
4600 errno = EVMSERR;
4601 vaxc$errno = status;
4602 return 0;
4604 status = SYS$CONNECT (&uaf_rab);
4605 if (!(status&1))
4607 errno = EVMSERR;
4608 vaxc$errno = status;
4609 return 0;
4611 /* read the requested record - index is in uname */
4612 uaf_rab.rab$l_kbf = uname;
4613 uaf_rab.rab$b_ksz = strlen (uname);
4614 uaf_rab.rab$b_rac = RAB$C_KEY;
4615 uaf_rab.rab$l_ubf = (char *)&retuaf;
4616 uaf_rab.rab$w_usz = sizeof retuaf;
4617 status = SYS$GET (&uaf_rab);
4618 if (!(status&1))
4620 errno = EVMSERR;
4621 vaxc$errno = status;
4622 return 0;
4624 /* close the User Authorization File */
4625 status = SYS$DISCONNECT (&uaf_rab);
4626 if (!(status&1))
4628 errno = EVMSERR;
4629 vaxc$errno = status;
4630 return 0;
4632 status = SYS$CLOSE (&uaf_fab);
4633 if (!(status&1))
4635 errno = EVMSERR;
4636 vaxc$errno = status;
4637 return 0;
4639 return &retuaf;
4642 struct UAF *
4643 get_uaf_uic (uic)
4644 unsigned long uic;
4646 register status;
4647 struct FAB uaf_fab;
4648 struct RAB uaf_rab;
4650 uaf_fab = cc$rms_fab;
4651 uaf_rab = cc$rms_rab;
4652 /* initialize fab fields */
4653 uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
4654 uaf_fab.fab$b_fns = 21;
4655 uaf_fab.fab$b_fac = FAB$M_GET;
4656 uaf_fab.fab$b_org = FAB$C_IDX;
4657 uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
4658 /* initialize rab fields */
4659 uaf_rab.rab$l_fab = &uaf_fab;
4660 /* open the User Authorization File */
4661 status = SYS$OPEN (&uaf_fab);
4662 if (!(status&1))
4664 errno = EVMSERR;
4665 vaxc$errno = status;
4666 return 0;
4668 status = SYS$CONNECT (&uaf_rab);
4669 if (!(status&1))
4671 errno = EVMSERR;
4672 vaxc$errno = status;
4673 return 0;
4675 /* read the requested record - index is in uic */
4676 uaf_rab.rab$b_krf = 1; /* 1st alternate key */
4677 uaf_rab.rab$l_kbf = (char *) &uic;
4678 uaf_rab.rab$b_ksz = sizeof uic;
4679 uaf_rab.rab$b_rac = RAB$C_KEY;
4680 uaf_rab.rab$l_ubf = (char *)&retuaf;
4681 uaf_rab.rab$w_usz = sizeof retuaf;
4682 status = SYS$GET (&uaf_rab);
4683 if (!(status&1))
4685 errno = EVMSERR;
4686 vaxc$errno = status;
4687 return 0;
4689 /* close the User Authorization File */
4690 status = SYS$DISCONNECT (&uaf_rab);
4691 if (!(status&1))
4693 errno = EVMSERR;
4694 vaxc$errno = status;
4695 return 0;
4697 status = SYS$CLOSE (&uaf_fab);
4698 if (!(status&1))
4700 errno = EVMSERR;
4701 vaxc$errno = status;
4702 return 0;
4704 return &retuaf;
4707 static struct passwd retpw;
4709 struct passwd *
4710 cnv_uaf_pw (up)
4711 struct UAF * up;
4713 char * ptr;
4715 /* copy these out first because if the username is 32 chars, the next
4716 section will overwrite the first byte of the UIC */
4717 retpw.pw_uid = up->uaf$w_mem;
4718 retpw.pw_gid = up->uaf$w_grp;
4720 /* I suppose this is not the best style, to possibly overwrite one
4721 byte beyond the end of the field, but what the heck... */
4722 ptr = &up->uaf$t_username[UAF$S_USERNAME];
4723 while (ptr[-1] == ' ')
4724 ptr--;
4725 *ptr = '\0';
4726 strcpy (retpw.pw_name, up->uaf$t_username);
4728 /* the rest of these are counted ascii strings */
4729 strncpy (retpw.pw_gecos, &up->uaf$t_owner[1], up->uaf$t_owner[0]);
4730 retpw.pw_gecos[up->uaf$t_owner[0]] = '\0';
4731 strncpy (retpw.pw_dir, &up->uaf$t_defdev[1], up->uaf$t_defdev[0]);
4732 retpw.pw_dir[up->uaf$t_defdev[0]] = '\0';
4733 strncat (retpw.pw_dir, &up->uaf$t_defdir[1], up->uaf$t_defdir[0]);
4734 retpw.pw_dir[up->uaf$t_defdev[0] + up->uaf$t_defdir[0]] = '\0';
4735 strncpy (retpw.pw_shell, &up->uaf$t_defcli[1], up->uaf$t_defcli[0]);
4736 retpw.pw_shell[up->uaf$t_defcli[0]] = '\0';
4738 return &retpw;
4740 #else /* not READ_SYSUAF */
4741 static struct passwd retpw;
4742 #endif /* not READ_SYSUAF */
4744 struct passwd *
4745 getpwnam (name)
4746 char * name;
4748 #ifdef READ_SYSUAF
4749 struct UAF *up;
4750 #else
4751 char * user;
4752 char * dir;
4753 unsigned char * full;
4754 #endif /* READ_SYSUAF */
4755 char *ptr = name;
4757 while (*ptr)
4759 if ('a' <= *ptr && *ptr <= 'z')
4760 *ptr -= 040;
4761 ptr++;
4763 #ifdef READ_SYSUAF
4764 if (!(up = get_uaf_name (name)))
4765 return 0;
4766 return cnv_uaf_pw (up);
4767 #else
4768 if (strcmp (name, getenv ("USER")) == 0)
4770 retpw.pw_uid = getuid ();
4771 retpw.pw_gid = getgid ();
4772 strcpy (retpw.pw_name, name);
4773 if (full = egetenv ("FULLNAME"))
4774 strcpy (retpw.pw_gecos, full);
4775 else
4776 *retpw.pw_gecos = '\0';
4777 strcpy (retpw.pw_dir, egetenv ("HOME"));
4778 *retpw.pw_shell = '\0';
4779 return &retpw;
4781 else
4782 return 0;
4783 #endif /* not READ_SYSUAF */
4786 struct passwd *
4787 getpwuid (uid)
4788 unsigned long uid;
4790 #ifdef READ_SYSUAF
4791 struct UAF * up;
4793 if (!(up = get_uaf_uic (uid)))
4794 return 0;
4795 return cnv_uaf_pw (up);
4796 #else
4797 if (uid == sys_getuid ())
4798 return getpwnam (egetenv ("USER"));
4799 else
4800 return 0;
4801 #endif /* not READ_SYSUAF */
4804 /* return total address space available to the current process. This is
4805 the sum of the current p0 size, p1 size and free page table entries
4806 available. */
4808 vlimit ()
4810 int item_code;
4811 unsigned long free_pages;
4812 unsigned long frep0va;
4813 unsigned long frep1va;
4814 register status;
4816 item_code = JPI$_FREPTECNT;
4817 if (((status = LIB$GETJPI (&item_code, 0, 0, &free_pages)) & 1) == 0)
4819 errno = EVMSERR;
4820 vaxc$errno = status;
4821 return -1;
4823 free_pages *= 512;
4825 item_code = JPI$_FREP0VA;
4826 if (((status = LIB$GETJPI (&item_code, 0, 0, &frep0va)) & 1) == 0)
4828 errno = EVMSERR;
4829 vaxc$errno = status;
4830 return -1;
4832 item_code = JPI$_FREP1VA;
4833 if (((status = LIB$GETJPI (&item_code, 0, 0, &frep1va)) & 1) == 0)
4835 errno = EVMSERR;
4836 vaxc$errno = status;
4837 return -1;
4840 return free_pages + frep0va + (0x7fffffff - frep1va);
4844 define_logical_name (varname, string)
4845 char *varname;
4846 char *string;
4848 struct dsc$descriptor_s strdsc =
4849 {strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string};
4850 struct dsc$descriptor_s envdsc =
4851 {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
4852 struct dsc$descriptor_s lnmdsc =
4853 {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
4855 return LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
4859 delete_logical_name (varname)
4860 char *varname;
4862 struct dsc$descriptor_s envdsc =
4863 {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
4864 struct dsc$descriptor_s lnmdsc =
4865 {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
4867 return LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
4871 ulimit ()
4873 return 0;
4877 setpgrp ()
4879 return 0;
4883 execvp ()
4885 error ("execvp system call not implemented");
4886 return -1;
4890 rename (from, to)
4891 char *from, *to;
4893 int status;
4894 struct FAB from_fab = cc$rms_fab, to_fab = cc$rms_fab;
4895 struct NAM from_nam = cc$rms_nam, to_nam = cc$rms_nam;
4896 char from_esn[NAM$C_MAXRSS];
4897 char to_esn[NAM$C_MAXRSS];
4899 from_fab.fab$l_fna = from;
4900 from_fab.fab$b_fns = strlen (from);
4901 from_fab.fab$l_nam = &from_nam;
4902 from_fab.fab$l_fop = FAB$M_NAM;
4904 from_nam.nam$l_esa = from_esn;
4905 from_nam.nam$b_ess = sizeof from_esn;
4907 to_fab.fab$l_fna = to;
4908 to_fab.fab$b_fns = strlen (to);
4909 to_fab.fab$l_nam = &to_nam;
4910 to_fab.fab$l_fop = FAB$M_NAM;
4912 to_nam.nam$l_esa = to_esn;
4913 to_nam.nam$b_ess = sizeof to_esn;
4915 status = SYS$RENAME (&from_fab, 0, 0, &to_fab);
4917 if (status & 1)
4918 return 0;
4919 else
4921 if (status == RMS$_DEV)
4922 errno = EXDEV;
4923 else
4924 errno = EVMSERR;
4925 vaxc$errno = status;
4926 return -1;
4930 /* This function renames a file like `rename', but it strips
4931 the version number from the "to" filename, such that the "to" file is
4932 will always be a new version. It also sets the file protection once it is
4933 finished. The protection that we will use is stored in fab_final_pro,
4934 and was set when we did a creat_copy_attrs to create the file that we
4935 are renaming.
4937 We could use the chmod function, but Eunichs uses 3 bits per user category
4938 to describe the protection, and VMS uses 4 (write and delete are separate
4939 bits). To maintain portability, the VMS implementation of `chmod' wires
4940 the W and D bits together. */
4943 static struct fibdef fib; /* We need this initialized to zero */
4944 char vms_file_written[NAM$C_MAXRSS];
4947 rename_sans_version (from,to)
4948 char *from, *to;
4950 short int chan;
4951 int stat;
4952 short int iosb[4];
4953 int status;
4954 struct FAB to_fab = cc$rms_fab;
4955 struct NAM to_nam = cc$rms_nam;
4956 struct dsc$descriptor fib_d ={sizeof (fib),0,0,(char*) &fib};
4957 struct dsc$descriptor fib_attr[2]
4958 = {{sizeof (fab_final_pro),ATR$C_FPRO,0,(char*) &fab_final_pro},{0,0,0,0}};
4959 char to_esn[NAM$C_MAXRSS];
4961 $DESCRIPTOR (disk,to_esn);
4963 to_fab.fab$l_fna = to;
4964 to_fab.fab$b_fns = strlen (to);
4965 to_fab.fab$l_nam = &to_nam;
4966 to_fab.fab$l_fop = FAB$M_NAM;
4968 to_nam.nam$l_esa = to_esn;
4969 to_nam.nam$b_ess = sizeof to_esn;
4971 status = SYS$PARSE (&to_fab, 0, 0); /* figure out the full file name */
4973 if (to_nam.nam$l_fnb && NAM$M_EXP_VER)
4974 *(to_nam.nam$l_ver) = '\0';
4976 stat = rename (from, to_esn);
4977 if (stat < 0)
4978 return stat;
4980 strcpy (vms_file_written, to_esn);
4982 to_fab.fab$l_fna = vms_file_written; /* this points to the versionless name */
4983 to_fab.fab$b_fns = strlen (vms_file_written);
4985 /* Now set the file protection to the correct value */
4986 SYS$OPEN (&to_fab, 0, 0); /* This fills in the nam$w_fid fields */
4988 /* Copy these fields into the fib */
4989 fib.fib$r_fid_overlay.fib$w_fid[0] = to_nam.nam$w_fid[0];
4990 fib.fib$r_fid_overlay.fib$w_fid[1] = to_nam.nam$w_fid[1];
4991 fib.fib$r_fid_overlay.fib$w_fid[2] = to_nam.nam$w_fid[2];
4993 SYS$CLOSE (&to_fab, 0, 0);
4995 stat = SYS$ASSIGN (&disk, &chan, 0, 0); /* open a channel to the disk */
4996 if (!stat)
4997 LIB$SIGNAL (stat);
4998 stat = SYS$QIOW (0, chan, IO$_MODIFY, iosb, 0, 0, &fib_d,
4999 0, 0, 0, &fib_attr, 0);
5000 if (!stat)
5001 LIB$SIGNAL (stat);
5002 stat = SYS$DASSGN (chan);
5003 if (!stat)
5004 LIB$SIGNAL (stat);
5005 strcpy (vms_file_written, to_esn); /* We will write this to the terminal*/
5006 return 0;
5010 link (file, new)
5011 char * file, * new;
5013 register status;
5014 struct FAB fab;
5015 struct NAM nam;
5016 unsigned short fid[3];
5017 char esa[NAM$C_MAXRSS];
5019 fab = cc$rms_fab;
5020 fab.fab$l_fop = FAB$M_OFP;
5021 fab.fab$l_fna = file;
5022 fab.fab$b_fns = strlen (file);
5023 fab.fab$l_nam = &nam;
5025 nam = cc$rms_nam;
5026 nam.nam$l_esa = esa;
5027 nam.nam$b_ess = NAM$C_MAXRSS;
5029 status = SYS$PARSE (&fab);
5030 if ((status & 1) == 0)
5032 errno = EVMSERR;
5033 vaxc$errno = status;
5034 return -1;
5036 status = SYS$SEARCH (&fab);
5037 if ((status & 1) == 0)
5039 errno = EVMSERR;
5040 vaxc$errno = status;
5041 return -1;
5044 fid[0] = nam.nam$w_fid[0];
5045 fid[1] = nam.nam$w_fid[1];
5046 fid[2] = nam.nam$w_fid[2];
5048 fab.fab$l_fna = new;
5049 fab.fab$b_fns = strlen (new);
5051 status = SYS$PARSE (&fab);
5052 if ((status & 1) == 0)
5054 errno = EVMSERR;
5055 vaxc$errno = status;
5056 return -1;
5059 nam.nam$w_fid[0] = fid[0];
5060 nam.nam$w_fid[1] = fid[1];
5061 nam.nam$w_fid[2] = fid[2];
5063 nam.nam$l_esa = nam.nam$l_name;
5064 nam.nam$b_esl = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver;
5066 status = SYS$ENTER (&fab);
5067 if ((status & 1) == 0)
5069 errno = EVMSERR;
5070 vaxc$errno = status;
5071 return -1;
5074 return 0;
5077 void
5078 croak (badfunc)
5079 char *badfunc;
5081 printf ("%s not yet implemented\r\n", badfunc);
5082 reset_all_sys_modes ();
5083 exit (1);
5086 long
5087 random ()
5089 /* Arrange to return a range centered on zero. */
5090 return rand () - (1 << 30);
5093 void
5094 srandom (seed)
5096 srand (seed);
5098 #endif /* VMS */
5100 #ifdef AIXHFT
5102 /* Called from init_sys_modes. */
5103 void
5104 hft_init (struct tty_output *tty_out)
5106 int junk;
5108 /* If we're not on an HFT we shouldn't do any of this. We determine
5109 if we are on an HFT by trying to get an HFT error code. If this
5110 call fails, we're not on an HFT. */
5111 #ifdef IBMR2AIX
5112 if (ioctl (0, HFQERROR, &junk) < 0)
5113 return;
5114 #else /* not IBMR2AIX */
5115 if (ioctl (0, HFQEIO, 0) < 0)
5116 return;
5117 #endif /* not IBMR2AIX */
5119 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5120 as the rubout key's ASCII code. Here this is changed. The bug is that
5121 there's no way to determine the old mapping, so in reset_sys_modes
5122 we need to assume that the normal map had been present. Of course, this
5123 code also doesn't help if on a terminal emulator which doesn't understand
5124 HFT VTD's. */
5126 struct hfbuf buf;
5127 struct hfkeymap keymap;
5129 buf.hf_bufp = (char *)&keymap;
5130 buf.hf_buflen = sizeof (keymap);
5131 keymap.hf_nkeys = 2;
5132 keymap.hfkey[0].hf_kpos = 15;
5133 keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
5134 #ifdef IBMR2AIX
5135 keymap.hfkey[0].hf_keyidh = '<';
5136 #else /* not IBMR2AIX */
5137 keymap.hfkey[0].hf_page = '<';
5138 #endif /* not IBMR2AIX */
5139 keymap.hfkey[0].hf_char = 127;
5140 keymap.hfkey[1].hf_kpos = 15;
5141 keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
5142 #ifdef IBMR2AIX
5143 keymap.hfkey[1].hf_keyidh = '<';
5144 #else /* not IBMR2AIX */
5145 keymap.hfkey[1].hf_page = '<';
5146 #endif /* not IBMR2AIX */
5147 keymap.hfkey[1].hf_char = 127;
5148 hftctl (0, HFSKBD, &buf);
5150 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
5151 at times. */
5152 TTY_LINE_INS_DEL_OK (tty_out) = 0;
5153 TTY_CHAR_INS_DEL_OK (tty_out) = 0;
5156 /* Reset the rubout key to backspace. */
5158 void
5159 hft_reset (struct tty_output *tty_out)
5161 struct hfbuf buf;
5162 struct hfkeymap keymap;
5163 int junk;
5165 #ifdef IBMR2AIX
5166 if (ioctl (0, HFQERROR, &junk) < 0)
5167 return;
5168 #else /* not IBMR2AIX */
5169 if (ioctl (0, HFQEIO, 0) < 0)
5170 return;
5171 #endif /* not IBMR2AIX */
5173 buf.hf_bufp = (char *)&keymap;
5174 buf.hf_buflen = sizeof (keymap);
5175 keymap.hf_nkeys = 2;
5176 keymap.hfkey[0].hf_kpos = 15;
5177 keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
5178 #ifdef IBMR2AIX
5179 keymap.hfkey[0].hf_keyidh = '<';
5180 #else /* not IBMR2AIX */
5181 keymap.hfkey[0].hf_page = '<';
5182 #endif /* not IBMR2AIX */
5183 keymap.hfkey[0].hf_char = 8;
5184 keymap.hfkey[1].hf_kpos = 15;
5185 keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
5186 #ifdef IBMR2AIX
5187 keymap.hfkey[1].hf_keyidh = '<';
5188 #else /* not IBMR2AIX */
5189 keymap.hfkey[1].hf_page = '<';
5190 #endif /* not IBMR2AIX */
5191 keymap.hfkey[1].hf_char = 8;
5192 hftctl (0, HFSKBD, &buf);
5195 #endif /* AIXHFT */
5197 #ifdef USE_DL_STUBS
5199 /* These are included on Sunos 4.1 when we do not use shared libraries.
5200 X11 libraries may refer to these functions but (we hope) do not
5201 actually call them. */
5203 void *
5204 dlopen ()
5206 return 0;
5209 void *
5210 dlsym ()
5212 return 0;
5216 dlclose ()
5218 return -1;
5221 #endif /* USE_DL_STUBS */
5223 #ifndef BSTRING
5225 #ifndef bzero
5227 void
5228 bzero (b, length)
5229 register char *b;
5230 register int length;
5232 #ifdef VMS
5233 short zero = 0;
5234 long max_str = 65535;
5236 while (length > max_str) {
5237 (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
5238 length -= max_str;
5239 b += max_str;
5241 max_str = length;
5242 (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
5243 #else
5244 while (length-- > 0)
5245 *b++ = 0;
5246 #endif /* not VMS */
5249 #endif /* no bzero */
5250 #endif /* BSTRING */
5252 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5253 #undef bcopy
5255 /* Saying `void' requires a declaration, above, where bcopy is used
5256 and that declaration causes pain for systems where bcopy is a macro. */
5257 bcopy (b1, b2, length)
5258 register char *b1;
5259 register char *b2;
5260 register int length;
5262 #ifdef VMS
5263 long max_str = 65535;
5265 while (length > max_str) {
5266 (void) LIB$MOVC3 (&max_str, b1, b2);
5267 length -= max_str;
5268 b1 += max_str;
5269 b2 += max_str;
5271 max_str = length;
5272 (void) LIB$MOVC3 (&length, b1, b2);
5273 #else
5274 while (length-- > 0)
5275 *b2++ = *b1++;
5276 #endif /* not VMS */
5278 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5280 #ifndef BSTRING
5281 #ifndef bcmp
5283 bcmp (b1, b2, length) /* This could be a macro! */
5284 register char *b1;
5285 register char *b2;
5286 register int length;
5288 #ifdef VMS
5289 struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
5290 struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
5292 return STR$COMPARE (&src1, &src2);
5293 #else
5294 while (length-- > 0)
5295 if (*b1++ != *b2++)
5296 return 1;
5298 return 0;
5299 #endif /* not VMS */
5301 #endif /* no bcmp */
5302 #endif /* not BSTRING */
5304 #ifndef HAVE_STRSIGNAL
5305 char *
5306 strsignal (code)
5307 int code;
5309 char *signame = 0;
5311 if (0 <= code && code < NSIG)
5313 #ifdef VMS
5314 signame = sys_errlist[code];
5315 #else
5316 /* Cast to suppress warning if the table has const char *. */
5317 signame = (char *) sys_siglist[code];
5318 #endif
5321 return signame;
5323 #endif /* HAVE_STRSIGNAL */
5325 /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
5326 (do not change this comment) */