(AC_PREREQ): Bump from 2.50 to 2.51; needed for vfork.
[emacs.git] / src / sysdep.c
blob28de7dba0195c66b510503ebbba9afed981d4144
1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 86,87,88,93,94,95, 1999, 2000, 2001
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. */
23 #include "config.h"
24 #include <signal.h>
25 #include <setjmp.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #include "lisp.h"
30 /* Including stdlib.h isn't necessarily enough to get srandom
31 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
32 #ifdef HAVE_RANDOM
33 #if 0 /* It turns out that defining _OSF_SOURCE in osf5-0.h gets
34 random prototyped as returning `int'. It looks to me as
35 though the best way to DTRT is to prefer the rand48 functions
36 (per libc.info). -- fx */
37 extern long int random P_ ((void));
38 #endif
39 #if 0 /* Don't prototype srandom; it takes an unsigned argument on
40 some systems, and an unsigned long on others, like FreeBSD
41 4.1. */
42 extern void srandom P_ ((unsigned int));
43 #endif
44 #endif
46 #include "blockinput.h"
47 #undef NULL
49 #ifdef macintosh
50 /* It is essential to include stdlib.h so that this file picks up
51 the correct definitions of rand, srand, and RAND_MAX.
52 Otherwise random numbers will not work correctly. */
53 #include <stdlib.h>
55 #ifndef subprocesses
56 /* Nonzero means delete a process right away if it exits (process.c). */
57 static int delete_exited_processes;
58 #endif
59 #endif /* macintosh */
61 #ifdef WINDOWSNT
62 #define read sys_read
63 #define write sys_write
64 #include <windows.h>
65 #ifndef NULL
66 #define NULL 0
67 #endif
68 #endif /* not WINDOWSNT */
70 /* Does anyone other than VMS need this? */
71 #ifndef fwrite
72 #define sys_fwrite fwrite
73 #else
74 #undef fwrite
75 #endif
77 #include <stdio.h>
78 #include <sys/types.h>
79 #include <sys/stat.h>
80 #include <errno.h>
82 /* Get _POSIX_VDISABLE, if it is available. */
83 #ifdef HAVE_UNISTD_H
84 #include <unistd.h>
85 #endif
87 #ifdef HAVE_STDLIB_H
88 #include <stdlib.h>
89 #endif
91 #ifdef HAVE_SETPGID
92 #if !defined (USG) || defined (BSD_PGRPS)
93 #undef setpgrp
94 #define setpgrp setpgid
95 #endif
96 #endif
98 /* Get SI_SRPC_DOMAIN, if it is available. */
99 #ifdef HAVE_SYS_SYSTEMINFO_H
100 #include <sys/systeminfo.h>
101 #endif
103 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
104 #include <dos.h>
105 #include "dosfns.h"
106 #include "msdos.h"
107 #include <sys/param.h>
109 #if __DJGPP__ > 1
110 extern int etext;
111 extern unsigned start __asm__ ("start");
112 #endif
113 #endif
115 #ifndef USE_CRT_DLL
116 #ifndef errno
117 extern int errno;
118 #endif
119 #endif
121 #ifdef VMS
122 #include <rms.h>
123 #include <ttdef.h>
124 #include <tt2def.h>
125 #include <iodef.h>
126 #include <ssdef.h>
127 #include <descrip.h>
128 #include <fibdef.h>
129 #include <atrdef.h>
130 #include <ctype.h>
131 #include <string.h>
132 #ifdef __GNUC__
133 #include <sys/file.h>
134 #else
135 #include <file.h>
136 #endif
137 #undef F_SETFL
138 #ifndef RAB$C_BID
139 #include <rab.h>
140 #endif
141 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
142 #endif /* VMS */
144 #ifndef BSD4_1
145 #ifdef BSD_SYSTEM /* avoid writing defined (BSD_SYSTEM) || defined (USG)
146 because the vms compiler doesn't grok `defined' */
147 #include <fcntl.h>
148 #endif
149 #ifdef USG
150 #ifndef USG5
151 #include <fcntl.h>
152 #endif
153 #endif
154 #endif /* not 4.1 bsd */
156 #ifndef MSDOS
157 #include <sys/ioctl.h>
158 #endif
160 #include "systty.h"
161 #include "syswait.h"
163 #ifdef BROKEN_TIOCGWINSZ
164 #undef TIOCGWINSZ
165 #undef TIOCSWINSZ
166 #endif
168 #if defined (USG) || defined (DGUX)
169 #include <sys/utsname.h>
170 #ifndef MEMORY_IN_STRING_H
171 #include <memory.h>
172 #endif
173 #if defined (TIOCGWINSZ) || defined (ISC4_0)
174 #ifdef NEED_SIOCTL
175 #include <sys/sioctl.h>
176 #endif
177 #ifdef NEED_PTEM_H
178 #include <sys/stream.h>
179 #include <sys/ptem.h>
180 #endif
181 #endif /* TIOCGWINSZ or ISC4_0 */
182 #endif /* USG or DGUX */
184 extern int quit_char;
186 #include "keyboard.h"
187 #include "frame.h"
188 #include "window.h"
189 #include "termhooks.h"
190 #include "termchar.h"
191 #include "termopts.h"
192 #include "dispextern.h"
193 #include "process.h"
195 #ifdef WINDOWSNT
196 #include <direct.h>
197 /* In process.h which conflicts with the local copy. */
198 #define _P_WAIT 0
199 int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
200 int _CRTAPI1 _getpid (void);
201 #endif
203 #ifdef NONSYSTEM_DIR_LIBRARY
204 #include "ndir.h"
205 #endif /* NONSYSTEM_DIR_LIBRARY */
207 #include "syssignal.h"
208 #include "systime.h"
209 #ifdef HAVE_UTIME_H
210 #include <utime.h>
211 #endif
213 #ifndef HAVE_UTIMES
214 #ifndef HAVE_STRUCT_UTIMBUF
215 /* We want to use utime rather than utimes, but we couldn't find the
216 structure declaration. We'll use the traditional one. */
217 struct utimbuf {
218 long actime;
219 long modtime;
221 #endif
222 #endif
224 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
225 #ifndef LPASS8
226 #define LPASS8 0
227 #endif
229 #ifdef BSD4_1
230 #define LNOFLSH 0100000
231 #endif
233 static int baud_convert[] =
234 #ifdef BAUD_CONVERT
235 BAUD_CONVERT;
236 #else
238 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
239 1800, 2400, 4800, 9600, 19200, 38400
241 #endif
243 #ifdef HAVE_SPEED_T
244 #include <termios.h>
245 #else
246 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
247 #else
248 #if defined (HAVE_TERMIOS_H) && defined (LINUX)
249 #include <termios.h>
250 #endif
251 #endif
252 #endif
254 int emacs_ospeed;
256 /* The file descriptor for Emacs's input terminal.
257 Under Unix, this is normally zero except when using X;
258 under VMS, we place the input channel number here. */
259 int input_fd;
261 void croak P_ ((char *));
263 #ifdef AIXHFT
264 void hft_init ();
265 void hft_reset ();
266 #endif
268 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
270 SIGMASKTYPE sigprocmask_set;
273 /* Specify a different file descriptor for further input operations. */
275 void
276 change_input_fd (fd)
277 int fd;
279 input_fd = fd;
282 /* Discard pending input on descriptor input_fd. */
284 void
285 discard_tty_input ()
287 #ifndef WINDOWSNT
288 struct emacs_tty buf;
290 if (noninteractive)
291 return;
293 /* Discarding input is not safe when the input could contain
294 replies from the X server. So don't do it. */
295 if (read_socket_hook)
296 return;
298 #ifdef VMS
299 end_kbd_input ();
300 SYS$QIOW (0, input_fd, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
301 &buf.main, 0, 0, terminator_mask, 0, 0);
302 queue_kbd_input ();
303 #else /* not VMS */
304 #ifdef APOLLO
306 int zero = 0;
307 ioctl (input_fd, TIOCFLUSH, &zero);
309 #else /* not Apollo */
310 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
311 while (dos_keyread () != -1)
313 #else /* not MSDOS */
314 EMACS_GET_TTY (input_fd, &buf);
315 EMACS_SET_TTY (input_fd, &buf, 0);
316 #endif /* not MSDOS */
317 #endif /* not Apollo */
318 #endif /* not VMS */
319 #endif /* not WINDOWSNT */
322 #ifdef SIGTSTP
324 /* Arrange for character C to be read as the next input from
325 the terminal. */
327 void
328 stuff_char (c)
329 char c;
331 if (read_socket_hook)
332 return;
334 /* Should perhaps error if in batch mode */
335 #ifdef TIOCSTI
336 ioctl (input_fd, TIOCSTI, &c);
337 #else /* no TIOCSTI */
338 error ("Cannot stuff terminal input characters in this version of Unix");
339 #endif /* no TIOCSTI */
342 #endif /* SIGTSTP */
344 void
345 init_baud_rate ()
347 if (noninteractive)
348 emacs_ospeed = 0;
349 else
351 #ifdef INIT_BAUD_RATE
352 INIT_BAUD_RATE ();
353 #else
354 #ifdef DOS_NT
355 emacs_ospeed = 15;
356 #else /* not DOS_NT */
357 #ifdef VMS
358 struct sensemode sg;
360 SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
361 &sg.class, 12, 0, 0, 0, 0 );
362 emacs_ospeed = sg.xmit_baud;
363 #else /* not VMS */
364 #ifdef HAVE_TERMIOS
365 struct termios sg;
367 sg.c_cflag = B9600;
368 tcgetattr (input_fd, &sg);
369 emacs_ospeed = cfgetospeed (&sg);
370 #if defined (USE_GETOBAUD) && defined (getobaud)
371 /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
372 if (emacs_ospeed == 0)
373 emacs_ospeed = getobaud (sg.c_cflag);
374 #endif
375 #else /* neither VMS nor TERMIOS */
376 #ifdef HAVE_TERMIO
377 struct termio sg;
379 sg.c_cflag = B9600;
380 #ifdef HAVE_TCATTR
381 tcgetattr (input_fd, &sg);
382 #else
383 ioctl (input_fd, TCGETA, &sg);
384 #endif
385 emacs_ospeed = sg.c_cflag & CBAUD;
386 #else /* neither VMS nor TERMIOS nor TERMIO */
387 struct sgttyb sg;
389 sg.sg_ospeed = B9600;
390 if (ioctl (input_fd, TIOCGETP, &sg) < 0)
391 abort ();
392 emacs_ospeed = sg.sg_ospeed;
393 #endif /* not HAVE_TERMIO */
394 #endif /* not HAVE_TERMIOS */
395 #endif /* not VMS */
396 #endif /* not DOS_NT */
397 #endif /* not INIT_BAUD_RATE */
400 baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
401 ? baud_convert[emacs_ospeed] : 9600);
402 if (baud_rate == 0)
403 baud_rate = 1200;
406 /*ARGSUSED*/
407 void
408 set_exclusive_use (fd)
409 int fd;
411 #ifdef FIOCLEX
412 ioctl (fd, FIOCLEX, 0);
413 #endif
414 /* Ok to do nothing if this feature does not exist */
417 #ifndef subprocesses
419 wait_without_blocking ()
421 #ifdef BSD_SYSTEM
422 wait3 (0, WNOHANG | WUNTRACED, 0);
423 #else
424 croak ("wait_without_blocking");
425 #endif
426 synch_process_alive = 0;
429 #endif /* not subprocesses */
431 int wait_debugging; /* Set nonzero to make following function work under dbx
432 (at least for bsd). */
434 SIGTYPE
435 wait_for_termination_signal ()
438 /* Wait for subprocess with process id `pid' to terminate and
439 make sure it will get eliminated (not remain forever as a zombie) */
441 void
442 wait_for_termination (pid)
443 int pid;
445 while (1)
447 #ifdef subprocesses
448 #ifdef VMS
449 int status;
451 status = SYS$FORCEX (&pid, 0, 0);
452 break;
453 #else /* not VMS */
454 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
455 /* Note that kill returns -1 even if the process is just a zombie now.
456 But inevitably a SIGCHLD interrupt should be generated
457 and child_sig will do wait3 and make the process go away. */
458 /* There is some indication that there is a bug involved with
459 termination of subprocesses, perhaps involving a kernel bug too,
460 but no idea what it is. Just as a hunch we signal SIGCHLD to see
461 if that causes the problem to go away or get worse. */
462 sigsetmask (sigmask (SIGCHLD));
463 if (0 > kill (pid, 0))
465 sigsetmask (SIGEMPTYMASK);
466 kill (getpid (), SIGCHLD);
467 break;
469 if (wait_debugging)
470 sleep (1);
471 else
472 sigpause (SIGEMPTYMASK);
473 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
474 #if defined (UNIPLUS)
475 if (0 > kill (pid, 0))
476 break;
477 wait (0);
478 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
479 #ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
480 sigblock (sigmask (SIGCHLD));
481 errno = 0;
482 if (kill (pid, 0) == -1 && errno == ESRCH)
484 sigunblock (sigmask (SIGCHLD));
485 break;
488 /* FIXME: Since sigpause is not POSIX and its use is deprecated,
489 this should probably be `sigsuspend (&empty_mask)', which is
490 POSIX. I'm not making that change right away because the
491 release is nearing. 2001-09-20 gerd. */
492 sigpause (SIGEMPTYMASK);
493 #else /* not POSIX_SIGNALS */
494 #ifdef HAVE_SYSV_SIGPAUSE
495 sighold (SIGCHLD);
496 if (0 > kill (pid, 0))
498 sigrelse (SIGCHLD);
499 break;
501 sigpause (SIGCHLD);
502 #else /* not HAVE_SYSV_SIGPAUSE */
503 #ifdef WINDOWSNT
504 wait (0);
505 break;
506 #else /* not WINDOWSNT */
507 if (0 > kill (pid, 0))
508 break;
509 /* Using sleep instead of pause avoids timing error.
510 If the inferior dies just before the sleep,
511 we lose just one second. */
512 sleep (1);
513 #endif /* not WINDOWSNT */
514 #endif /* not HAVE_SYSV_SIGPAUSE */
515 #endif /* not POSIX_SIGNALS */
516 #endif /* not UNIPLUS */
517 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
518 #endif /* not VMS */
519 #else /* not subprocesses */
520 #if __DJGPP__ > 1
521 break;
522 #else /* not __DJGPP__ > 1 */
523 #ifndef BSD4_1
524 if (kill (pid, 0) < 0)
525 break;
526 wait (0);
527 #else /* BSD4_1 */
528 int status;
529 status = wait (0);
530 if (status == pid || status == -1)
531 break;
532 #endif /* BSD4_1 */
533 #endif /* not __DJGPP__ > 1*/
534 #endif /* not subprocesses */
538 #ifdef subprocesses
541 * flush any pending output
542 * (may flush input as well; it does not matter the way we use it)
545 void
546 flush_pending_output (channel)
547 int channel;
549 #ifdef HAVE_TERMIOS
550 /* If we try this, we get hit with SIGTTIN, because
551 the child's tty belongs to the child's pgrp. */
552 #else
553 #ifdef TCFLSH
554 ioctl (channel, TCFLSH, 1);
555 #else
556 #ifdef TIOCFLUSH
557 int zero = 0;
558 /* 3rd arg should be ignored
559 but some 4.2 kernels actually want the address of an int
560 and nonzero means something different. */
561 ioctl (channel, TIOCFLUSH, &zero);
562 #endif
563 #endif
564 #endif
567 #ifndef VMS
568 /* Set up the terminal at the other end of a pseudo-terminal that
569 we will be controlling an inferior through.
570 It should not echo or do line-editing, since that is done
571 in Emacs. No padding needed for insertion into an Emacs buffer. */
573 void
574 child_setup_tty (out)
575 int out;
577 #ifndef DOS_NT
578 struct emacs_tty s;
580 EMACS_GET_TTY (out, &s);
582 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
583 s.main.c_oflag |= OPOST; /* Enable output postprocessing */
584 s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */
585 #ifdef NLDLY
586 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
587 /* No output delays */
588 #endif
589 s.main.c_lflag &= ~ECHO; /* Disable echo */
590 s.main.c_lflag |= ISIG; /* Enable signals */
591 #if 0 /* This causes bugs in (for instance) telnet to certain sites. */
592 s.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
593 #ifdef INLCR /* Just being cautious, since I can't check how
594 widespread INLCR is--rms. */
595 s.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
596 #endif
597 #endif
598 #ifdef IUCLC
599 s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */
600 #endif
601 #ifdef ISTRIP
602 s.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
603 #endif
604 #ifdef OLCUC
605 s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */
606 #endif
607 s.main.c_oflag &= ~TAB3; /* Disable tab expansion */
608 s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
609 #if 0
610 /* Said to be unnecessary: */
611 s.main.c_cc[VMIN] = 1; /* minimum number of characters to accept */
612 s.main.c_cc[VTIME] = 0; /* wait forever for at least 1 character */
613 #endif
615 s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */
616 s.main.c_cc[VEOF] = 04; /* insure that EOF is Control-D */
617 s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
618 s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
620 #ifdef HPUX
621 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
622 #endif /* HPUX */
624 #ifdef AIX
625 /* AIX enhanced edit loses NULs, so disable it */
626 #ifndef IBMR2AIX
627 s.main.c_line = 0;
628 s.main.c_iflag &= ~ASCEDIT;
629 #endif
630 /* Also, PTY overloads NUL and BREAK.
631 don't ignore break, but don't signal either, so it looks like NUL. */
632 s.main.c_iflag &= ~IGNBRK;
633 s.main.c_iflag &= ~BRKINT;
634 /* QUIT and INTR work better as signals, so disable character forms */
635 s.main.c_cc[VINTR] = 0377;
636 #ifdef SIGNALS_VIA_CHARACTERS
637 /* the QUIT and INTR character are used in process_send_signal
638 so set them here to something useful. */
639 if (s.main.c_cc[VQUIT] == 0377)
640 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
641 if (s.main.c_cc[VINTR] == 0377)
642 s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
643 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
644 /* QUIT and INTR work better as signals, so disable character forms */
645 s.main.c_cc[VQUIT] = 0377;
646 s.main.c_cc[VINTR] = 0377;
647 s.main.c_lflag &= ~ISIG;
648 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
649 s.main.c_cc[VEOL] = 0377;
650 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
651 #endif /* AIX */
653 #else /* not HAVE_TERMIO */
655 s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
656 | CBREAK | TANDEM);
657 s.main.sg_flags |= LPASS8;
658 s.main.sg_erase = 0377;
659 s.main.sg_kill = 0377;
660 s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */
662 #endif /* not HAVE_TERMIO */
664 EMACS_SET_TTY (out, &s, 0);
666 #ifdef BSD4_1
667 if (interrupt_input)
668 reset_sigio ();
669 #endif /* BSD4_1 */
670 #ifdef RTU
672 int zero = 0;
673 ioctl (out, FIOASYNC, &zero);
675 #endif /* RTU */
676 #endif /* not DOS_NT */
678 #endif /* not VMS */
680 #endif /* subprocesses */
682 /* Record a signal code and the handler for it. */
683 struct save_signal
685 int code;
686 SIGTYPE (*handler) P_ ((int));
689 static void save_signal_handlers P_ ((struct save_signal *));
690 static void restore_signal_handlers P_ ((struct save_signal *));
692 /* Suspend the Emacs process; give terminal to its superior. */
694 void
695 sys_suspend ()
697 #ifdef VMS
698 /* "Foster" parentage allows emacs to return to a subprocess that attached
699 to the current emacs as a cheaper than starting a whole new process. This
700 is set up by KEPTEDITOR.COM. */
701 unsigned long parent_id, foster_parent_id;
702 char *fpid_string;
704 fpid_string = getenv ("EMACS_PARENT_PID");
705 if (fpid_string != NULL)
707 sscanf (fpid_string, "%x", &foster_parent_id);
708 if (foster_parent_id != 0)
709 parent_id = foster_parent_id;
710 else
711 parent_id = getppid ();
713 else
714 parent_id = getppid ();
716 xfree (fpid_string); /* On VMS, this was malloc'd */
718 if (parent_id && parent_id != 0xffffffff)
720 SIGTYPE (*oldsig)() = (int) signal (SIGINT, SIG_IGN);
721 int status = LIB$ATTACH (&parent_id) & 1;
722 signal (SIGINT, oldsig);
723 return status;
725 else
727 struct {
728 int l;
729 char *a;
730 } d_prompt;
731 d_prompt.l = sizeof ("Emacs: "); /* Our special prompt */
732 d_prompt.a = "Emacs: "; /* Just a reminder */
733 LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0);
734 return 1;
736 return -1;
737 #else
738 #if defined (SIGTSTP) && !defined (MSDOS)
741 int pgrp = EMACS_GETPGRP (0);
742 EMACS_KILLPG (pgrp, SIGTSTP);
745 #else /* No SIGTSTP */
746 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
747 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
748 kill (getpid (), SIGQUIT);
750 #else /* No SIGTSTP or USG_JOBCTRL */
752 /* On a system where suspending is not implemented,
753 instead fork a subshell and let it talk directly to the terminal
754 while we wait. */
755 sys_subshell ();
757 #endif /* no USG_JOBCTRL */
758 #endif /* no SIGTSTP */
759 #endif /* not VMS */
762 /* Fork a subshell. */
764 #ifndef macintosh
765 void
766 sys_subshell ()
768 #ifndef VMS
769 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
770 int st;
771 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
772 #endif
773 int pid;
774 struct save_signal saved_handlers[5];
775 Lisp_Object dir;
776 unsigned char *str = 0;
777 int len;
779 saved_handlers[0].code = SIGINT;
780 saved_handlers[1].code = SIGQUIT;
781 saved_handlers[2].code = SIGTERM;
782 #ifdef SIGIO
783 saved_handlers[3].code = SIGIO;
784 saved_handlers[4].code = 0;
785 #else
786 saved_handlers[3].code = 0;
787 #endif
789 /* Mentioning current_buffer->buffer would mean including buffer.h,
790 which somehow wedges the hp compiler. So instead... */
792 dir = intern ("default-directory");
793 if (NILP (Fboundp (dir)))
794 goto xyzzy;
795 dir = Fsymbol_value (dir);
796 if (!STRINGP (dir))
797 goto xyzzy;
799 dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
800 str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
801 len = XSTRING (dir)->size;
802 bcopy (XSTRING (dir)->data, str, len);
803 if (str[len - 1] != '/') str[len++] = '/';
804 str[len] = 0;
805 xyzzy:
807 #ifdef DOS_NT
808 pid = 0;
809 #if __DJGPP__ > 1
810 save_signal_handlers (saved_handlers);
811 synch_process_alive = 1;
812 #endif /* __DJGPP__ > 1 */
813 #else
814 pid = vfork ();
815 if (pid == -1)
816 error ("Can't spawn subshell");
817 #endif
819 if (pid == 0)
821 char *sh = 0;
823 #ifdef DOS_NT /* MW, Aug 1993 */
824 getwd (oldwd);
825 if (sh == 0)
826 sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
827 #endif
828 if (sh == 0)
829 sh = (char *) egetenv ("SHELL");
830 if (sh == 0)
831 sh = "sh";
833 /* Use our buffer's default directory for the subshell. */
834 if (str)
835 chdir ((char *) str);
837 #ifdef subprocesses
838 close_process_descs (); /* Close Emacs's pipes/ptys */
839 #endif
841 #ifdef SET_EMACS_PRIORITY
843 extern int emacs_priority;
845 if (emacs_priority < 0)
846 nice (-emacs_priority);
848 #endif
850 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
851 st = system (sh);
852 chdir (oldwd);
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 /* !macintosh */
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 old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
920 fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
921 #endif
922 interrupts_deferred = 0;
925 void
926 reset_sigio ()
928 unrequest_sigio ();
931 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
933 void
934 request_sigio ()
936 if (read_socket_hook)
937 return;
939 #ifdef SIGWINCH
940 sigunblock (sigmask (SIGWINCH));
941 #endif
942 fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
944 interrupts_deferred = 0;
947 void
948 unrequest_sigio ()
950 if (read_socket_hook)
951 return;
953 #ifdef SIGWINCH
954 sigblock (sigmask (SIGWINCH));
955 #endif
956 fcntl (input_fd, F_SETFL, old_fcntl_flags);
957 interrupts_deferred = 1;
960 #else /* no FASYNC */
961 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
963 void
964 request_sigio ()
966 int on = 1;
968 if (read_socket_hook)
969 return;
971 ioctl (input_fd, FIOASYNC, &on);
972 interrupts_deferred = 0;
975 void
976 unrequest_sigio ()
978 int off = 0;
980 if (read_socket_hook)
981 return;
983 ioctl (input_fd, FIOASYNC, &off);
984 interrupts_deferred = 1;
987 #else /* not FASYNC, not STRIDE */
989 #ifdef _CX_UX
991 #include <termios.h>
993 void
994 request_sigio ()
996 int on = 1;
997 sigset_t st;
999 if (read_socket_hook)
1000 return;
1002 sigemptyset (&st);
1003 sigaddset (&st, SIGIO);
1004 ioctl (input_fd, FIOASYNC, &on);
1005 interrupts_deferred = 0;
1006 sigprocmask (SIG_UNBLOCK, &st, (sigset_t *)0);
1009 void
1010 unrequest_sigio ()
1012 int off = 0;
1014 if (read_socket_hook)
1015 return;
1017 ioctl (input_fd, FIOASYNC, &off);
1018 interrupts_deferred = 1;
1021 #else /* ! _CX_UX */
1023 void
1024 request_sigio ()
1026 if (read_socket_hook)
1027 return;
1029 croak ("request_sigio");
1032 void
1033 unrequest_sigio ()
1035 if (read_socket_hook)
1036 return;
1038 croak ("unrequest_sigio");
1041 #endif /* _CX_UX */
1042 #endif /* STRIDE */
1043 #endif /* FASYNC */
1044 #endif /* F_SETFL */
1046 /* Saving and restoring the process group of Emacs's terminal. */
1048 #ifdef BSD_PGRPS
1050 /* The process group of which Emacs was a member when it initially
1051 started.
1053 If Emacs was in its own process group (i.e. inherited_pgroup ==
1054 getpid ()), then we know we're running under a shell with job
1055 control (Emacs would never be run as part of a pipeline).
1056 Everything is fine.
1058 If Emacs was not in its own process group, then we know we're
1059 running under a shell (or a caller) that doesn't know how to
1060 separate itself from Emacs (like sh). Emacs must be in its own
1061 process group in order to receive SIGIO correctly. In this
1062 situation, we put ourselves in our own pgroup, forcibly set the
1063 tty's pgroup to our pgroup, and make sure to restore and reinstate
1064 the tty's pgroup just like any other terminal setting. If
1065 inherited_group was not the tty's pgroup, then we'll get a
1066 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1067 it goes foreground in the future, which is what should happen. */
1068 int inherited_pgroup;
1070 /* Split off the foreground process group to Emacs alone.
1071 When we are in the foreground, but not started in our own process
1072 group, redirect the TTY to point to our own process group. We need
1073 to be in our own process group to receive SIGIO properly. */
1074 void
1075 narrow_foreground_group ()
1077 int me = getpid ();
1079 setpgrp (0, inherited_pgroup);
1080 if (inherited_pgroup != me)
1081 EMACS_SET_TTY_PGRP (input_fd, &me);
1082 setpgrp (0, me);
1085 /* Set the tty to our original foreground group. */
1086 void
1087 widen_foreground_group ()
1089 if (inherited_pgroup != getpid ())
1090 EMACS_SET_TTY_PGRP (input_fd, &inherited_pgroup);
1091 setpgrp (0, inherited_pgroup);
1094 #endif /* BSD_PGRPS */
1096 /* Getting and setting emacs_tty structures. */
1098 /* Set *TC to the parameters associated with the terminal FD.
1099 Return zero if all's well, or -1 if we ran into an error we
1100 couldn't deal with. */
1102 emacs_get_tty (fd, settings)
1103 int fd;
1104 struct emacs_tty *settings;
1106 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1107 #ifdef HAVE_TCATTR
1108 /* We have those nifty POSIX tcmumbleattr functions. */
1109 bzero (&settings->main, sizeof (settings->main));
1110 if (tcgetattr (fd, &settings->main) < 0)
1111 return -1;
1113 #else
1114 #ifdef HAVE_TERMIO
1115 /* The SYSV-style interface? */
1116 if (ioctl (fd, TCGETA, &settings->main) < 0)
1117 return -1;
1119 #else
1120 #ifdef VMS
1121 /* Vehemently Monstrous System? :-) */
1122 if (! (SYS$QIOW (0, fd, IO$_SENSEMODE, settings, 0, 0,
1123 &settings->main.class, 12, 0, 0, 0, 0)
1124 & 1))
1125 return -1;
1127 #else
1128 #ifndef DOS_NT
1129 /* I give up - I hope you have the BSD ioctls. */
1130 if (ioctl (fd, TIOCGETP, &settings->main) < 0)
1131 return -1;
1132 #endif /* not DOS_NT */
1133 #endif
1134 #endif
1135 #endif
1137 /* Suivant - Do we have to get struct ltchars data? */
1138 #ifdef HAVE_LTCHARS
1139 if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
1140 return -1;
1141 #endif
1143 /* How about a struct tchars and a wordful of lmode bits? */
1144 #ifdef HAVE_TCHARS
1145 if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
1146 || ioctl (fd, TIOCLGET, &settings->lmode) < 0)
1147 return -1;
1148 #endif
1150 /* We have survived the tempest. */
1151 return 0;
1155 /* Set the parameters of the tty on FD according to the contents of
1156 *SETTINGS. If FLUSHP is non-zero, we discard input.
1157 Return 0 if all went well, and -1 if anything failed. */
1160 emacs_set_tty (fd, settings, flushp)
1161 int fd;
1162 struct emacs_tty *settings;
1163 int flushp;
1165 /* Set the primary parameters - baud rate, character size, etcetera. */
1166 #ifdef HAVE_TCATTR
1167 int i;
1168 /* We have those nifty POSIX tcmumbleattr functions.
1169 William J. Smith <wjs@wiis.wang.com> writes:
1170 "POSIX 1003.1 defines tcsetattr to return success if it was
1171 able to perform any of the requested actions, even if some
1172 of the requested actions could not be performed.
1173 We must read settings back to ensure tty setup properly.
1174 AIX requires this to keep tty from hanging occasionally." */
1175 /* This make sure that we don't loop indefinitely in here. */
1176 for (i = 0 ; i < 10 ; i++)
1177 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
1179 if (errno == EINTR)
1180 continue;
1181 else
1182 return -1;
1184 else
1186 struct termios new;
1188 bzero (&new, sizeof (new));
1189 /* Get the current settings, and see if they're what we asked for. */
1190 tcgetattr (fd, &new);
1191 /* We cannot use memcmp on the whole structure here because under
1192 * aix386 the termios structure has some reserved field that may
1193 * not be filled in.
1195 if ( new.c_iflag == settings->main.c_iflag
1196 && new.c_oflag == settings->main.c_oflag
1197 && new.c_cflag == settings->main.c_cflag
1198 && new.c_lflag == settings->main.c_lflag
1199 && memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
1200 break;
1201 else
1202 continue;
1205 #else
1206 #ifdef HAVE_TERMIO
1207 /* The SYSV-style interface? */
1208 if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
1209 return -1;
1211 #else
1212 #ifdef VMS
1213 /* Vehemently Monstrous System? :-) */
1214 if (! (SYS$QIOW (0, fd, IO$_SETMODE, &input_iosb, 0, 0,
1215 &settings->main.class, 12, 0, 0, 0, 0)
1216 & 1))
1217 return -1;
1219 #else
1220 #ifndef DOS_NT
1221 /* I give up - I hope you have the BSD ioctls. */
1222 if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
1223 return -1;
1224 #endif /* not DOS_NT */
1226 #endif
1227 #endif
1228 #endif
1230 /* Suivant - Do we have to get struct ltchars data? */
1231 #ifdef HAVE_LTCHARS
1232 if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
1233 return -1;
1234 #endif
1236 /* How about a struct tchars and a wordful of lmode bits? */
1237 #ifdef HAVE_TCHARS
1238 if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
1239 || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
1240 return -1;
1241 #endif
1243 /* We have survived the tempest. */
1244 return 0;
1248 /* The initial tty mode bits */
1249 struct emacs_tty old_tty;
1251 /* 1 if we have been through init_sys_modes. */
1252 int term_initted;
1254 /* 1 if outer tty status has been recorded. */
1255 int old_tty_valid;
1257 #ifdef BSD4_1
1258 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1259 sigio. */
1260 int lmode;
1261 #endif
1263 #ifndef F_SETOWN_BUG
1264 #ifdef F_SETOWN
1265 int old_fcntl_owner;
1266 #endif /* F_SETOWN */
1267 #endif /* F_SETOWN_BUG */
1269 /* This may also be defined in stdio,
1270 but if so, this does no harm,
1271 and using the same name avoids wasting the other one's space. */
1273 #ifdef nec_ews_svr4
1274 extern char *_sobuf ;
1275 #else
1276 #if defined (USG) || defined (DGUX)
1277 unsigned char _sobuf[BUFSIZ+8];
1278 #else
1279 char _sobuf[BUFSIZ];
1280 #endif
1281 #endif
1283 #ifdef HAVE_LTCHARS
1284 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
1285 #endif
1286 #ifdef HAVE_TCHARS
1287 static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
1288 #endif
1290 void
1291 init_sys_modes ()
1293 struct emacs_tty tty;
1295 #ifdef macintosh
1296 /* cus-start.el complains if delete-exited-processes is not defined */
1297 #ifndef subprocesses
1298 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
1299 doc: /* *Non-nil means delete processes immediately when they exit.
1300 nil means don't delete them until `list-processes' is run. */);
1301 delete_exited_processes = 0;
1302 #endif
1303 #endif /* not macintosh */
1305 #ifdef VMS
1306 #if 0
1307 static int oob_chars[2] = {0, 1 << 7}; /* catch C-g's */
1308 extern int (*interrupt_signal) ();
1309 #endif
1310 #endif
1312 Vtty_erase_char = Qnil;
1314 if (noninteractive)
1315 return;
1317 #ifdef VMS
1318 if (!input_ef)
1319 input_ef = get_kbd_event_flag ();
1320 /* LIB$GET_EF (&input_ef); */
1321 SYS$CLREF (input_ef);
1322 waiting_for_ast = 0;
1323 if (!timer_ef)
1324 timer_ef = get_timer_event_flag ();
1325 /* LIB$GET_EF (&timer_ef); */
1326 SYS$CLREF (timer_ef);
1327 #if 0
1328 if (!process_ef)
1330 LIB$GET_EF (&process_ef);
1331 SYS$CLREF (process_ef);
1333 if (input_ef / 32 != process_ef / 32)
1334 croak ("Input and process event flags in different clusters.");
1335 #endif
1336 if (input_ef / 32 != timer_ef / 32)
1337 croak ("Input and timer event flags in different clusters.");
1338 #if 0
1339 input_eflist = ((unsigned) 1 << (input_ef % 32)) |
1340 ((unsigned) 1 << (process_ef % 32));
1341 #endif
1342 timer_eflist = ((unsigned) 1 << (input_ef % 32)) |
1343 ((unsigned) 1 << (timer_ef % 32));
1344 #ifndef VMS4_4
1345 sys_access_reinit ();
1346 #endif
1347 #endif /* not VMS */
1349 #ifdef BSD_PGRPS
1350 if (! read_socket_hook && EQ (Vwindow_system, Qnil))
1351 narrow_foreground_group ();
1352 #endif
1354 #ifdef HAVE_WINDOW_SYSTEM
1355 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1356 needs the initialization code below. */
1357 if (!read_socket_hook && EQ (Vwindow_system, Qnil))
1358 #endif
1360 EMACS_GET_TTY (input_fd, &old_tty);
1362 old_tty_valid = 1;
1364 tty = old_tty;
1366 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1367 XSETINT (Vtty_erase_char, old_tty.main.c_cc[VERASE]);
1369 #ifdef DGUX
1370 /* This allows meta to be sent on 8th bit. */
1371 tty.main.c_iflag &= ~INPCK; /* don't check input for parity */
1372 #endif
1373 tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
1374 tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
1375 #ifdef INLCR /* I'm just being cautious,
1376 since I can't check how widespread INLCR is--rms. */
1377 tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
1378 #endif
1379 #ifdef ISTRIP
1380 tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
1381 #endif
1382 tty.main.c_lflag &= ~ECHO; /* Disable echo */
1383 tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */
1384 #ifdef IEXTEN
1385 tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
1386 #endif
1387 tty.main.c_lflag |= ISIG; /* Enable signals */
1388 if (flow_control)
1390 tty.main.c_iflag |= IXON; /* Enable start/stop output control */
1391 #ifdef IXANY
1392 tty.main.c_iflag &= ~IXANY;
1393 #endif /* IXANY */
1395 else
1396 tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
1397 tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
1398 on output */
1399 tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */
1400 #ifdef CS8
1401 if (meta_key)
1403 tty.main.c_cflag |= CS8; /* allow 8th bit on input */
1404 tty.main.c_cflag &= ~PARENB;/* Don't check parity */
1406 #endif
1407 tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
1408 /* Set up C-g for both SIGQUIT and SIGINT.
1409 We don't know which we will get, but we handle both alike
1410 so which one it really gives us does not matter. */
1411 tty.main.c_cc[VQUIT] = quit_char;
1412 tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
1413 tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
1414 #ifdef VSWTCH
1415 tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
1416 of C-z */
1417 #endif /* VSWTCH */
1419 #if defined (mips) || defined (HAVE_TCATTR)
1420 #ifdef VSUSP
1421 tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
1422 #endif /* VSUSP */
1423 #ifdef V_DSUSP
1424 tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
1425 #endif /* V_DSUSP */
1426 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1427 tty.main.c_cc[VDSUSP] = CDISABLE;
1428 #endif /* VDSUSP */
1429 #ifdef VLNEXT
1430 tty.main.c_cc[VLNEXT] = CDISABLE;
1431 #endif /* VLNEXT */
1432 #ifdef VREPRINT
1433 tty.main.c_cc[VREPRINT] = CDISABLE;
1434 #endif /* VREPRINT */
1435 #ifdef VWERASE
1436 tty.main.c_cc[VWERASE] = CDISABLE;
1437 #endif /* VWERASE */
1438 #ifdef VDISCARD
1439 tty.main.c_cc[VDISCARD] = CDISABLE;
1440 #endif /* VDISCARD */
1442 if (flow_control)
1444 #ifdef VSTART
1445 tty.main.c_cc[VSTART] = '\021';
1446 #endif /* VSTART */
1447 #ifdef VSTOP
1448 tty.main.c_cc[VSTOP] = '\023';
1449 #endif /* VSTOP */
1451 else
1453 #ifdef VSTART
1454 tty.main.c_cc[VSTART] = CDISABLE;
1455 #endif /* VSTART */
1456 #ifdef VSTOP
1457 tty.main.c_cc[VSTOP] = CDISABLE;
1458 #endif /* VSTOP */
1460 #endif /* mips or HAVE_TCATTR */
1462 #ifdef SET_LINE_DISCIPLINE
1463 /* Need to explicitly request TERMIODISC line discipline or
1464 Ultrix's termios does not work correctly. */
1465 tty.main.c_line = SET_LINE_DISCIPLINE;
1466 #endif
1467 #ifdef AIX
1468 #ifndef IBMR2AIX
1469 /* AIX enhanced edit loses NULs, so disable it. */
1470 tty.main.c_line = 0;
1471 tty.main.c_iflag &= ~ASCEDIT;
1472 #else
1473 tty.main.c_cc[VSTRT] = 255;
1474 tty.main.c_cc[VSTOP] = 255;
1475 tty.main.c_cc[VSUSP] = 255;
1476 tty.main.c_cc[VDSUSP] = 255;
1477 #endif /* IBMR2AIX */
1478 if (flow_control)
1480 #ifdef VSTART
1481 tty.main.c_cc[VSTART] = '\021';
1482 #endif /* VSTART */
1483 #ifdef VSTOP
1484 tty.main.c_cc[VSTOP] = '\023';
1485 #endif /* VSTOP */
1487 /* Also, PTY overloads NUL and BREAK.
1488 don't ignore break, but don't signal either, so it looks like NUL.
1489 This really serves a purpose only if running in an XTERM window
1490 or via TELNET or the like, but does no harm elsewhere. */
1491 tty.main.c_iflag &= ~IGNBRK;
1492 tty.main.c_iflag &= ~BRKINT;
1493 #endif
1494 #else /* if not HAVE_TERMIO */
1495 #ifdef VMS
1496 tty.main.tt_char |= TT$M_NOECHO;
1497 if (meta_key)
1498 tty.main.tt_char |= TT$M_EIGHTBIT;
1499 if (flow_control)
1500 tty.main.tt_char |= TT$M_TTSYNC;
1501 else
1502 tty.main.tt_char &= ~TT$M_TTSYNC;
1503 tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
1504 #else /* not VMS (BSD, that is) */
1505 #ifndef DOS_NT
1506 XSETINT (Vtty_erase_char, tty.main.sg_erase);
1507 tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1508 if (meta_key)
1509 tty.main.sg_flags |= ANYP;
1510 tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
1511 #endif /* not DOS_NT */
1512 #endif /* not VMS (BSD, that is) */
1513 #endif /* not HAVE_TERMIO */
1515 /* If going to use CBREAK mode, we must request C-g to interrupt
1516 and turn off start and stop chars, etc. If not going to use
1517 CBREAK mode, do this anyway so as to turn off local flow
1518 control for user coming over network on 4.2; in this case,
1519 only t_stopc and t_startc really matter. */
1520 #ifndef HAVE_TERMIO
1521 #ifdef HAVE_TCHARS
1522 /* Note: if not using CBREAK mode, it makes no difference how we
1523 set this */
1524 tty.tchars = new_tchars;
1525 tty.tchars.t_intrc = quit_char;
1526 if (flow_control)
1528 tty.tchars.t_startc = '\021';
1529 tty.tchars.t_stopc = '\023';
1532 tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_tty.lmode;
1533 #ifdef ultrix
1534 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1535 anything, and leaving it in breaks the meta key. Go figure. */
1536 tty.lmode &= ~LLITOUT;
1537 #endif
1539 #ifdef BSD4_1
1540 lmode = tty.lmode;
1541 #endif
1543 #endif /* HAVE_TCHARS */
1544 #endif /* not HAVE_TERMIO */
1546 #ifdef HAVE_LTCHARS
1547 tty.ltchars = new_ltchars;
1548 #endif /* HAVE_LTCHARS */
1549 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1550 if (!term_initted)
1551 internal_terminal_init ();
1552 dos_ttraw ();
1553 #endif
1555 EMACS_SET_TTY (input_fd, &tty, 0);
1557 /* This code added to insure that, if flow-control is not to be used,
1558 we have an unlocked terminal at the start. */
1560 #ifdef TCXONC
1561 if (!flow_control) ioctl (input_fd, TCXONC, 1);
1562 #endif
1563 #ifndef APOLLO
1564 #ifdef TIOCSTART
1565 if (!flow_control) ioctl (input_fd, TIOCSTART, 0);
1566 #endif
1567 #endif
1569 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1570 #ifdef TCOON
1571 if (!flow_control) tcflow (input_fd, TCOON);
1572 #endif
1573 #endif
1575 #ifdef AIXHFT
1576 hft_init ();
1577 #ifdef IBMR2AIX
1579 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1580 to be only LF. This is the way that is done. */
1581 struct termio tty;
1583 if (ioctl (1, HFTGETID, &tty) != -1)
1584 write (1, "\033[20l", 5);
1586 #endif
1587 #endif /* AIXHFT */
1589 #ifdef VMS
1590 /* Appears to do nothing when in PASTHRU mode.
1591 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1592 interrupt_signal, oob_chars, 0, 0, 0, 0);
1594 queue_kbd_input (0);
1595 #endif /* VMS */
1598 #ifdef F_SETFL
1599 #ifndef F_SETOWN_BUG
1600 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1601 if (interrupt_input
1602 && ! read_socket_hook && EQ (Vwindow_system, Qnil))
1604 old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
1605 fcntl (input_fd, F_SETOWN, getpid ());
1606 init_sigio (input_fd);
1608 #endif /* F_GETOWN */
1609 #endif /* F_SETOWN_BUG */
1610 #endif /* F_SETFL */
1612 #ifdef BSD4_1
1613 if (interrupt_input)
1614 init_sigio (input_fd);
1615 #endif
1617 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1618 #undef _IOFBF
1619 #endif
1620 #ifdef _IOFBF
1621 /* This symbol is defined on recent USG systems.
1622 Someone says without this call USG won't really buffer the file
1623 even with a call to setbuf. */
1624 setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
1625 #else
1626 setbuf (stdout, (char *) _sobuf);
1627 #endif
1628 #ifdef HAVE_WINDOW_SYSTEM
1629 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1630 needs the initialization code below. */
1631 if (EQ (Vwindow_system, Qnil)
1632 #ifndef WINDOWSNT
1633 /* When running in tty mode on NT/Win95, we have a read_socket
1634 hook, but still need the rest of the initialization code below. */
1635 && (! read_socket_hook)
1636 #endif
1638 #endif
1639 set_terminal_modes ();
1641 if (!term_initted
1642 && FRAMEP (Vterminal_frame)
1643 && FRAME_TERMCAP_P (XFRAME (Vterminal_frame)))
1644 init_frame_faces (XFRAME (Vterminal_frame));
1646 if (term_initted && no_redraw_on_reenter)
1648 if (display_completed)
1649 direct_output_forward_char (0);
1651 else
1653 frame_garbaged = 1;
1654 if (FRAMEP (Vterminal_frame))
1655 FRAME_GARBAGED_P (XFRAME (Vterminal_frame)) = 1;
1658 term_initted = 1;
1661 /* Return nonzero if safe to use tabs in output.
1662 At the time this is called, init_sys_modes has not been done yet. */
1665 tabs_safe_p ()
1667 struct emacs_tty tty;
1669 EMACS_GET_TTY (input_fd, &tty);
1670 return EMACS_TTY_TABS_OK (&tty);
1673 /* Get terminal size from system.
1674 Store number of lines into *HEIGHTP and width into *WIDTHP.
1675 We store 0 if there's no valid information. */
1677 void
1678 get_frame_size (widthp, heightp)
1679 int *widthp, *heightp;
1682 #ifdef TIOCGWINSZ
1684 /* BSD-style. */
1685 struct winsize size;
1687 if (ioctl (input_fd, TIOCGWINSZ, &size) == -1)
1688 *widthp = *heightp = 0;
1689 else
1691 *widthp = size.ws_col;
1692 *heightp = size.ws_row;
1695 #else
1696 #ifdef TIOCGSIZE
1698 /* SunOS - style. */
1699 struct ttysize size;
1701 if (ioctl (input_fd, TIOCGSIZE, &size) == -1)
1702 *widthp = *heightp = 0;
1703 else
1705 *widthp = size.ts_cols;
1706 *heightp = size.ts_lines;
1709 #else
1710 #ifdef VMS
1712 struct sensemode tty;
1714 SYS$QIOW (0, input_fd, IO$_SENSEMODE, &tty, 0, 0,
1715 &tty.class, 12, 0, 0, 0, 0);
1716 *widthp = tty.scr_wid;
1717 *heightp = tty.scr_len;
1719 #else
1720 #ifdef MSDOS
1721 *widthp = ScreenCols ();
1722 *heightp = ScreenRows ();
1723 #else /* system doesn't know size */
1724 *widthp = 0;
1725 *heightp = 0;
1726 #endif
1728 #endif /* not VMS */
1729 #endif /* not SunOS-style */
1730 #endif /* not BSD-style */
1733 /* Set the logical window size associated with descriptor FD
1734 to HEIGHT and WIDTH. This is used mainly with ptys. */
1737 set_window_size (fd, height, width)
1738 int fd, height, width;
1740 #ifdef TIOCSWINSZ
1742 /* BSD-style. */
1743 struct winsize size;
1744 size.ws_row = height;
1745 size.ws_col = width;
1747 if (ioctl (fd, TIOCSWINSZ, &size) == -1)
1748 return 0; /* error */
1749 else
1750 return 1;
1752 #else
1753 #ifdef TIOCSSIZE
1755 /* SunOS - style. */
1756 struct ttysize size;
1757 size.ts_lines = height;
1758 size.ts_cols = width;
1760 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1761 return 0;
1762 else
1763 return 1;
1764 #else
1765 return -1;
1766 #endif /* not SunOS-style */
1767 #endif /* not BSD-style */
1771 /* Prepare the terminal for exiting Emacs; move the cursor to the
1772 bottom of the frame, turn off interrupt-driven I/O, etc. */
1773 void
1774 reset_sys_modes ()
1776 struct frame *sf;
1778 if (noninteractive)
1780 fflush (stdout);
1781 return;
1783 if (!term_initted)
1784 return;
1785 #ifdef HAVE_WINDOW_SYSTEM
1786 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1787 needs the clean-up code below. */
1788 if (!EQ (Vwindow_system, Qnil)
1789 #ifndef WINDOWSNT
1790 /* When running in tty mode on NT/Win95, we have a read_socket
1791 hook, but still need the rest of the clean-up code below. */
1792 || read_socket_hook
1793 #endif
1795 return;
1796 #endif
1797 sf = SELECTED_FRAME ();
1798 cursor_to (FRAME_HEIGHT (sf) - 1, 0);
1799 clear_end_of_line (FRAME_WIDTH (sf));
1800 /* clear_end_of_line may move the cursor */
1801 cursor_to (FRAME_HEIGHT (sf) - 1, 0);
1802 #if defined (IBMR2AIX) && defined (AIXHFT)
1804 /* HFT devices normally use ^J as a LF/CR. We forced it to
1805 do the LF only. Now, we need to reset it. */
1806 struct termio tty;
1808 if (ioctl (1, HFTGETID, &tty) != -1)
1809 write (1, "\033[20h", 5);
1811 #endif
1813 reset_terminal_modes ();
1814 fflush (stdout);
1815 #ifdef BSD_SYSTEM
1816 #ifndef BSD4_1
1817 /* Avoid possible loss of output when changing terminal modes. */
1818 fsync (fileno (stdout));
1819 #endif
1820 #endif
1822 #ifdef F_SETFL
1823 #ifndef F_SETOWN_BUG
1824 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1825 if (interrupt_input)
1827 reset_sigio ();
1828 fcntl (input_fd, F_SETOWN, old_fcntl_owner);
1830 #endif /* F_SETOWN */
1831 #endif /* F_SETOWN_BUG */
1832 #ifdef O_NDELAY
1833 fcntl (input_fd, F_SETFL, fcntl (input_fd, F_GETFL, 0) & ~O_NDELAY);
1834 #endif
1835 #endif /* F_SETFL */
1836 #ifdef BSD4_1
1837 if (interrupt_input)
1838 reset_sigio ();
1839 #endif /* BSD4_1 */
1841 if (old_tty_valid)
1842 while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR)
1845 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1846 dos_ttcooked ();
1847 #endif
1849 #ifdef SET_LINE_DISCIPLINE
1850 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1851 A different old line discipline is therefore not restored, yet.
1852 Restore the old line discipline by hand. */
1853 ioctl (0, TIOCSETD, &old_tty.main.c_line);
1854 #endif
1856 #ifdef AIXHFT
1857 hft_reset ();
1858 #endif
1860 #ifdef BSD_PGRPS
1861 widen_foreground_group ();
1862 #endif
1865 #ifdef HAVE_PTYS
1867 /* Set up the proper status flags for use of a pty. */
1869 void
1870 setup_pty (fd)
1871 int fd;
1873 /* I'm told that TOICREMOTE does not mean control chars
1874 "can't be sent" but rather that they don't have
1875 input-editing or signaling effects.
1876 That should be good, because we have other ways
1877 to do those things in Emacs.
1878 However, telnet mode seems not to work on 4.2.
1879 So TIOCREMOTE is turned off now. */
1881 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1882 will hang. In particular, the "timeout" feature (which
1883 causes a read to return if there is no data available)
1884 does this. Also it is known that telnet mode will hang
1885 in such a way that Emacs must be stopped (perhaps this
1886 is the same problem).
1888 If TIOCREMOTE is turned off, then there is a bug in
1889 hp-ux which sometimes loses data. Apparently the
1890 code which blocks the master process when the internal
1891 buffer fills up does not work. Other than this,
1892 though, everything else seems to work fine.
1894 Since the latter lossage is more benign, we may as well
1895 lose that way. -- cph */
1896 #ifdef FIONBIO
1897 #if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
1899 int on = 1;
1900 ioctl (fd, FIONBIO, &on);
1902 #endif
1903 #endif
1904 #ifdef IBMRTAIX
1905 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1906 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1907 /* cause EMACS not to die when it should, i.e., when its own controlling */
1908 /* tty goes away. I've complained to the AIX developers, and they may */
1909 /* change this behavior, but I'm not going to hold my breath. */
1910 signal (SIGHUP, SIG_IGN);
1911 #endif
1913 #endif /* HAVE_PTYS */
1915 #ifdef VMS
1917 /* Assigning an input channel is done at the start of Emacs execution.
1918 This is called each time Emacs is resumed, also, but does nothing
1919 because input_chain is no longer zero. */
1921 void
1922 init_vms_input ()
1924 int status;
1926 if (input_fd == 0)
1928 status = SYS$ASSIGN (&input_dsc, &input_fd, 0, 0);
1929 if (! (status & 1))
1930 LIB$STOP (status);
1934 /* Deassigning the input channel is done before exiting. */
1936 void
1937 stop_vms_input ()
1939 return SYS$DASSGN (input_fd);
1942 short input_buffer;
1944 /* Request reading one character into the keyboard buffer.
1945 This is done as soon as the buffer becomes empty. */
1947 void
1948 queue_kbd_input ()
1950 int status;
1951 extern kbd_input_ast ();
1953 waiting_for_ast = 0;
1954 stop_input = 0;
1955 status = SYS$QIO (0, input_fd, IO$_READVBLK,
1956 &input_iosb, kbd_input_ast, 1,
1957 &input_buffer, 1, 0, terminator_mask, 0, 0);
1960 int input_count;
1962 /* Ast routine that is called when keyboard input comes in
1963 in accord with the SYS$QIO above. */
1965 void
1966 kbd_input_ast ()
1968 register int c = -1;
1969 int old_errno = errno;
1970 extern EMACS_TIME *input_available_clear_time;
1972 if (waiting_for_ast)
1973 SYS$SETEF (input_ef);
1974 waiting_for_ast = 0;
1975 input_count++;
1976 #ifdef ASTDEBUG
1977 if (input_count == 25)
1978 exit (1);
1979 printf ("Ast # %d,", input_count);
1980 printf (" iosb = %x, %x, %x, %x",
1981 input_iosb.offset, input_iosb.status, input_iosb.termlen,
1982 input_iosb.term);
1983 #endif
1984 if (input_iosb.offset)
1986 c = input_buffer;
1987 #ifdef ASTDEBUG
1988 printf (", char = 0%o", c);
1989 #endif
1991 #ifdef ASTDEBUG
1992 printf ("\n");
1993 fflush (stdout);
1994 sleep (1);
1995 #endif
1996 if (! stop_input)
1997 queue_kbd_input ();
1998 if (c >= 0)
2000 struct input_event e;
2001 e.kind = ascii_keystroke;
2002 XSETINT (e.code, c);
2003 e.frame_or_window = selected_frame;
2004 kbd_buffer_store_event (&e);
2006 if (input_available_clear_time)
2007 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
2008 errno = old_errno;
2011 /* Wait until there is something in kbd_buffer. */
2013 void
2014 wait_for_kbd_input ()
2016 extern int have_process_input, process_exited;
2018 /* If already something, avoid doing system calls. */
2019 if (detect_input_pending ())
2021 return;
2023 /* Clear a flag, and tell ast routine above to set it. */
2024 SYS$CLREF (input_ef);
2025 waiting_for_ast = 1;
2026 /* Check for timing error: ast happened while we were doing that. */
2027 if (!detect_input_pending ())
2029 /* No timing error: wait for flag to be set. */
2030 set_waiting_for_input (0);
2031 SYS$WFLOR (input_ef, input_eflist);
2032 clear_waiting_for_input ();
2033 if (!detect_input_pending ())
2034 /* Check for subprocess input availability */
2036 int dsp = have_process_input || process_exited;
2038 SYS$CLREF (process_ef);
2039 if (have_process_input)
2040 process_command_input ();
2041 if (process_exited)
2042 process_exit ();
2043 if (dsp)
2045 update_mode_lines++;
2046 prepare_menu_bars ();
2047 redisplay_preserve_echo_area (18);
2051 waiting_for_ast = 0;
2054 /* Get rid of any pending QIO, when we are about to suspend
2055 or when we want to throw away pending input.
2056 We wait for a positive sign that the AST routine has run
2057 and therefore there is no I/O request queued when we return.
2058 SYS$SETAST is used to avoid a timing error. */
2060 void
2061 end_kbd_input ()
2063 #ifdef ASTDEBUG
2064 printf ("At end_kbd_input.\n");
2065 fflush (stdout);
2066 sleep (1);
2067 #endif
2068 if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2070 SYS$CANCEL (input_fd);
2071 return;
2074 SYS$SETAST (0);
2075 /* Clear a flag, and tell ast routine above to set it. */
2076 SYS$CLREF (input_ef);
2077 waiting_for_ast = 1;
2078 stop_input = 1;
2079 SYS$CANCEL (input_fd);
2080 SYS$SETAST (1);
2081 SYS$WAITFR (input_ef);
2082 waiting_for_ast = 0;
2085 /* Wait for either input available or time interval expiry. */
2087 void
2088 input_wait_timeout (timeval)
2089 int timeval; /* Time to wait, in seconds */
2091 int time [2];
2092 static int zero = 0;
2093 static int large = -10000000;
2095 LIB$EMUL (&timeval, &large, &zero, time); /* Convert to VMS format */
2097 /* If already something, avoid doing system calls. */
2098 if (detect_input_pending ())
2100 return;
2102 /* Clear a flag, and tell ast routine above to set it. */
2103 SYS$CLREF (input_ef);
2104 waiting_for_ast = 1;
2105 /* Check for timing error: ast happened while we were doing that. */
2106 if (!detect_input_pending ())
2108 /* No timing error: wait for flag to be set. */
2109 SYS$CANTIM (1, 0);
2110 if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
2111 SYS$WFLOR (timer_ef, timer_eflist); /* Wait for timer expiry or input */
2113 waiting_for_ast = 0;
2116 /* The standard `sleep' routine works some other way
2117 and it stops working if you have ever quit out of it.
2118 This one continues to work. */
2120 sys_sleep (timeval)
2121 int timeval;
2123 int time [2];
2124 static int zero = 0;
2125 static int large = -10000000;
2127 LIB$EMUL (&timeval, &large, &zero, time); /* Convert to VMS format */
2129 SYS$CANTIM (1, 0);
2130 if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
2131 SYS$WAITFR (timer_ef); /* Wait for timer expiry only */
2134 void
2135 init_sigio (fd)
2136 int fd;
2138 request_sigio ();
2141 reset_sigio ()
2143 unrequest_sigio ();
2146 void
2147 request_sigio ()
2149 croak ("request sigio");
2152 void
2153 unrequest_sigio ()
2155 croak ("unrequest sigio");
2158 #endif /* VMS */
2160 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2161 #ifndef CANNOT_DUMP
2162 #define NEED_STARTS
2163 #endif
2165 #ifndef SYSTEM_MALLOC
2166 #ifndef NEED_STARTS
2167 #define NEED_STARTS
2168 #endif
2169 #endif
2171 #ifdef NEED_STARTS
2172 /* Some systems that cannot dump also cannot implement these. */
2175 * Return the address of the start of the text segment prior to
2176 * doing an unexec. After unexec the return value is undefined.
2177 * See crt0.c for further explanation and _start.
2181 #if !(defined (__NetBSD__) && defined (__ELF__))
2182 #ifndef HAVE_TEXT_START
2183 char *
2184 start_of_text ()
2186 #ifdef TEXT_START
2187 return ((char *) TEXT_START);
2188 #else
2189 #ifdef GOULD
2190 extern csrt ();
2191 return ((char *) csrt);
2192 #else /* not GOULD */
2193 extern int _start ();
2194 return ((char *) _start);
2195 #endif /* GOULD */
2196 #endif /* TEXT_START */
2198 #endif /* not HAVE_TEXT_START */
2199 #endif
2202 * Return the address of the start of the data segment prior to
2203 * doing an unexec. After unexec the return value is undefined.
2204 * See crt0.c for further information and definition of data_start.
2206 * Apparently, on BSD systems this is etext at startup. On
2207 * USG systems (swapping) this is highly mmu dependent and
2208 * is also dependent on whether or not the program is running
2209 * with shared text. Generally there is a (possibly large)
2210 * gap between end of text and start of data with shared text.
2212 * On Uniplus+ systems with shared text, data starts at a
2213 * fixed address. Each port (from a given oem) is generally
2214 * different, and the specific value of the start of data can
2215 * be obtained via the UniPlus+ specific "uvar" system call,
2216 * however the method outlined in crt0.c seems to be more portable.
2218 * Probably what will have to happen when a USG unexec is available,
2219 * at least on UniPlus, is temacs will have to be made unshared so
2220 * that text and data are contiguous. Then once loadup is complete,
2221 * unexec will produce a shared executable where the data can be
2222 * at the normal shared text boundary and the startofdata variable
2223 * will be patched by unexec to the correct value.
2227 char *
2228 start_of_data ()
2230 #ifdef DATA_START
2231 return ((char *) DATA_START);
2232 #else
2233 #ifdef ORDINARY_LINK
2235 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2236 * data_start isn't defined. We take the address of environ, which
2237 * is known to live at or near the start of the system crt0.c, and
2238 * we don't sweat the handful of bytes that might lose.
2240 extern char **environ;
2242 return ((char *) &environ);
2243 #else
2244 extern int data_start;
2245 return ((char *) &data_start);
2246 #endif /* ORDINARY_LINK */
2247 #endif /* DATA_START */
2249 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2251 #ifndef CANNOT_DUMP
2252 /* Some systems that cannot dump also cannot implement these. */
2255 * Return the address of the end of the text segment prior to
2256 * doing an unexec. After unexec the return value is undefined.
2259 char *
2260 end_of_text ()
2262 #ifdef TEXT_END
2263 return ((char *) TEXT_END);
2264 #else
2265 extern int etext;
2266 return ((char *) &etext);
2267 #endif
2271 * Return the address of the end of the data segment prior to
2272 * doing an unexec. After unexec the return value is undefined.
2275 char *
2276 end_of_data ()
2278 #ifdef DATA_END
2279 return ((char *) DATA_END);
2280 #else
2281 extern int edata;
2282 return ((char *) &edata);
2283 #endif
2286 #endif /* not CANNOT_DUMP */
2288 /* init_system_name sets up the string for the Lisp function
2289 system-name to return. */
2291 #ifdef BSD4_1
2292 #include <whoami.h>
2293 #endif
2295 extern Lisp_Object Vsystem_name;
2297 #ifndef BSD4_1
2298 #ifndef VMS
2299 #ifdef HAVE_SOCKETS
2300 #include <sys/socket.h>
2301 #include <netdb.h>
2302 #endif /* HAVE_SOCKETS */
2303 #endif /* not VMS */
2304 #endif /* not BSD4_1 */
2306 #ifdef TRY_AGAIN
2307 #ifndef HAVE_H_ERRNO
2308 extern int h_errno;
2309 #endif
2310 #endif /* TRY_AGAIN */
2312 void
2313 init_system_name ()
2315 #ifdef BSD4_1
2316 Vsystem_name = build_string (sysname);
2317 #else
2318 #ifdef VMS
2319 char *sp, *end;
2320 if ((sp = egetenv ("SYS$NODE")) == 0)
2321 Vsystem_name = build_string ("vax-vms");
2322 else if ((end = index (sp, ':')) == 0)
2323 Vsystem_name = build_string (sp);
2324 else
2325 Vsystem_name = make_string (sp, end - sp);
2326 #else
2327 #ifndef HAVE_GETHOSTNAME
2328 struct utsname uts;
2329 uname (&uts);
2330 Vsystem_name = build_string (uts.nodename);
2331 #else /* HAVE_GETHOSTNAME */
2332 unsigned int hostname_size = 256;
2333 char *hostname = (char *) alloca (hostname_size);
2335 /* Try to get the host name; if the buffer is too short, try
2336 again. Apparently, the only indication gethostname gives of
2337 whether the buffer was large enough is the presence or absence
2338 of a '\0' in the string. Eech. */
2339 for (;;)
2341 gethostname (hostname, hostname_size - 1);
2342 hostname[hostname_size - 1] = '\0';
2344 /* Was the buffer large enough for the '\0'? */
2345 if (strlen (hostname) < hostname_size - 1)
2346 break;
2348 hostname_size <<= 1;
2349 hostname = (char *) alloca (hostname_size);
2351 #ifdef HAVE_SOCKETS
2352 /* Turn the hostname into the official, fully-qualified hostname.
2353 Don't do this if we're going to dump; this can confuse system
2354 libraries on some machines and make the dumped emacs core dump. */
2355 #ifndef CANNOT_DUMP
2356 if (initialized)
2357 #endif /* not CANNOT_DUMP */
2358 if (! index (hostname, '.'))
2360 struct hostent *hp;
2361 int count;
2362 for (count = 0;; count++)
2364 #ifdef TRY_AGAIN
2365 h_errno = 0;
2366 #endif
2367 hp = gethostbyname (hostname);
2368 #ifdef TRY_AGAIN
2369 if (! (hp == 0 && h_errno == TRY_AGAIN))
2370 #endif
2371 break;
2372 if (count >= 5)
2373 break;
2374 Fsleep_for (make_number (1), Qnil);
2376 if (hp)
2378 char *fqdn = (char *) hp->h_name;
2379 char *p;
2381 if (!index (fqdn, '.'))
2383 /* We still don't have a fully qualified domain name.
2384 Try to find one in the list of alternate names */
2385 char **alias = hp->h_aliases;
2386 while (*alias && !index (*alias, '.'))
2387 alias++;
2388 if (*alias)
2389 fqdn = *alias;
2391 hostname = fqdn;
2392 #if 0
2393 /* Convert the host name to lower case. */
2394 /* Using ctype.h here would introduce a possible locale
2395 dependence that is probably wrong for hostnames. */
2396 p = hostname;
2397 while (*p)
2399 if (*p >= 'A' && *p <= 'Z')
2400 *p += 'a' - 'A';
2401 p++;
2403 #endif
2406 #endif /* HAVE_SOCKETS */
2407 /* We used to try using getdomainname here,
2408 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2409 getdomainname gets the NIS/YP domain which often is not the same
2410 as in Internet domain name. */
2411 #if 0 /* Turned off because sysinfo is not really likely to return the
2412 correct Internet domain. */
2413 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2414 if (! index (hostname, '.'))
2416 /* The hostname is not fully qualified. Append the domain name. */
2418 int hostlen = strlen (hostname);
2419 int domain_size = 256;
2421 for (;;)
2423 char *domain = (char *) alloca (domain_size + 1);
2424 char *fqdn = (char *) alloca (hostlen + 1 + domain_size + 1);
2425 int sys_domain_size = sysinfo (SI_SRPC_DOMAIN, domain, domain_size);
2426 if (sys_domain_size <= 0)
2427 break;
2428 if (domain_size < sys_domain_size)
2430 domain_size = sys_domain_size;
2431 continue;
2433 strcpy (fqdn, hostname);
2434 if (domain[0] == '.')
2435 strcpy (fqdn + hostlen, domain);
2436 else if (domain[0] != 0)
2438 fqdn[hostlen] = '.';
2439 strcpy (fqdn + hostlen + 1, domain);
2441 hostname = fqdn;
2442 break;
2445 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2446 #endif /* 0 */
2447 Vsystem_name = build_string (hostname);
2448 #endif /* HAVE_GETHOSTNAME */
2449 #endif /* VMS */
2450 #endif /* BSD4_1 */
2452 unsigned char *p;
2453 for (p = XSTRING (Vsystem_name)->data; *p; p++)
2454 if (*p == ' ' || *p == '\t')
2455 *p = '-';
2459 #ifndef MSDOS
2460 #ifndef VMS
2461 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2463 #include "sysselect.h"
2464 #undef select
2466 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2467 /* Cause explanatory error message at compile time,
2468 since the select emulation is not good enough for X. */
2469 int *x = &x_windows_lose_if_no_select_system_call;
2470 #endif
2472 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2473 * Only checks read descriptors.
2475 /* How long to wait between checking fds in select */
2476 #define SELECT_PAUSE 1
2477 int select_alarmed;
2479 /* For longjmp'ing back to read_input_waiting. */
2481 jmp_buf read_alarm_throw;
2483 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2484 The read_socket_hook function sets this to 1 while it is waiting. */
2486 int read_alarm_should_throw;
2488 SIGTYPE
2489 select_alarm ()
2491 select_alarmed = 1;
2492 #ifdef BSD4_1
2493 sigrelse (SIGALRM);
2494 #else /* not BSD4_1 */
2495 signal (SIGALRM, SIG_IGN);
2496 #endif /* not BSD4_1 */
2497 if (read_alarm_should_throw)
2498 longjmp (read_alarm_throw, 1);
2501 #ifndef WINDOWSNT
2502 /* Only rfds are checked. */
2504 sys_select (nfds, rfds, wfds, efds, timeout)
2505 int nfds;
2506 SELECT_TYPE *rfds, *wfds, *efds;
2507 EMACS_TIME *timeout;
2509 int ravail = 0;
2510 SELECT_TYPE orfds;
2511 int timeoutval;
2512 int *local_timeout;
2513 extern int proc_buffered_char[];
2514 #ifndef subprocesses
2515 int process_tick = 0, update_tick = 0;
2516 #else
2517 extern int process_tick, update_tick;
2518 #endif
2519 unsigned char buf;
2521 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2522 /* If we're using X, then the native select will work; we only need the
2523 emulation for non-X usage. */
2524 if (!NILP (Vwindow_system))
2525 return select (nfds, rfds, wfds, efds, timeout);
2526 #endif
2527 timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
2528 local_timeout = &timeoutval;
2529 FD_ZERO (&orfds);
2530 if (rfds)
2532 orfds = *rfds;
2533 FD_ZERO (rfds);
2535 if (wfds)
2536 FD_ZERO (wfds);
2537 if (efds)
2538 FD_ZERO (efds);
2540 /* If we are looking only for the terminal, with no timeout,
2541 just read it and wait -- that's more efficient. */
2542 if (*local_timeout == 100000 && process_tick == update_tick
2543 && FD_ISSET (0, &orfds))
2545 int fd;
2546 for (fd = 1; fd < nfds; ++fd)
2547 if (FD_ISSET (fd, &orfds))
2548 goto hardway;
2549 if (! detect_input_pending ())
2550 read_input_waiting ();
2551 FD_SET (0, rfds);
2552 return 1;
2555 hardway:
2556 /* Once a second, till the timer expires, check all the flagged read
2557 * descriptors to see if any input is available. If there is some then
2558 * set the corresponding bit in the return copy of rfds.
2560 while (1)
2562 register int to_check, fd;
2564 if (rfds)
2566 for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
2568 if (FD_ISSET (fd, &orfds))
2570 int avail = 0, status = 0;
2572 if (fd == 0)
2573 avail = detect_input_pending (); /* Special keyboard handler */
2574 else
2576 #ifdef FIONREAD
2577 status = ioctl (fd, FIONREAD, &avail);
2578 #else /* no FIONREAD */
2579 /* Hoping it will return -1 if nothing available
2580 or 0 if all 0 chars requested are read. */
2581 if (proc_buffered_char[fd] >= 0)
2582 avail = 1;
2583 else
2585 avail = read (fd, &buf, 1);
2586 if (avail > 0)
2587 proc_buffered_char[fd] = buf;
2589 #endif /* no FIONREAD */
2591 if (status >= 0 && avail > 0)
2593 FD_SET (fd, rfds);
2594 ravail++;
2599 if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
2600 break;
2602 turn_on_atimers (0);
2603 signal (SIGALRM, select_alarm);
2604 select_alarmed = 0;
2605 alarm (SELECT_PAUSE);
2607 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2608 while (select_alarmed == 0 && *local_timeout != 0
2609 && process_tick == update_tick)
2611 /* If we are interested in terminal input,
2612 wait by reading the terminal.
2613 That makes instant wakeup for terminal input at least. */
2614 if (FD_ISSET (0, &orfds))
2616 read_input_waiting ();
2617 if (detect_input_pending ())
2618 select_alarmed = 1;
2620 else
2621 pause ();
2623 (*local_timeout) -= SELECT_PAUSE;
2625 /* Reset the old alarm if there was one. */
2626 turn_on_atimers (1);
2628 if (*local_timeout == 0) /* Stop on timer being cleared */
2629 break;
2631 return ravail;
2633 #endif /* not WINDOWSNT */
2635 /* Read keyboard input into the standard buffer,
2636 waiting for at least one character. */
2638 /* Make all keyboard buffers much bigger when using a window system. */
2639 #ifdef HAVE_WINDOW_SYSTEM
2640 #define BUFFER_SIZE_FACTOR 16
2641 #else
2642 #define BUFFER_SIZE_FACTOR 1
2643 #endif
2645 void
2646 read_input_waiting ()
2648 struct input_event e;
2649 int nread, i;
2650 extern int quit_char;
2652 if (read_socket_hook)
2654 struct input_event buf[256];
2656 read_alarm_should_throw = 0;
2657 if (! setjmp (read_alarm_throw))
2658 nread = (*read_socket_hook) (0, buf, 256, 1);
2659 else
2660 nread = -1;
2662 /* Scan the chars for C-g and store them in kbd_buffer. */
2663 for (i = 0; i < nread; i++)
2665 kbd_buffer_store_event (&buf[i]);
2666 /* Don't look at input that follows a C-g too closely.
2667 This reduces lossage due to autorepeat on C-g. */
2668 if (buf[i].kind == ascii_keystroke
2669 && buf[i].code == quit_char)
2670 break;
2673 else
2675 char buf[3];
2676 nread = read (fileno (stdin), buf, 1);
2678 /* Scan the chars for C-g and store them in kbd_buffer. */
2679 e.kind = ascii_keystroke;
2680 e.frame_or_window = selected_frame;
2681 e.modifiers = 0;
2682 for (i = 0; i < nread; i++)
2684 /* Convert chars > 0177 to meta events if desired.
2685 We do this under the same conditions that read_avail_input does. */
2686 if (read_socket_hook == 0)
2688 /* If the user says she has a meta key, then believe her. */
2689 if (meta_key == 1 && (buf[i] & 0x80))
2690 e.modifiers = meta_modifier;
2691 if (meta_key != 2)
2692 buf[i] &= ~0x80;
2695 XSETINT (e.code, buf[i]);
2696 kbd_buffer_store_event (&e);
2697 /* Don't look at input that follows a C-g too closely.
2698 This reduces lossage due to autorepeat on C-g. */
2699 if (buf[i] == quit_char)
2700 break;
2705 #endif /* not HAVE_SELECT */
2706 #endif /* not VMS */
2707 #endif /* not MSDOS */
2709 #ifdef BSD4_1
2710 void
2711 init_sigio (fd)
2712 int fd;
2714 if (noninteractive)
2715 return;
2716 lmode = LINTRUP | lmode;
2717 ioctl (fd, TIOCLSET, &lmode);
2720 void
2721 reset_sigio ()
2723 if (noninteractive)
2724 return;
2725 lmode = ~LINTRUP & lmode;
2726 ioctl (0, TIOCLSET, &lmode);
2729 void
2730 request_sigio ()
2732 sigrelse (SIGTINT);
2734 interrupts_deferred = 0;
2737 void
2738 unrequest_sigio ()
2740 sighold (SIGTINT);
2742 interrupts_deferred = 1;
2745 /* still inside #ifdef BSD4_1 */
2746 #ifdef subprocesses
2748 int sigheld; /* Mask of held signals */
2750 void
2751 sigholdx (signum)
2752 int signum;
2754 sigheld |= sigbit (signum);
2755 sighold (signum);
2758 void
2759 sigisheld (signum)
2760 int signum;
2762 sigheld |= sigbit (signum);
2765 void
2766 sigunhold (signum)
2767 int signum;
2769 sigheld &= ~sigbit (signum);
2770 sigrelse (signum);
2773 void
2774 sigfree () /* Free all held signals */
2776 int i;
2777 for (i = 0; i < NSIG; i++)
2778 if (sigheld & sigbit (i))
2779 sigrelse (i);
2780 sigheld = 0;
2784 sigbit (i)
2786 return 1 << (i - 1);
2788 #endif /* subprocesses */
2789 #endif /* BSD4_1 */
2791 /* POSIX signals support - DJB */
2792 /* Anyone with POSIX signals should have ANSI C declarations */
2794 #ifdef POSIX_SIGNALS
2796 sigset_t empty_mask, full_mask;
2798 signal_handler_t
2799 sys_signal (int signal_number, signal_handler_t action)
2801 struct sigaction new_action, old_action;
2802 sigemptyset (&new_action.sa_mask);
2803 new_action.sa_handler = action;
2804 #ifdef SA_RESTART
2805 /* Emacs mostly works better with restartable system services. If this
2806 * flag exists, we probably want to turn it on here.
2808 new_action.sa_flags = SA_RESTART;
2809 #else
2810 new_action.sa_flags = 0;
2811 #endif
2812 sigaction (signal_number, &new_action, &old_action);
2813 return (old_action.sa_handler);
2816 #ifndef __GNUC__
2817 /* If we're compiling with GCC, we don't need this function, since it
2818 can be written as a macro. */
2819 sigset_t
2820 sys_sigmask (int sig)
2822 sigset_t mask;
2823 sigemptyset (&mask);
2824 sigaddset (&mask, sig);
2825 return mask;
2827 #endif
2829 /* I'd like to have these guys return pointers to the mask storage in here,
2830 but there'd be trouble if the code was saving multiple masks. I'll be
2831 safe and pass the structure. It normally won't be more than 2 bytes
2832 anyhow. - DJB */
2834 sigset_t
2835 sys_sigblock (sigset_t new_mask)
2837 sigset_t old_mask;
2838 sigprocmask (SIG_BLOCK, &new_mask, &old_mask);
2839 return (old_mask);
2842 sigset_t
2843 sys_sigunblock (sigset_t new_mask)
2845 sigset_t old_mask;
2846 sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask);
2847 return (old_mask);
2850 sigset_t
2851 sys_sigsetmask (sigset_t new_mask)
2853 sigset_t old_mask;
2854 sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
2855 return (old_mask);
2858 #endif /* POSIX_SIGNALS */
2860 #if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
2861 static char *my_sys_siglist[NSIG];
2862 # ifdef sys_siglist
2863 # undef sys_siglist
2864 # endif
2865 # define sys_siglist my_sys_siglist
2866 #endif
2868 void
2869 init_signals ()
2871 #ifdef POSIX_SIGNALS
2872 sigemptyset (&empty_mask);
2873 sigfillset (&full_mask);
2874 #endif
2876 #if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
2877 if (! initialized)
2879 # ifdef SIGABRT
2880 sys_siglist[SIGABRT] = "Aborted";
2881 # endif
2882 # ifdef SIGAIO
2883 sys_siglist[SIGAIO] = "LAN I/O interrupt";
2884 # endif
2885 # ifdef SIGALRM
2886 sys_siglist[SIGALRM] = "Alarm clock";
2887 # endif
2888 # ifdef SIGBUS
2889 sys_siglist[SIGBUS] = "Bus error";
2890 # endif
2891 # ifdef SIGCLD
2892 sys_siglist[SIGCLD] = "Child status changed";
2893 # endif
2894 # ifdef SIGCHLD
2895 sys_siglist[SIGCHLD] = "Child status changed";
2896 # endif
2897 # ifdef SIGCONT
2898 sys_siglist[SIGCONT] = "Continued";
2899 # endif
2900 # ifdef SIGDANGER
2901 sys_siglist[SIGDANGER] = "Swap space dangerously low";
2902 # endif
2903 # ifdef SIGDGNOTIFY
2904 sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
2905 # endif
2906 # ifdef SIGEMT
2907 sys_siglist[SIGEMT] = "Emulation trap";
2908 # endif
2909 # ifdef SIGFPE
2910 sys_siglist[SIGFPE] = "Arithmetic exception";
2911 # endif
2912 # ifdef SIGFREEZE
2913 sys_siglist[SIGFREEZE] = "SIGFREEZE";
2914 # endif
2915 # ifdef SIGGRANT
2916 sys_siglist[SIGGRANT] = "Monitor mode granted";
2917 # endif
2918 # ifdef SIGHUP
2919 sys_siglist[SIGHUP] = "Hangup";
2920 # endif
2921 # ifdef SIGILL
2922 sys_siglist[SIGILL] = "Illegal instruction";
2923 # endif
2924 # ifdef SIGINT
2925 sys_siglist[SIGINT] = "Interrupt";
2926 # endif
2927 # ifdef SIGIO
2928 sys_siglist[SIGIO] = "I/O possible";
2929 # endif
2930 # ifdef SIGIOINT
2931 sys_siglist[SIGIOINT] = "I/O intervention required";
2932 # endif
2933 # ifdef SIGIOT
2934 sys_siglist[SIGIOT] = "IOT trap";
2935 # endif
2936 # ifdef SIGKILL
2937 sys_siglist[SIGKILL] = "Killed";
2938 # endif
2939 # ifdef SIGLOST
2940 sys_siglist[SIGLOST] = "Resource lost";
2941 # endif
2942 # ifdef SIGLWP
2943 sys_siglist[SIGLWP] = "SIGLWP";
2944 # endif
2945 # ifdef SIGMSG
2946 sys_siglist[SIGMSG] = "Monitor mode data available";
2947 # endif
2948 # ifdef SIGPHONE
2949 sys_siglist[SIGWIND] = "SIGPHONE";
2950 # endif
2951 # ifdef SIGPIPE
2952 sys_siglist[SIGPIPE] = "Broken pipe";
2953 # endif
2954 # ifdef SIGPOLL
2955 sys_siglist[SIGPOLL] = "Pollable event occurred";
2956 # endif
2957 # ifdef SIGPROF
2958 sys_siglist[SIGPROF] = "Profiling timer expired";
2959 # endif
2960 # ifdef SIGPTY
2961 sys_siglist[SIGPTY] = "PTY I/O interrupt";
2962 # endif
2963 # ifdef SIGPWR
2964 sys_siglist[SIGPWR] = "Power-fail restart";
2965 # endif
2966 # ifdef SIGQUIT
2967 sys_siglist[SIGQUIT] = "Quit";
2968 # endif
2969 # ifdef SIGRETRACT
2970 sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode";
2971 # endif
2972 # ifdef SIGSAK
2973 sys_siglist[SIGSAK] = "Secure attention";
2974 # endif
2975 # ifdef SIGSEGV
2976 sys_siglist[SIGSEGV] = "Segmentation violation";
2977 # endif
2978 # ifdef SIGSOUND
2979 sys_siglist[SIGSOUND] = "Sound completed";
2980 # endif
2981 # ifdef SIGSTOP
2982 sys_siglist[SIGSTOP] = "Stopped (signal)";
2983 # endif
2984 # ifdef SIGSTP
2985 sys_siglist[SIGSTP] = "Stopped (user)";
2986 # endif
2987 # ifdef SIGSYS
2988 sys_siglist[SIGSYS] = "Bad argument to system call";
2989 # endif
2990 # ifdef SIGTERM
2991 sys_siglist[SIGTERM] = "Terminated";
2992 # endif
2993 # ifdef SIGTHAW
2994 sys_siglist[SIGTHAW] = "SIGTHAW";
2995 # endif
2996 # ifdef SIGTRAP
2997 sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
2998 # endif
2999 # ifdef SIGTSTP
3000 sys_siglist[SIGTSTP] = "Stopped (user)";
3001 # endif
3002 # ifdef SIGTTIN
3003 sys_siglist[SIGTTIN] = "Stopped (tty input)";
3004 # endif
3005 # ifdef SIGTTOU
3006 sys_siglist[SIGTTOU] = "Stopped (tty output)";
3007 # endif
3008 # ifdef SIGURG
3009 sys_siglist[SIGURG] = "Urgent I/O condition";
3010 # endif
3011 # ifdef SIGUSR1
3012 sys_siglist[SIGUSR1] = "User defined signal 1";
3013 # endif
3014 # ifdef SIGUSR2
3015 sys_siglist[SIGUSR2] = "User defined signal 2";
3016 # endif
3017 # ifdef SIGVTALRM
3018 sys_siglist[SIGVTALRM] = "Virtual timer expired";
3019 # endif
3020 # ifdef SIGWAITING
3021 sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
3022 # endif
3023 # ifdef SIGWINCH
3024 sys_siglist[SIGWINCH] = "Window size changed";
3025 # endif
3026 # ifdef SIGWIND
3027 sys_siglist[SIGWIND] = "SIGWIND";
3028 # endif
3029 # ifdef SIGXCPU
3030 sys_siglist[SIGXCPU] = "CPU time limit exceeded";
3031 # endif
3032 # ifdef SIGXFSZ
3033 sys_siglist[SIGXFSZ] = "File size limit exceeded";
3034 # endif
3036 #endif /* !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED */
3039 #ifndef HAVE_RANDOM
3040 #ifdef random
3041 #define HAVE_RANDOM
3042 #endif
3043 #endif
3045 /* Figure out how many bits the system's random number generator uses.
3046 `random' and `lrand48' are assumed to return 31 usable bits.
3047 BSD `rand' returns a 31 bit value but the low order bits are unusable;
3048 so we'll shift it and treat it like the 15-bit USG `rand'. */
3050 #ifndef RAND_BITS
3051 # ifdef HAVE_RANDOM
3052 # define RAND_BITS 31
3053 # else /* !HAVE_RANDOM */
3054 # ifdef HAVE_LRAND48
3055 # define RAND_BITS 31
3056 # define random lrand48
3057 # else /* !HAVE_LRAND48 */
3058 # define RAND_BITS 15
3059 # if RAND_MAX == 32767
3060 # define random rand
3061 # else /* RAND_MAX != 32767 */
3062 # if RAND_MAX == 2147483647
3063 # define random() (rand () >> 16)
3064 # else /* RAND_MAX != 2147483647 */
3065 # ifdef USG
3066 # define random rand
3067 # else
3068 # define random() (rand () >> 16)
3069 # endif /* !USG */
3070 # endif /* RAND_MAX != 2147483647 */
3071 # endif /* RAND_MAX != 32767 */
3072 # endif /* !HAVE_LRAND48 */
3073 # endif /* !HAVE_RANDOM */
3074 #endif /* !RAND_BITS */
3076 void
3077 seed_random (arg)
3078 long arg;
3080 #ifdef HAVE_RANDOM
3081 srandom ((unsigned int)arg);
3082 #else
3083 # ifdef HAVE_LRAND48
3084 srand48 (arg);
3085 # else
3086 srand ((unsigned int)arg);
3087 # endif
3088 #endif
3092 * Build a full Emacs-sized word out of whatever we've got.
3093 * This suffices even for a 64-bit architecture with a 15-bit rand.
3095 long
3096 get_random ()
3098 long val = random ();
3099 #if VALBITS > RAND_BITS
3100 val = (val << RAND_BITS) ^ random ();
3101 #if VALBITS > 2*RAND_BITS
3102 val = (val << RAND_BITS) ^ random ();
3103 #if VALBITS > 3*RAND_BITS
3104 val = (val << RAND_BITS) ^ random ();
3105 #if VALBITS > 4*RAND_BITS
3106 val = (val << RAND_BITS) ^ random ();
3107 #endif /* need at least 5 */
3108 #endif /* need at least 4 */
3109 #endif /* need at least 3 */
3110 #endif /* need at least 2 */
3111 return val & ((1L << VALBITS) - 1);
3114 #ifdef WRONG_NAME_INSQUE
3116 insque (q,p)
3117 caddr_t q,p;
3119 _insque (q,p);
3122 #endif
3124 #ifdef VMS
3126 #ifdef getenv
3127 /* If any place else asks for the TERM variable,
3128 allow it to be overridden with the EMACS_TERM variable
3129 before attempting to translate the logical name TERM. As a last
3130 resort, ask for VAX C's special idea of the TERM variable. */
3131 #undef getenv
3132 char *
3133 sys_getenv (name)
3134 char *name;
3136 register char *val;
3137 static char buf[256];
3138 static struct dsc$descriptor_s equiv
3139 = {sizeof (buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf};
3140 static struct dsc$descriptor_s d_name
3141 = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
3142 short eqlen;
3144 if (!strcmp (name, "TERM"))
3146 val = (char *) getenv ("EMACS_TERM");
3147 if (val)
3148 return val;
3151 d_name.dsc$w_length = strlen (name);
3152 d_name.dsc$a_pointer = name;
3153 if (LIB$SYS_TRNLOG (&d_name, &eqlen, &equiv) == 1)
3155 char *str = (char *) xmalloc (eqlen + 1);
3156 bcopy (buf, str, eqlen);
3157 str[eqlen] = '\0';
3158 /* This is a storage leak, but a pain to fix. With luck,
3159 no one will ever notice. */
3160 return str;
3162 return (char *) getenv (name);
3164 #endif /* getenv */
3166 #ifdef abort
3167 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
3168 to force a call on the debugger from within the image. */
3169 #undef abort
3170 sys_abort ()
3172 reset_sys_modes ();
3173 LIB$SIGNAL (SS$_DEBUG);
3175 #endif /* abort */
3176 #endif /* VMS */
3178 #ifdef VMS
3179 #ifdef LINK_CRTL_SHARE
3180 #ifdef SHARABLE_LIB_BUG
3181 /* Variables declared noshare and initialized in sharable libraries
3182 cannot be shared. The VMS linker incorrectly forces you to use a private
3183 version which is uninitialized... If not for this "feature", we
3184 could use the C library definition of sys_nerr and sys_errlist. */
3185 int sys_nerr = 35;
3186 char *sys_errlist[] =
3188 "error 0",
3189 "not owner",
3190 "no such file or directory",
3191 "no such process",
3192 "interrupted system call",
3193 "i/o error",
3194 "no such device or address",
3195 "argument list too long",
3196 "exec format error",
3197 "bad file number",
3198 "no child process",
3199 "no more processes",
3200 "not enough memory",
3201 "permission denied",
3202 "bad address",
3203 "block device required",
3204 "mount devices busy",
3205 "file exists",
3206 "cross-device link",
3207 "no such device",
3208 "not a directory",
3209 "is a directory",
3210 "invalid argument",
3211 "file table overflow",
3212 "too many open files",
3213 "not a typewriter",
3214 "text file busy",
3215 "file too big",
3216 "no space left on device",
3217 "illegal seek",
3218 "read-only file system",
3219 "too many links",
3220 "broken pipe",
3221 "math argument",
3222 "result too large",
3223 "I/O stream empty",
3224 "vax/vms specific error code nontranslatable error"
3226 #endif /* SHARABLE_LIB_BUG */
3227 #endif /* LINK_CRTL_SHARE */
3228 #endif /* VMS */
3230 #ifndef HAVE_STRERROR
3231 #ifndef WINDOWSNT
3232 char *
3233 strerror (errnum)
3234 int errnum;
3236 extern char *sys_errlist[];
3237 extern int sys_nerr;
3239 if (errnum >= 0 && errnum < sys_nerr)
3240 return sys_errlist[errnum];
3241 return (char *) "Unknown error";
3243 #endif /* not WINDOWSNT */
3244 #endif /* ! HAVE_STRERROR */
3247 emacs_open (path, oflag, mode)
3248 char *path;
3249 int oflag, mode;
3251 register int rtnval;
3253 #ifdef BSD4_1
3254 if (oflag & O_CREAT)
3255 return creat (path, mode);
3256 #endif
3258 while ((rtnval = open (path, oflag, mode)) == -1
3259 && (errno == EINTR));
3260 return (rtnval);
3264 emacs_close (fd)
3265 int fd;
3267 int did_retry = 0;
3268 register int rtnval;
3270 while ((rtnval = close (fd)) == -1
3271 && (errno == EINTR))
3272 did_retry = 1;
3274 /* If close is interrupted SunOS 4.1 may or may not have closed the
3275 file descriptor. If it did the second close will fail with
3276 errno = EBADF. That means we have succeeded. */
3277 if (rtnval == -1 && did_retry && errno == EBADF)
3278 return 0;
3280 return rtnval;
3284 emacs_read (fildes, buf, nbyte)
3285 int fildes;
3286 char *buf;
3287 unsigned int nbyte;
3289 register int rtnval;
3291 while ((rtnval = read (fildes, buf, nbyte)) == -1
3292 && (errno == EINTR));
3293 return (rtnval);
3297 emacs_write (fildes, buf, nbyte)
3298 int fildes;
3299 char *buf;
3300 unsigned int nbyte;
3302 register int rtnval, bytes_written;
3304 bytes_written = 0;
3306 while (nbyte > 0)
3308 rtnval = write (fildes, buf, nbyte);
3310 if (rtnval == -1)
3312 if (errno == EINTR)
3313 continue;
3314 else
3315 return (bytes_written ? bytes_written : -1);
3318 buf += rtnval;
3319 nbyte -= rtnval;
3320 bytes_written += rtnval;
3322 return (bytes_written);
3325 #ifdef USG
3327 * All of the following are for USG.
3329 * On USG systems the system calls are INTERRUPTIBLE by signals
3330 * that the user program has elected to catch. Thus the system call
3331 * must be retried in these cases. To handle this without massive
3332 * changes in the source code, we remap the standard system call names
3333 * to names for our own functions in sysdep.c that do the system call
3334 * with retries. Actually, for portability reasons, it is good
3335 * programming practice, as this example shows, to limit all actual
3336 * system calls to a single occurrence in the source. Sure, this
3337 * adds an extra level of function call overhead but it is almost
3338 * always negligible. Fred Fish, Unisoft Systems Inc.
3342 * Warning, this function may not duplicate 4.2 action properly
3343 * under error conditions.
3346 #ifndef MAXPATHLEN
3347 /* In 4.1, param.h fails to define this. */
3348 #define MAXPATHLEN 1024
3349 #endif
3351 #ifndef HAVE_GETWD
3353 char *
3354 getwd (pathname)
3355 char *pathname;
3357 char *npath, *spath;
3358 extern char *getcwd ();
3360 BLOCK_INPUT; /* getcwd uses malloc */
3361 spath = npath = getcwd ((char *) 0, MAXPATHLEN);
3362 if (spath == 0)
3364 UNBLOCK_INPUT;
3365 return spath;
3367 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3368 up to first slash. Should be harmless on other systems. */
3369 while (*npath && *npath != '/')
3370 npath++;
3371 strcpy (pathname, npath);
3372 free (spath); /* getcwd uses malloc */
3373 UNBLOCK_INPUT;
3374 return pathname;
3377 #endif /* HAVE_GETWD */
3380 * Emulate rename using unlink/link. Note that this is
3381 * only partially correct. Also, doesn't enforce restriction
3382 * that files be of same type (regular->regular, dir->dir, etc).
3385 #ifndef HAVE_RENAME
3387 rename (from, to)
3388 const char *from;
3389 const char *to;
3391 if (access (from, 0) == 0)
3393 unlink (to);
3394 if (link (from, to) == 0)
3395 if (unlink (from) == 0)
3396 return (0);
3398 return (-1);
3401 #endif
3404 #ifdef HPUX
3405 #ifndef HAVE_PERROR
3407 /* HPUX curses library references perror, but as far as we know
3408 it won't be called. Anyway this definition will do for now. */
3410 perror ()
3414 #endif /* not HAVE_PERROR */
3415 #endif /* HPUX */
3417 #ifndef HAVE_DUP2
3420 * Emulate BSD dup2. First close newd if it already exists.
3421 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3422 * until we are, then close the unsuccessful ones.
3425 dup2 (oldd, newd)
3426 int oldd;
3427 int newd;
3429 register int fd, ret;
3431 emacs_close (newd);
3433 #ifdef F_DUPFD
3434 return fcntl (oldd, F_DUPFD, newd);
3435 #else
3436 fd = dup (old);
3437 if (fd == -1)
3438 return -1;
3439 if (fd == new)
3440 return new;
3441 ret = dup2 (old,new);
3442 emacs_close (fd);
3443 return ret;
3444 #endif
3447 #endif /* not HAVE_DUP2 */
3450 * Gettimeofday. Simulate as much as possible. Only accurate
3451 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3452 * Only needed when subprocesses are defined.
3455 #ifdef subprocesses
3456 #ifndef VMS
3457 #ifndef HAVE_GETTIMEOFDAY
3458 #ifdef HAVE_TIMEVAL
3460 /* ARGSUSED */
3462 gettimeofday (tp, tzp)
3463 struct timeval *tp;
3464 struct timezone *tzp;
3466 extern long time ();
3468 tp->tv_sec = time ((long *)0);
3469 tp->tv_usec = 0;
3470 if (tzp != 0)
3471 tzp->tz_minuteswest = -1;
3472 return 0;
3475 #endif
3476 #endif
3477 #endif
3478 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3481 * This function will go away as soon as all the stubs fixed. (fnf)
3484 void
3485 croak (badfunc)
3486 char *badfunc;
3488 printf ("%s not yet implemented\r\n", badfunc);
3489 reset_sys_modes ();
3490 exit (1);
3493 #endif /* USG */
3495 /* Directory routines for systems that don't have them. */
3497 #ifdef SYSV_SYSTEM_DIR
3499 #include <dirent.h>
3501 #if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
3504 closedir (dirp)
3505 register DIR *dirp; /* stream from opendir */
3507 int rtnval;
3509 rtnval = emacs_close (dirp->dd_fd);
3511 /* Some systems (like Solaris) allocate the buffer and the DIR all
3512 in one block. Why in the world are we freeing this ourselves
3513 anyway? */
3514 #if ! (defined (sun) && defined (USG5_4))
3515 xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
3516 #endif
3517 xfree ((char *) dirp);
3519 return rtnval;
3521 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3522 #endif /* SYSV_SYSTEM_DIR */
3524 #ifdef NONSYSTEM_DIR_LIBRARY
3526 DIR *
3527 opendir (filename)
3528 char *filename; /* name of directory */
3530 register DIR *dirp; /* -> malloc'ed storage */
3531 register int fd; /* file descriptor for read */
3532 struct stat sbuf; /* result of fstat */
3534 fd = emacs_open (filename, O_RDONLY, 0);
3535 if (fd < 0)
3536 return 0;
3538 BLOCK_INPUT;
3539 if (fstat (fd, &sbuf) < 0
3540 || (sbuf.st_mode & S_IFMT) != S_IFDIR
3541 || (dirp = (DIR *) xmalloc (sizeof (DIR))) == 0)
3543 emacs_close (fd);
3544 UNBLOCK_INPUT;
3545 return 0; /* bad luck today */
3547 UNBLOCK_INPUT;
3549 dirp->dd_fd = fd;
3550 dirp->dd_loc = dirp->dd_size = 0; /* refill needed */
3552 return dirp;
3555 void
3556 closedir (dirp)
3557 register DIR *dirp; /* stream from opendir */
3559 emacs_close (dirp->dd_fd);
3560 xfree ((char *) dirp);
3564 #ifndef VMS
3565 #define DIRSIZ 14
3566 struct olddir
3568 ino_t od_ino; /* inode */
3569 char od_name[DIRSIZ]; /* filename */
3571 #endif /* not VMS */
3573 struct direct dir_static; /* simulated directory contents */
3575 /* ARGUSED */
3576 struct direct *
3577 readdir (dirp)
3578 register DIR *dirp; /* stream from opendir */
3580 #ifndef VMS
3581 register struct olddir *dp; /* -> directory data */
3582 #else /* VMS */
3583 register struct dir$_name *dp; /* -> directory data */
3584 register struct dir$_version *dv; /* -> version data */
3585 #endif /* VMS */
3587 for (; ;)
3589 if (dirp->dd_loc >= dirp->dd_size)
3590 dirp->dd_loc = dirp->dd_size = 0;
3592 if (dirp->dd_size == 0 /* refill buffer */
3593 && (dirp->dd_size = emacs_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3594 return 0;
3596 #ifndef VMS
3597 dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
3598 dirp->dd_loc += sizeof (struct olddir);
3600 if (dp->od_ino != 0) /* not deleted entry */
3602 dir_static.d_ino = dp->od_ino;
3603 strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
3604 dir_static.d_name[DIRSIZ] = '\0';
3605 dir_static.d_namlen = strlen (dir_static.d_name);
3606 dir_static.d_reclen = sizeof (struct direct)
3607 - MAXNAMLEN + 3
3608 + dir_static.d_namlen - dir_static.d_namlen % 4;
3609 return &dir_static; /* -> simulated structure */
3611 #else /* VMS */
3612 dp = (struct dir$_name *) dirp->dd_buf;
3613 if (dirp->dd_loc == 0)
3614 dirp->dd_loc = (dp->dir$b_namecount&1) ? dp->dir$b_namecount + 1
3615 : dp->dir$b_namecount;
3616 dv = (struct dir$_version *)&dp->dir$t_name[dirp->dd_loc];
3617 dir_static.d_ino = dv->dir$w_fid_num;
3618 dir_static.d_namlen = dp->dir$b_namecount;
3619 dir_static.d_reclen = sizeof (struct direct)
3620 - MAXNAMLEN + 3
3621 + dir_static.d_namlen - dir_static.d_namlen % 4;
3622 strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
3623 dir_static.d_name[dir_static.d_namlen] = '\0';
3624 dirp->dd_loc = dirp->dd_size; /* only one record at a time */
3625 return &dir_static;
3626 #endif /* VMS */
3630 #ifdef VMS
3631 /* readdirver is just like readdir except it returns all versions of a file
3632 as separate entries. */
3634 /* ARGUSED */
3635 struct direct *
3636 readdirver (dirp)
3637 register DIR *dirp; /* stream from opendir */
3639 register struct dir$_name *dp; /* -> directory data */
3640 register struct dir$_version *dv; /* -> version data */
3642 if (dirp->dd_loc >= dirp->dd_size - sizeof (struct dir$_name))
3643 dirp->dd_loc = dirp->dd_size = 0;
3645 if (dirp->dd_size == 0 /* refill buffer */
3646 && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3647 return 0;
3649 dp = (struct dir$_name *) dirp->dd_buf;
3650 if (dirp->dd_loc == 0)
3651 dirp->dd_loc = (dp->dir$b_namecount & 1) ? dp->dir$b_namecount + 1
3652 : dp->dir$b_namecount;
3653 dv = (struct dir$_version *) &dp->dir$t_name[dirp->dd_loc];
3654 strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
3655 sprintf (&dir_static.d_name[dp->dir$b_namecount], ";%d", dv->dir$w_version);
3656 dir_static.d_namlen = strlen (dir_static.d_name);
3657 dir_static.d_ino = dv->dir$w_fid_num;
3658 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3
3659 + dir_static.d_namlen - dir_static.d_namlen % 4;
3660 dirp->dd_loc = ((char *) (++dv) - dp->dir$t_name);
3661 return &dir_static;
3664 #endif /* VMS */
3666 #endif /* NONSYSTEM_DIR_LIBRARY */
3670 set_file_times (filename, atime, mtime)
3671 char *filename;
3672 EMACS_TIME atime, mtime;
3674 #ifdef HAVE_UTIMES
3675 struct timeval tv[2];
3676 tv[0] = atime;
3677 tv[1] = mtime;
3678 return utimes (filename, tv);
3679 #else /* not HAVE_UTIMES */
3680 struct utimbuf utb;
3681 utb.actime = EMACS_SECS (atime);
3682 utb.modtime = EMACS_SECS (mtime);
3683 return utime (filename, &utb);
3684 #endif /* not HAVE_UTIMES */
3687 /* mkdir and rmdir functions, for systems which don't have them. */
3689 #ifndef HAVE_MKDIR
3691 * Written by Robert Rother, Mariah Corporation, August 1985.
3693 * If you want it, it's yours. All I ask in return is that if you
3694 * figure out how to do this in a Bourne Shell script you send me
3695 * a copy.
3696 * sdcsvax!rmr or rmr@uscd
3698 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3699 * subroutine. 11Mar86; hoptoad!gnu
3701 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3702 * subroutine didn't return EEXIST. It does now.
3706 * Make a directory.
3708 #ifdef MKDIR_PROTOTYPE
3709 MKDIR_PROTOTYPE
3710 #else
3712 mkdir (dpath, dmode)
3713 char *dpath;
3714 int dmode;
3715 #endif
3717 int cpid, status, fd;
3718 struct stat statbuf;
3720 if (stat (dpath, &statbuf) == 0)
3722 errno = EEXIST; /* Stat worked, so it already exists */
3723 return -1;
3726 /* If stat fails for a reason other than non-existence, return error */
3727 if (errno != ENOENT)
3728 return -1;
3730 synch_process_alive = 1;
3731 switch (cpid = fork ())
3734 case -1: /* Error in fork */
3735 return (-1); /* Errno is set already */
3737 case 0: /* Child process */
3739 * Cheap hack to set mode of new directory. Since this
3740 * child process is going away anyway, we zap its umask.
3741 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3742 * directory. Does anybody care?
3744 status = umask (0); /* Get current umask */
3745 status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
3746 fd = emacs_open ("/dev/null", O_RDWR, 0);
3747 if (fd >= 0)
3749 dup2 (fd, 0);
3750 dup2 (fd, 1);
3751 dup2 (fd, 2);
3753 execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
3754 _exit (-1); /* Can't exec /bin/mkdir */
3756 default: /* Parent process */
3757 wait_for_termination (cpid);
3760 if (synch_process_death != 0 || synch_process_retcode != 0)
3762 errno = EIO; /* We don't know why, but */
3763 return -1; /* /bin/mkdir failed */
3766 return 0;
3768 #endif /* not HAVE_MKDIR */
3770 #ifndef HAVE_RMDIR
3772 rmdir (dpath)
3773 char *dpath;
3775 int cpid, status, fd;
3776 struct stat statbuf;
3778 if (stat (dpath, &statbuf) != 0)
3780 /* Stat just set errno. We don't have to */
3781 return -1;
3784 synch_process_alive = 1;
3785 switch (cpid = fork ())
3788 case -1: /* Error in fork */
3789 return (-1); /* Errno is set already */
3791 case 0: /* Child process */
3792 fd = emacs_open ("/dev/null", O_RDWR, 0);
3793 if (fd >= 0)
3795 dup2 (fd, 0);
3796 dup2 (fd, 1);
3797 dup2 (fd, 2);
3799 execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
3800 _exit (-1); /* Can't exec /bin/rmdir */
3802 default: /* Parent process */
3803 wait_for_termination (cpid);
3806 if (synch_process_death != 0 || synch_process_retcode != 0)
3808 errno = EIO; /* We don't know why, but */
3809 return -1; /* /bin/rmdir failed */
3812 return 0;
3814 #endif /* !HAVE_RMDIR */
3818 /* Functions for VMS */
3819 #ifdef VMS
3820 #include "vms-pwd.h"
3821 #include <acldef.h>
3822 #include <chpdef.h>
3823 #include <jpidef.h>
3825 /* Return as a string the VMS error string pertaining to STATUS.
3826 Reuses the same static buffer each time it is called. */
3828 char *
3829 vmserrstr (status)
3830 int status; /* VMS status code */
3832 int bufadr[2];
3833 short len;
3834 static char buf[257];
3836 bufadr[0] = sizeof buf - 1;
3837 bufadr[1] = (int) buf;
3838 if (! (SYS$GETMSG (status, &len, bufadr, 0x1, 0) & 1))
3839 return "untranslatable VMS error status";
3840 buf[len] = '\0';
3841 return buf;
3844 #ifdef access
3845 #undef access
3847 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3848 * not work correctly. (It also doesn't work well in version 2.3.)
3851 #ifdef VMS4_4
3853 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3854 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3856 typedef union {
3857 struct {
3858 unsigned short s_buflen;
3859 unsigned short s_code;
3860 char *s_bufadr;
3861 unsigned short *s_retlenadr;
3862 } s;
3863 int end;
3864 } item;
3865 #define buflen s.s_buflen
3866 #define code s.s_code
3867 #define bufadr s.s_bufadr
3868 #define retlenadr s.s_retlenadr
3870 #define R_OK 4 /* test for read permission */
3871 #define W_OK 2 /* test for write permission */
3872 #define X_OK 1 /* test for execute (search) permission */
3873 #define F_OK 0 /* test for presence of file */
3876 sys_access (path, mode)
3877 char *path;
3878 int mode;
3880 static char *user = NULL;
3881 char dir_fn[512];
3883 /* translate possible directory spec into .DIR file name, so brain-dead
3884 * access can treat the directory like a file. */
3885 if (directory_file_name (path, dir_fn))
3886 path = dir_fn;
3888 if (mode == F_OK)
3889 return access (path, mode);
3890 if (user == NULL && (user = (char *) getenv ("USER")) == NULL)
3891 return -1;
3893 int stat;
3894 int flags;
3895 int acces;
3896 unsigned short int dummy;
3897 item itemlst[3];
3898 static int constant = ACL$C_FILE;
3899 DESCRIPTOR (path_desc, path);
3900 DESCRIPTOR (user_desc, user);
3902 flags = 0;
3903 acces = 0;
3904 if ((mode & X_OK) && ((stat = access (path, mode)) < 0 || mode == X_OK))
3905 return stat;
3906 if (mode & R_OK)
3907 acces |= CHP$M_READ;
3908 if (mode & W_OK)
3909 acces |= CHP$M_WRITE;
3910 itemlst[0].buflen = sizeof (int);
3911 itemlst[0].code = CHP$_FLAGS;
3912 itemlst[0].bufadr = (char *) &flags;
3913 itemlst[0].retlenadr = &dummy;
3914 itemlst[1].buflen = sizeof (int);
3915 itemlst[1].code = CHP$_ACCESS;
3916 itemlst[1].bufadr = (char *) &acces;
3917 itemlst[1].retlenadr = &dummy;
3918 itemlst[2].end = CHP$_END;
3919 stat = SYS$CHECK_ACCESS (&constant, &path_desc, &user_desc, itemlst);
3920 return stat == SS$_NORMAL ? 0 : -1;
3924 #else /* not VMS4_4 */
3926 #include <prvdef.h>
3927 #define ACE$M_WRITE 2
3928 #define ACE$C_KEYID 1
3930 static unsigned short memid, grpid;
3931 static unsigned int uic;
3933 /* Called from init_sys_modes, so it happens not very often
3934 but at least each time Emacs is loaded. */
3935 void
3936 sys_access_reinit ()
3938 uic = 0;
3942 sys_access (filename, type)
3943 char * filename;
3944 int type;
3946 struct FAB fab;
3947 struct XABPRO xab;
3948 int status, size, i, typecode, acl_controlled;
3949 unsigned int *aclptr, *aclend, aclbuf[60];
3950 union prvdef prvmask;
3952 /* Get UIC and GRP values for protection checking. */
3953 if (uic == 0)
3955 status = LIB$GETJPI (&JPI$_UIC, 0, 0, &uic, 0, 0);
3956 if (! (status & 1))
3957 return -1;
3958 memid = uic & 0xFFFF;
3959 grpid = uic >> 16;
3962 if (type != 2) /* not checking write access */
3963 return access (filename, type);
3965 /* Check write protection. */
3967 #define CHECKPRIV(bit) (prvmask.bit)
3968 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3970 /* Find privilege bits */
3971 status = SYS$SETPRV (0, 0, 0, prvmask);
3972 if (! (status & 1))
3973 error ("Unable to find privileges: %s", vmserrstr (status));
3974 if (CHECKPRIV (PRV$V_BYPASS))
3975 return 0; /* BYPASS enabled */
3976 fab = cc$rms_fab;
3977 fab.fab$b_fac = FAB$M_GET;
3978 fab.fab$l_fna = filename;
3979 fab.fab$b_fns = strlen (filename);
3980 fab.fab$l_xab = &xab;
3981 xab = cc$rms_xabpro;
3982 xab.xab$l_aclbuf = aclbuf;
3983 xab.xab$w_aclsiz = sizeof (aclbuf);
3984 status = SYS$OPEN (&fab, 0, 0);
3985 if (! (status & 1))
3986 return -1;
3987 SYS$CLOSE (&fab, 0, 0);
3988 /* Check system access */
3989 if (CHECKPRIV (PRV$V_SYSPRV) && WRITABLE (XAB$V_SYS))
3990 return 0;
3991 /* Check ACL entries, if any */
3992 acl_controlled = 0;
3993 if (xab.xab$w_acllen > 0)
3995 aclptr = aclbuf;
3996 aclend = &aclbuf[xab.xab$w_acllen / 4];
3997 while (*aclptr && aclptr < aclend)
3999 size = (*aclptr & 0xff) / 4;
4000 typecode = (*aclptr >> 8) & 0xff;
4001 if (typecode == ACE$C_KEYID)
4002 for (i = size - 1; i > 1; i--)
4003 if (aclptr[i] == uic)
4005 acl_controlled = 1;
4006 if (aclptr[1] & ACE$M_WRITE)
4007 return 0; /* Write access through ACL */
4009 aclptr = &aclptr[size];
4011 if (acl_controlled) /* ACL specified, prohibits write access */
4012 return -1;
4014 /* No ACL entries specified, check normal protection */
4015 if (WRITABLE (XAB$V_WLD)) /* World writable */
4016 return 0;
4017 if (WRITABLE (XAB$V_GRP) &&
4018 (unsigned short) (xab.xab$l_uic >> 16) == grpid)
4019 return 0; /* Group writable */
4020 if (WRITABLE (XAB$V_OWN) &&
4021 (xab.xab$l_uic & 0xFFFF) == memid)
4022 return 0; /* Owner writable */
4024 return -1; /* Not writable */
4026 #endif /* not VMS4_4 */
4027 #endif /* access */
4029 static char vtbuf[NAM$C_MAXRSS+1];
4031 /* translate a vms file spec to a unix path */
4032 char *
4033 sys_translate_vms (vfile)
4034 char * vfile;
4036 char * p;
4037 char * targ;
4039 if (!vfile)
4040 return 0;
4042 targ = vtbuf;
4044 /* leading device or logical name is a root directory */
4045 if (p = strchr (vfile, ':'))
4047 *targ++ = '/';
4048 while (vfile < p)
4049 *targ++ = *vfile++;
4050 vfile++;
4051 *targ++ = '/';
4053 p = vfile;
4054 if (*p == '[' || *p == '<')
4056 while (*++vfile != *p + 2)
4057 switch (*vfile)
4059 case '.':
4060 if (vfile[-1] == *p)
4061 *targ++ = '.';
4062 *targ++ = '/';
4063 break;
4065 case '-':
4066 *targ++ = '.';
4067 *targ++ = '.';
4068 break;
4070 default:
4071 *targ++ = *vfile;
4072 break;
4074 vfile++;
4075 *targ++ = '/';
4077 while (*vfile)
4078 *targ++ = *vfile++;
4080 return vtbuf;
4083 static char utbuf[NAM$C_MAXRSS+1];
4085 /* translate a unix path to a VMS file spec */
4086 char *
4087 sys_translate_unix (ufile)
4088 char * ufile;
4090 int slash_seen = 0;
4091 char *p;
4092 char * targ;
4094 if (!ufile)
4095 return 0;
4097 targ = utbuf;
4099 if (*ufile == '/')
4101 ufile++;
4104 while (*ufile)
4106 switch (*ufile)
4108 case '/':
4109 if (slash_seen)
4110 if (index (&ufile[1], '/'))
4111 *targ++ = '.';
4112 else
4113 *targ++ = ']';
4114 else
4116 *targ++ = ':';
4117 if (index (&ufile[1], '/'))
4118 *targ++ = '[';
4119 slash_seen = 1;
4121 break;
4123 case '.':
4124 if (strncmp (ufile, "./", 2) == 0)
4126 if (!slash_seen)
4128 *targ++ = '[';
4129 slash_seen = 1;
4131 ufile++; /* skip the dot */
4132 if (index (&ufile[1], '/'))
4133 *targ++ = '.';
4134 else
4135 *targ++ = ']';
4137 else if (strncmp (ufile, "../", 3) == 0)
4139 if (!slash_seen)
4141 *targ++ = '[';
4142 slash_seen = 1;
4144 *targ++ = '-';
4145 ufile += 2; /* skip the dots */
4146 if (index (&ufile[1], '/'))
4147 *targ++ = '.';
4148 else
4149 *targ++ = ']';
4151 else
4152 *targ++ = *ufile;
4153 break;
4155 default:
4156 *targ++ = *ufile;
4157 break;
4159 ufile++;
4161 *targ = '\0';
4163 return utbuf;
4166 char *
4167 getwd (pathname)
4168 char *pathname;
4170 char *ptr, *val;
4171 extern char *getcwd ();
4173 #define MAXPATHLEN 1024
4175 ptr = xmalloc (MAXPATHLEN);
4176 val = getcwd (ptr, MAXPATHLEN);
4177 if (val == 0)
4179 xfree (ptr);
4180 return val;
4182 strcpy (pathname, ptr);
4183 xfree (ptr);
4185 return pathname;
4189 getppid ()
4191 long item_code = JPI$_OWNER;
4192 unsigned long parent_id;
4193 int status;
4195 if (((status = LIB$GETJPI (&item_code, 0, 0, &parent_id)) & 1) == 0)
4197 errno = EVMSERR;
4198 vaxc$errno = status;
4199 return -1;
4201 return parent_id;
4204 #undef getuid
4205 unsigned
4206 sys_getuid ()
4208 return (getgid () << 16) | getuid ();
4211 #undef read
4213 sys_read (fildes, buf, nbyte)
4214 int fildes;
4215 char *buf;
4216 unsigned int nbyte;
4218 return read (fildes, buf, (nbyte < MAXIOSIZE ? nbyte : MAXIOSIZE));
4221 #if 0
4223 sys_write (fildes, buf, nbyte)
4224 int fildes;
4225 char *buf;
4226 unsigned int nbyte;
4228 register int nwrote, rtnval = 0;
4230 while (nbyte > MAXIOSIZE && (nwrote = write (fildes, buf, MAXIOSIZE)) > 0) {
4231 nbyte -= nwrote;
4232 buf += nwrote;
4233 rtnval += nwrote;
4235 if (nwrote < 0)
4236 return rtnval ? rtnval : -1;
4237 if ((nwrote = write (fildes, buf, nbyte)) < 0)
4238 return rtnval ? rtnval : -1;
4239 return (rtnval + nwrote);
4241 #endif /* 0 */
4244 * VAX/VMS VAX C RTL really loses. It insists that records
4245 * end with a newline (carriage return) character, and if they
4246 * don't it adds one (nice of it isn't it!)
4248 * Thus we do this stupidity below.
4251 #undef write
4253 sys_write (fildes, buf, nbytes)
4254 int fildes;
4255 char *buf;
4256 unsigned int nbytes;
4258 register char *p;
4259 register char *e;
4260 int sum = 0;
4261 struct stat st;
4263 fstat (fildes, &st);
4264 p = buf;
4265 while (nbytes > 0)
4267 int len, retval;
4269 /* Handle fixed-length files with carriage control. */
4270 if (st.st_fab_rfm == FAB$C_FIX
4271 && ((st.st_fab_rat & (FAB$M_FTN | FAB$M_CR)) != 0))
4273 len = st.st_fab_mrs;
4274 retval = write (fildes, p, min (len, nbytes));
4275 if (retval != len)
4276 return -1;
4277 retval++; /* This skips the implied carriage control */
4279 else
4281 e = p + min (MAXIOSIZE, nbytes) - 1;
4282 while (*e != '\n' && e > p) e--;
4283 if (p == e) /* Ok.. so here we add a newline... sigh. */
4284 e = p + min (MAXIOSIZE, nbytes) - 1;
4285 len = e + 1 - p;
4286 retval = write (fildes, p, len);
4287 if (retval != len)
4288 return -1;
4290 p += retval;
4291 sum += retval;
4292 nbytes -= retval;
4294 return sum;
4297 /* Create file NEW copying its attributes from file OLD. If
4298 OLD is 0 or does not exist, create based on the value of
4299 vms_stmlf_recfm. */
4301 /* Protection value the file should ultimately have.
4302 Set by create_copy_attrs, and use by rename_sansversions. */
4303 static unsigned short int fab_final_pro;
4306 creat_copy_attrs (old, new)
4307 char *old, *new;
4309 struct FAB fab = cc$rms_fab;
4310 struct XABPRO xabpro;
4311 char aclbuf[256]; /* Choice of size is arbitrary. See below. */
4312 extern int vms_stmlf_recfm;
4314 if (old)
4316 fab.fab$b_fac = FAB$M_GET;
4317 fab.fab$l_fna = old;
4318 fab.fab$b_fns = strlen (old);
4319 fab.fab$l_xab = (char *) &xabpro;
4320 xabpro = cc$rms_xabpro;
4321 xabpro.xab$l_aclbuf = aclbuf;
4322 xabpro.xab$w_aclsiz = sizeof aclbuf;
4323 /* Call $OPEN to fill in the fab & xabpro fields. */
4324 if (SYS$OPEN (&fab, 0, 0) & 1)
4326 SYS$CLOSE (&fab, 0, 0);
4327 fab.fab$l_alq = 0; /* zero the allocation quantity */
4328 if (xabpro.xab$w_acllen > 0)
4330 if (xabpro.xab$w_acllen > sizeof aclbuf)
4331 /* If the acl buffer was too short, redo open with longer one.
4332 Wouldn't need to do this if there were some system imposed
4333 limit on the size of an ACL, but I can't find any such. */
4335 xabpro.xab$l_aclbuf = (char *) alloca (xabpro.xab$w_acllen);
4336 xabpro.xab$w_aclsiz = xabpro.xab$w_acllen;
4337 if (SYS$OPEN (&fab, 0, 0) & 1)
4338 SYS$CLOSE (&fab, 0, 0);
4339 else
4340 old = 0;
4343 else
4344 xabpro.xab$l_aclbuf = 0;
4346 else
4347 old = 0;
4349 fab.fab$l_fna = new;
4350 fab.fab$b_fns = strlen (new);
4351 if (!old)
4353 fab.fab$l_xab = 0;
4354 fab.fab$b_rfm = vms_stmlf_recfm ? FAB$C_STMLF : FAB$C_VAR;
4355 fab.fab$b_rat = FAB$M_CR;
4358 /* Set the file protections such that we will be able to manipulate
4359 this file. Once we are done writing and renaming it, we will set
4360 the protections back. */
4361 if (old)
4362 fab_final_pro = xabpro.xab$w_pro;
4363 else
4364 SYS$SETDFPROT (0, &fab_final_pro);
4365 xabpro.xab$w_pro &= 0xff0f; /* set O:rewd for now. This is set back later. */
4367 /* Create the new file with either default attrs or attrs copied
4368 from old file. */
4369 if (!(SYS$CREATE (&fab, 0, 0) & 1))
4370 return -1;
4371 SYS$CLOSE (&fab, 0, 0);
4372 /* As this is a "replacement" for creat, return a file descriptor
4373 opened for writing. */
4374 return open (new, O_WRONLY);
4377 #ifdef creat
4378 #undef creat
4379 #include <varargs.h>
4380 #ifdef __GNUC__
4381 #ifndef va_count
4382 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4383 #endif
4384 #endif
4387 sys_creat (va_alist)
4388 va_dcl
4390 va_list list_incrementer;
4391 char *name;
4392 int mode;
4393 int rfd; /* related file descriptor */
4394 int fd; /* Our new file descriptor */
4395 int count;
4396 struct stat st_buf;
4397 char rfm[12];
4398 char rat[15];
4399 char mrs[13];
4400 char fsz[13];
4401 extern int vms_stmlf_recfm;
4403 va_count (count);
4404 va_start (list_incrementer);
4405 name = va_arg (list_incrementer, char *);
4406 mode = va_arg (list_incrementer, int);
4407 if (count > 2)
4408 rfd = va_arg (list_incrementer, int);
4409 va_end (list_incrementer);
4410 if (count > 2)
4412 /* Use information from the related file descriptor to set record
4413 format of the newly created file. */
4414 fstat (rfd, &st_buf);
4415 switch (st_buf.st_fab_rfm)
4417 case FAB$C_FIX:
4418 strcpy (rfm, "rfm = fix");
4419 sprintf (mrs, "mrs = %d", st_buf.st_fab_mrs);
4420 strcpy (rat, "rat = ");
4421 if (st_buf.st_fab_rat & FAB$M_CR)
4422 strcat (rat, "cr");
4423 else if (st_buf.st_fab_rat & FAB$M_FTN)
4424 strcat (rat, "ftn");
4425 else if (st_buf.st_fab_rat & FAB$M_PRN)
4426 strcat (rat, "prn");
4427 if (st_buf.st_fab_rat & FAB$M_BLK)
4428 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4429 strcat (rat, ", blk");
4430 else
4431 strcat (rat, "blk");
4432 return creat (name, 0, rfm, rat, mrs);
4434 case FAB$C_VFC:
4435 strcpy (rfm, "rfm = vfc");
4436 sprintf (fsz, "fsz = %d", st_buf.st_fab_fsz);
4437 strcpy (rat, "rat = ");
4438 if (st_buf.st_fab_rat & FAB$M_CR)
4439 strcat (rat, "cr");
4440 else if (st_buf.st_fab_rat & FAB$M_FTN)
4441 strcat (rat, "ftn");
4442 else if (st_buf.st_fab_rat & FAB$M_PRN)
4443 strcat (rat, "prn");
4444 if (st_buf.st_fab_rat & FAB$M_BLK)
4445 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4446 strcat (rat, ", blk");
4447 else
4448 strcat (rat, "blk");
4449 return creat (name, 0, rfm, rat, fsz);
4451 case FAB$C_STM:
4452 strcpy (rfm, "rfm = stm");
4453 break;
4455 case FAB$C_STMCR:
4456 strcpy (rfm, "rfm = stmcr");
4457 break;
4459 case FAB$C_STMLF:
4460 strcpy (rfm, "rfm = stmlf");
4461 break;
4463 case FAB$C_UDF:
4464 strcpy (rfm, "rfm = udf");
4465 break;
4467 case FAB$C_VAR:
4468 strcpy (rfm, "rfm = var");
4469 break;
4471 strcpy (rat, "rat = ");
4472 if (st_buf.st_fab_rat & FAB$M_CR)
4473 strcat (rat, "cr");
4474 else if (st_buf.st_fab_rat & FAB$M_FTN)
4475 strcat (rat, "ftn");
4476 else if (st_buf.st_fab_rat & FAB$M_PRN)
4477 strcat (rat, "prn");
4478 if (st_buf.st_fab_rat & FAB$M_BLK)
4479 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4480 strcat (rat, ", blk");
4481 else
4482 strcat (rat, "blk");
4484 else
4486 strcpy (rfm, vms_stmlf_recfm ? "rfm = stmlf" : "rfm=var");
4487 strcpy (rat, "rat=cr");
4489 /* Until the VAX C RTL fixes the many bugs with modes, always use
4490 mode 0 to get the user's default protection. */
4491 fd = creat (name, 0, rfm, rat);
4492 if (fd < 0 && errno == EEXIST)
4494 if (unlink (name) < 0)
4495 report_file_error ("delete", build_string (name));
4496 fd = creat (name, 0, rfm, rat);
4498 return fd;
4500 #endif /* creat */
4502 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4504 sys_fwrite (ptr, size, num, fp)
4505 register char * ptr;
4506 FILE * fp;
4508 register int tot = num * size;
4510 while (tot--)
4511 fputc (*ptr++, fp);
4512 return num;
4516 * The VMS C library routine creat actually creates a new version of an
4517 * existing file rather than truncating the old version. There are times
4518 * when this is not the desired behavior, for instance, when writing an
4519 * auto save file (you only want one version), or when you don't have
4520 * write permission in the directory containing the file (but the file
4521 * itself is writable). Hence this routine, which is equivalent to
4522 * "close (creat (fn, 0));" on Unix if fn already exists.
4525 vms_truncate (fn)
4526 char *fn;
4528 struct FAB xfab = cc$rms_fab;
4529 struct RAB xrab = cc$rms_rab;
4530 int status;
4532 xfab.fab$l_fop = FAB$M_TEF; /* free allocated but unused blocks on close */
4533 xfab.fab$b_fac = FAB$M_TRN | FAB$M_GET; /* allow truncate and get access */
4534 xfab.fab$b_shr = FAB$M_NIL; /* allow no sharing - file must be locked */
4535 xfab.fab$l_fna = fn;
4536 xfab.fab$b_fns = strlen (fn);
4537 xfab.fab$l_dna = ";0"; /* default to latest version of the file */
4538 xfab.fab$b_dns = 2;
4539 xrab.rab$l_fab = &xfab;
4541 /* This gibberish opens the file, positions to the first record, and
4542 deletes all records from there until the end of file. */
4543 if ((SYS$OPEN (&xfab) & 01) == 01)
4545 if ((SYS$CONNECT (&xrab) & 01) == 01 &&
4546 (SYS$FIND (&xrab) & 01) == 01 &&
4547 (SYS$TRUNCATE (&xrab) & 01) == 01)
4548 status = 0;
4549 else
4550 status = -1;
4552 else
4553 status = -1;
4554 SYS$CLOSE (&xfab);
4555 return status;
4558 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4559 SYSPRV or a readable SYSUAF.DAT. */
4561 #ifdef READ_SYSUAF
4563 * getuaf.c
4565 * Routine to read the VMS User Authorization File and return
4566 * a specific user's record.
4569 static struct UAF retuaf;
4571 struct UAF *
4572 get_uaf_name (uname)
4573 char * uname;
4575 register status;
4576 struct FAB uaf_fab;
4577 struct RAB uaf_rab;
4579 uaf_fab = cc$rms_fab;
4580 uaf_rab = cc$rms_rab;
4581 /* initialize fab fields */
4582 uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
4583 uaf_fab.fab$b_fns = 21;
4584 uaf_fab.fab$b_fac = FAB$M_GET;
4585 uaf_fab.fab$b_org = FAB$C_IDX;
4586 uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
4587 /* initialize rab fields */
4588 uaf_rab.rab$l_fab = &uaf_fab;
4589 /* open the User Authorization File */
4590 status = SYS$OPEN (&uaf_fab);
4591 if (!(status&1))
4593 errno = EVMSERR;
4594 vaxc$errno = status;
4595 return 0;
4597 status = SYS$CONNECT (&uaf_rab);
4598 if (!(status&1))
4600 errno = EVMSERR;
4601 vaxc$errno = status;
4602 return 0;
4604 /* read the requested record - index is in uname */
4605 uaf_rab.rab$l_kbf = uname;
4606 uaf_rab.rab$b_ksz = strlen (uname);
4607 uaf_rab.rab$b_rac = RAB$C_KEY;
4608 uaf_rab.rab$l_ubf = (char *)&retuaf;
4609 uaf_rab.rab$w_usz = sizeof retuaf;
4610 status = SYS$GET (&uaf_rab);
4611 if (!(status&1))
4613 errno = EVMSERR;
4614 vaxc$errno = status;
4615 return 0;
4617 /* close the User Authorization File */
4618 status = SYS$DISCONNECT (&uaf_rab);
4619 if (!(status&1))
4621 errno = EVMSERR;
4622 vaxc$errno = status;
4623 return 0;
4625 status = SYS$CLOSE (&uaf_fab);
4626 if (!(status&1))
4628 errno = EVMSERR;
4629 vaxc$errno = status;
4630 return 0;
4632 return &retuaf;
4635 struct UAF *
4636 get_uaf_uic (uic)
4637 unsigned long uic;
4639 register status;
4640 struct FAB uaf_fab;
4641 struct RAB uaf_rab;
4643 uaf_fab = cc$rms_fab;
4644 uaf_rab = cc$rms_rab;
4645 /* initialize fab fields */
4646 uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
4647 uaf_fab.fab$b_fns = 21;
4648 uaf_fab.fab$b_fac = FAB$M_GET;
4649 uaf_fab.fab$b_org = FAB$C_IDX;
4650 uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
4651 /* initialize rab fields */
4652 uaf_rab.rab$l_fab = &uaf_fab;
4653 /* open the User Authorization File */
4654 status = SYS$OPEN (&uaf_fab);
4655 if (!(status&1))
4657 errno = EVMSERR;
4658 vaxc$errno = status;
4659 return 0;
4661 status = SYS$CONNECT (&uaf_rab);
4662 if (!(status&1))
4664 errno = EVMSERR;
4665 vaxc$errno = status;
4666 return 0;
4668 /* read the requested record - index is in uic */
4669 uaf_rab.rab$b_krf = 1; /* 1st alternate key */
4670 uaf_rab.rab$l_kbf = (char *) &uic;
4671 uaf_rab.rab$b_ksz = sizeof uic;
4672 uaf_rab.rab$b_rac = RAB$C_KEY;
4673 uaf_rab.rab$l_ubf = (char *)&retuaf;
4674 uaf_rab.rab$w_usz = sizeof retuaf;
4675 status = SYS$GET (&uaf_rab);
4676 if (!(status&1))
4678 errno = EVMSERR;
4679 vaxc$errno = status;
4680 return 0;
4682 /* close the User Authorization File */
4683 status = SYS$DISCONNECT (&uaf_rab);
4684 if (!(status&1))
4686 errno = EVMSERR;
4687 vaxc$errno = status;
4688 return 0;
4690 status = SYS$CLOSE (&uaf_fab);
4691 if (!(status&1))
4693 errno = EVMSERR;
4694 vaxc$errno = status;
4695 return 0;
4697 return &retuaf;
4700 static struct passwd retpw;
4702 struct passwd *
4703 cnv_uaf_pw (up)
4704 struct UAF * up;
4706 char * ptr;
4708 /* copy these out first because if the username is 32 chars, the next
4709 section will overwrite the first byte of the UIC */
4710 retpw.pw_uid = up->uaf$w_mem;
4711 retpw.pw_gid = up->uaf$w_grp;
4713 /* I suppose this is not the best style, to possibly overwrite one
4714 byte beyond the end of the field, but what the heck... */
4715 ptr = &up->uaf$t_username[UAF$S_USERNAME];
4716 while (ptr[-1] == ' ')
4717 ptr--;
4718 *ptr = '\0';
4719 strcpy (retpw.pw_name, up->uaf$t_username);
4721 /* the rest of these are counted ascii strings */
4722 strncpy (retpw.pw_gecos, &up->uaf$t_owner[1], up->uaf$t_owner[0]);
4723 retpw.pw_gecos[up->uaf$t_owner[0]] = '\0';
4724 strncpy (retpw.pw_dir, &up->uaf$t_defdev[1], up->uaf$t_defdev[0]);
4725 retpw.pw_dir[up->uaf$t_defdev[0]] = '\0';
4726 strncat (retpw.pw_dir, &up->uaf$t_defdir[1], up->uaf$t_defdir[0]);
4727 retpw.pw_dir[up->uaf$t_defdev[0] + up->uaf$t_defdir[0]] = '\0';
4728 strncpy (retpw.pw_shell, &up->uaf$t_defcli[1], up->uaf$t_defcli[0]);
4729 retpw.pw_shell[up->uaf$t_defcli[0]] = '\0';
4731 return &retpw;
4733 #else /* not READ_SYSUAF */
4734 static struct passwd retpw;
4735 #endif /* not READ_SYSUAF */
4737 struct passwd *
4738 getpwnam (name)
4739 char * name;
4741 #ifdef READ_SYSUAF
4742 struct UAF *up;
4743 #else
4744 char * user;
4745 char * dir;
4746 unsigned char * full;
4747 #endif /* READ_SYSUAF */
4748 char *ptr = name;
4750 while (*ptr)
4752 if ('a' <= *ptr && *ptr <= 'z')
4753 *ptr -= 040;
4754 ptr++;
4756 #ifdef READ_SYSUAF
4757 if (!(up = get_uaf_name (name)))
4758 return 0;
4759 return cnv_uaf_pw (up);
4760 #else
4761 if (strcmp (name, getenv ("USER")) == 0)
4763 retpw.pw_uid = getuid ();
4764 retpw.pw_gid = getgid ();
4765 strcpy (retpw.pw_name, name);
4766 if (full = egetenv ("FULLNAME"))
4767 strcpy (retpw.pw_gecos, full);
4768 else
4769 *retpw.pw_gecos = '\0';
4770 strcpy (retpw.pw_dir, egetenv ("HOME"));
4771 *retpw.pw_shell = '\0';
4772 return &retpw;
4774 else
4775 return 0;
4776 #endif /* not READ_SYSUAF */
4779 struct passwd *
4780 getpwuid (uid)
4781 unsigned long uid;
4783 #ifdef READ_SYSUAF
4784 struct UAF * up;
4786 if (!(up = get_uaf_uic (uid)))
4787 return 0;
4788 return cnv_uaf_pw (up);
4789 #else
4790 if (uid == sys_getuid ())
4791 return getpwnam (egetenv ("USER"));
4792 else
4793 return 0;
4794 #endif /* not READ_SYSUAF */
4797 /* return total address space available to the current process. This is
4798 the sum of the current p0 size, p1 size and free page table entries
4799 available. */
4801 vlimit ()
4803 int item_code;
4804 unsigned long free_pages;
4805 unsigned long frep0va;
4806 unsigned long frep1va;
4807 register status;
4809 item_code = JPI$_FREPTECNT;
4810 if (((status = LIB$GETJPI (&item_code, 0, 0, &free_pages)) & 1) == 0)
4812 errno = EVMSERR;
4813 vaxc$errno = status;
4814 return -1;
4816 free_pages *= 512;
4818 item_code = JPI$_FREP0VA;
4819 if (((status = LIB$GETJPI (&item_code, 0, 0, &frep0va)) & 1) == 0)
4821 errno = EVMSERR;
4822 vaxc$errno = status;
4823 return -1;
4825 item_code = JPI$_FREP1VA;
4826 if (((status = LIB$GETJPI (&item_code, 0, 0, &frep1va)) & 1) == 0)
4828 errno = EVMSERR;
4829 vaxc$errno = status;
4830 return -1;
4833 return free_pages + frep0va + (0x7fffffff - frep1va);
4837 define_logical_name (varname, string)
4838 char *varname;
4839 char *string;
4841 struct dsc$descriptor_s strdsc =
4842 {strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string};
4843 struct dsc$descriptor_s envdsc =
4844 {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
4845 struct dsc$descriptor_s lnmdsc =
4846 {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
4848 return LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
4852 delete_logical_name (varname)
4853 char *varname;
4855 struct dsc$descriptor_s envdsc =
4856 {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
4857 struct dsc$descriptor_s lnmdsc =
4858 {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
4860 return LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
4864 ulimit ()
4866 return 0;
4870 setpgrp ()
4872 return 0;
4876 execvp ()
4878 error ("execvp system call not implemented");
4879 return -1;
4883 rename (from, to)
4884 char *from, *to;
4886 int status;
4887 struct FAB from_fab = cc$rms_fab, to_fab = cc$rms_fab;
4888 struct NAM from_nam = cc$rms_nam, to_nam = cc$rms_nam;
4889 char from_esn[NAM$C_MAXRSS];
4890 char to_esn[NAM$C_MAXRSS];
4892 from_fab.fab$l_fna = from;
4893 from_fab.fab$b_fns = strlen (from);
4894 from_fab.fab$l_nam = &from_nam;
4895 from_fab.fab$l_fop = FAB$M_NAM;
4897 from_nam.nam$l_esa = from_esn;
4898 from_nam.nam$b_ess = sizeof from_esn;
4900 to_fab.fab$l_fna = to;
4901 to_fab.fab$b_fns = strlen (to);
4902 to_fab.fab$l_nam = &to_nam;
4903 to_fab.fab$l_fop = FAB$M_NAM;
4905 to_nam.nam$l_esa = to_esn;
4906 to_nam.nam$b_ess = sizeof to_esn;
4908 status = SYS$RENAME (&from_fab, 0, 0, &to_fab);
4910 if (status & 1)
4911 return 0;
4912 else
4914 if (status == RMS$_DEV)
4915 errno = EXDEV;
4916 else
4917 errno = EVMSERR;
4918 vaxc$errno = status;
4919 return -1;
4923 /* This function renames a file like `rename', but it strips
4924 the version number from the "to" filename, such that the "to" file is
4925 will always be a new version. It also sets the file protection once it is
4926 finished. The protection that we will use is stored in fab_final_pro,
4927 and was set when we did a creat_copy_attrs to create the file that we
4928 are renaming.
4930 We could use the chmod function, but Eunichs uses 3 bits per user category
4931 to describe the protection, and VMS uses 4 (write and delete are separate
4932 bits). To maintain portability, the VMS implementation of `chmod' wires
4933 the W and D bits together. */
4936 static struct fibdef fib; /* We need this initialized to zero */
4937 char vms_file_written[NAM$C_MAXRSS];
4940 rename_sans_version (from,to)
4941 char *from, *to;
4943 short int chan;
4944 int stat;
4945 short int iosb[4];
4946 int status;
4947 struct FAB to_fab = cc$rms_fab;
4948 struct NAM to_nam = cc$rms_nam;
4949 struct dsc$descriptor fib_d ={sizeof (fib),0,0,(char*) &fib};
4950 struct dsc$descriptor fib_attr[2]
4951 = {{sizeof (fab_final_pro),ATR$C_FPRO,0,(char*) &fab_final_pro},{0,0,0,0}};
4952 char to_esn[NAM$C_MAXRSS];
4954 $DESCRIPTOR (disk,to_esn);
4956 to_fab.fab$l_fna = to;
4957 to_fab.fab$b_fns = strlen (to);
4958 to_fab.fab$l_nam = &to_nam;
4959 to_fab.fab$l_fop = FAB$M_NAM;
4961 to_nam.nam$l_esa = to_esn;
4962 to_nam.nam$b_ess = sizeof to_esn;
4964 status = SYS$PARSE (&to_fab, 0, 0); /* figure out the full file name */
4966 if (to_nam.nam$l_fnb && NAM$M_EXP_VER)
4967 *(to_nam.nam$l_ver) = '\0';
4969 stat = rename (from, to_esn);
4970 if (stat < 0)
4971 return stat;
4973 strcpy (vms_file_written, to_esn);
4975 to_fab.fab$l_fna = vms_file_written; /* this points to the versionless name */
4976 to_fab.fab$b_fns = strlen (vms_file_written);
4978 /* Now set the file protection to the correct value */
4979 SYS$OPEN (&to_fab, 0, 0); /* This fills in the nam$w_fid fields */
4981 /* Copy these fields into the fib */
4982 fib.fib$r_fid_overlay.fib$w_fid[0] = to_nam.nam$w_fid[0];
4983 fib.fib$r_fid_overlay.fib$w_fid[1] = to_nam.nam$w_fid[1];
4984 fib.fib$r_fid_overlay.fib$w_fid[2] = to_nam.nam$w_fid[2];
4986 SYS$CLOSE (&to_fab, 0, 0);
4988 stat = SYS$ASSIGN (&disk, &chan, 0, 0); /* open a channel to the disk */
4989 if (!stat)
4990 LIB$SIGNAL (stat);
4991 stat = SYS$QIOW (0, chan, IO$_MODIFY, iosb, 0, 0, &fib_d,
4992 0, 0, 0, &fib_attr, 0);
4993 if (!stat)
4994 LIB$SIGNAL (stat);
4995 stat = SYS$DASSGN (chan);
4996 if (!stat)
4997 LIB$SIGNAL (stat);
4998 strcpy (vms_file_written, to_esn); /* We will write this to the terminal*/
4999 return 0;
5003 link (file, new)
5004 char * file, * new;
5006 register status;
5007 struct FAB fab;
5008 struct NAM nam;
5009 unsigned short fid[3];
5010 char esa[NAM$C_MAXRSS];
5012 fab = cc$rms_fab;
5013 fab.fab$l_fop = FAB$M_OFP;
5014 fab.fab$l_fna = file;
5015 fab.fab$b_fns = strlen (file);
5016 fab.fab$l_nam = &nam;
5018 nam = cc$rms_nam;
5019 nam.nam$l_esa = esa;
5020 nam.nam$b_ess = NAM$C_MAXRSS;
5022 status = SYS$PARSE (&fab);
5023 if ((status & 1) == 0)
5025 errno = EVMSERR;
5026 vaxc$errno = status;
5027 return -1;
5029 status = SYS$SEARCH (&fab);
5030 if ((status & 1) == 0)
5032 errno = EVMSERR;
5033 vaxc$errno = status;
5034 return -1;
5037 fid[0] = nam.nam$w_fid[0];
5038 fid[1] = nam.nam$w_fid[1];
5039 fid[2] = nam.nam$w_fid[2];
5041 fab.fab$l_fna = new;
5042 fab.fab$b_fns = strlen (new);
5044 status = SYS$PARSE (&fab);
5045 if ((status & 1) == 0)
5047 errno = EVMSERR;
5048 vaxc$errno = status;
5049 return -1;
5052 nam.nam$w_fid[0] = fid[0];
5053 nam.nam$w_fid[1] = fid[1];
5054 nam.nam$w_fid[2] = fid[2];
5056 nam.nam$l_esa = nam.nam$l_name;
5057 nam.nam$b_esl = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver;
5059 status = SYS$ENTER (&fab);
5060 if ((status & 1) == 0)
5062 errno = EVMSERR;
5063 vaxc$errno = status;
5064 return -1;
5067 return 0;
5070 void
5071 croak (badfunc)
5072 char *badfunc;
5074 printf ("%s not yet implemented\r\n", badfunc);
5075 reset_sys_modes ();
5076 exit (1);
5079 long
5080 random ()
5082 /* Arrange to return a range centered on zero. */
5083 return rand () - (1 << 30);
5086 void
5087 srandom (seed)
5089 srand (seed);
5091 #endif /* VMS */
5093 #ifdef AIXHFT
5095 /* Called from init_sys_modes. */
5096 void
5097 hft_init ()
5099 int junk;
5101 /* If we're not on an HFT we shouldn't do any of this. We determine
5102 if we are on an HFT by trying to get an HFT error code. If this
5103 call fails, we're not on an HFT. */
5104 #ifdef IBMR2AIX
5105 if (ioctl (0, HFQERROR, &junk) < 0)
5106 return;
5107 #else /* not IBMR2AIX */
5108 if (ioctl (0, HFQEIO, 0) < 0)
5109 return;
5110 #endif /* not IBMR2AIX */
5112 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5113 as the rubout key's ASCII code. Here this is changed. The bug is that
5114 there's no way to determine the old mapping, so in reset_sys_modes
5115 we need to assume that the normal map had been present. Of course, this
5116 code also doesn't help if on a terminal emulator which doesn't understand
5117 HFT VTD's. */
5119 struct hfbuf buf;
5120 struct hfkeymap keymap;
5122 buf.hf_bufp = (char *)&keymap;
5123 buf.hf_buflen = sizeof (keymap);
5124 keymap.hf_nkeys = 2;
5125 keymap.hfkey[0].hf_kpos = 15;
5126 keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
5127 #ifdef IBMR2AIX
5128 keymap.hfkey[0].hf_keyidh = '<';
5129 #else /* not IBMR2AIX */
5130 keymap.hfkey[0].hf_page = '<';
5131 #endif /* not IBMR2AIX */
5132 keymap.hfkey[0].hf_char = 127;
5133 keymap.hfkey[1].hf_kpos = 15;
5134 keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
5135 #ifdef IBMR2AIX
5136 keymap.hfkey[1].hf_keyidh = '<';
5137 #else /* not IBMR2AIX */
5138 keymap.hfkey[1].hf_page = '<';
5139 #endif /* not IBMR2AIX */
5140 keymap.hfkey[1].hf_char = 127;
5141 hftctl (0, HFSKBD, &buf);
5143 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
5144 at times. */
5145 line_ins_del_ok = char_ins_del_ok = 0;
5148 /* Reset the rubout key to backspace. */
5150 void
5151 hft_reset ()
5153 struct hfbuf buf;
5154 struct hfkeymap keymap;
5155 int junk;
5157 #ifdef IBMR2AIX
5158 if (ioctl (0, HFQERROR, &junk) < 0)
5159 return;
5160 #else /* not IBMR2AIX */
5161 if (ioctl (0, HFQEIO, 0) < 0)
5162 return;
5163 #endif /* not IBMR2AIX */
5165 buf.hf_bufp = (char *)&keymap;
5166 buf.hf_buflen = sizeof (keymap);
5167 keymap.hf_nkeys = 2;
5168 keymap.hfkey[0].hf_kpos = 15;
5169 keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
5170 #ifdef IBMR2AIX
5171 keymap.hfkey[0].hf_keyidh = '<';
5172 #else /* not IBMR2AIX */
5173 keymap.hfkey[0].hf_page = '<';
5174 #endif /* not IBMR2AIX */
5175 keymap.hfkey[0].hf_char = 8;
5176 keymap.hfkey[1].hf_kpos = 15;
5177 keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
5178 #ifdef IBMR2AIX
5179 keymap.hfkey[1].hf_keyidh = '<';
5180 #else /* not IBMR2AIX */
5181 keymap.hfkey[1].hf_page = '<';
5182 #endif /* not IBMR2AIX */
5183 keymap.hfkey[1].hf_char = 8;
5184 hftctl (0, HFSKBD, &buf);
5187 #endif /* AIXHFT */
5189 #ifdef USE_DL_STUBS
5191 /* These are included on Sunos 4.1 when we do not use shared libraries.
5192 X11 libraries may refer to these functions but (we hope) do not
5193 actually call them. */
5195 void *
5196 dlopen ()
5198 return 0;
5201 void *
5202 dlsym ()
5204 return 0;
5208 dlclose ()
5210 return -1;
5213 #endif /* USE_DL_STUBS */
5215 #ifndef BSTRING
5217 #ifndef bzero
5219 void
5220 bzero (b, length)
5221 register char *b;
5222 register int length;
5224 #ifdef VMS
5225 short zero = 0;
5226 long max_str = 65535;
5228 while (length > max_str) {
5229 (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
5230 length -= max_str;
5231 b += max_str;
5233 max_str = length;
5234 (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
5235 #else
5236 while (length-- > 0)
5237 *b++ = 0;
5238 #endif /* not VMS */
5241 #endif /* no bzero */
5242 #endif /* BSTRING */
5244 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5245 #undef bcopy
5247 /* Saying `void' requires a declaration, above, where bcopy is used
5248 and that declaration causes pain for systems where bcopy is a macro. */
5249 bcopy (b1, b2, length)
5250 register char *b1;
5251 register char *b2;
5252 register int length;
5254 #ifdef VMS
5255 long max_str = 65535;
5257 while (length > max_str) {
5258 (void) LIB$MOVC3 (&max_str, b1, b2);
5259 length -= max_str;
5260 b1 += max_str;
5261 b2 += max_str;
5263 max_str = length;
5264 (void) LIB$MOVC3 (&length, b1, b2);
5265 #else
5266 while (length-- > 0)
5267 *b2++ = *b1++;
5268 #endif /* not VMS */
5270 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5272 #ifndef BSTRING
5273 #ifndef bcmp
5275 bcmp (b1, b2, length) /* This could be a macro! */
5276 register char *b1;
5277 register char *b2;
5278 register int length;
5280 #ifdef VMS
5281 struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
5282 struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
5284 return STR$COMPARE (&src1, &src2);
5285 #else
5286 while (length-- > 0)
5287 if (*b1++ != *b2++)
5288 return 1;
5290 return 0;
5291 #endif /* not VMS */
5293 #endif /* no bcmp */
5294 #endif /* not BSTRING */
5296 #ifndef HAVE_STRSIGNAL
5297 char *
5298 strsignal (code)
5299 int code;
5301 char *signame = 0;
5303 if (0 <= code && code < NSIG)
5305 #ifdef VMS
5306 signame = sys_errlist[code];
5307 #else
5308 /* Cast to suppress warning if the table has const char *. */
5309 signame = (char *) sys_siglist[code];
5310 #endif
5313 return signame;
5315 #endif /* HAVE_STRSIGNAL */