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)
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. */
32 /* Including stdlib.h isn't necessarily enough to get srandom
33 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
35 #if 0 /* It turns out that defining _OSF_SOURCE in osf5-0.h gets
36 random prototyped as returning `int'. It looks to me as
37 though the best way to DTRT is to prefer the rand48 functions
38 (per libc.info). -- fx */
39 extern long int random
P_ ((void));
41 #if 0 /* Don't prototype srandom; it takes an unsigned argument on
42 some systems, and an unsigned long on others, like FreeBSD
44 extern void srandom
P_ ((unsigned int));
48 #include "blockinput.h"
52 /* It is essential to include stdlib.h so that this file picks up
53 the correct definitions of rand, srand, and RAND_MAX.
54 Otherwise random numbers will not work correctly. */
58 /* Nonzero means delete a process right away if it exits (process.c). */
59 static int delete_exited_processes
;
65 #define write sys_write
70 #endif /* not WINDOWSNT */
76 /* Does anyone other than VMS need this? */
78 #define sys_fwrite fwrite
84 #include <sys/types.h>
88 /* Get _POSIX_VDISABLE, if it is available. */
98 #if !defined (USG) || defined (BSD_PGRPS)
100 #define setpgrp setpgid
104 /* Get SI_SRPC_DOMAIN, if it is available. */
105 #ifdef HAVE_SYS_SYSTEMINFO_H
106 #include <sys/systeminfo.h>
109 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
113 #include <sys/param.h>
117 extern unsigned start
__asm__ ("start");
139 #include <sys/file.h>
147 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
151 #include <sys/file.h>
159 #include <sys/ioctl.h>
165 #ifdef BROKEN_TIOCGWINSZ
170 #if defined (USG) || defined (DGUX)
171 #include <sys/utsname.h>
172 #ifndef MEMORY_IN_STRING_H
175 #if defined (TIOCGWINSZ) || defined (ISC4_0)
177 #include <sys/sioctl.h>
180 #include <sys/stream.h>
181 #include <sys/ptem.h>
183 #endif /* TIOCGWINSZ or ISC4_0 */
184 #endif /* USG or DGUX */
186 extern int quit_char
;
188 #include "keyboard.h"
191 #include "termhooks.h"
192 #include "termchar.h"
193 #include "termopts.h"
194 #include "dispextern.h"
199 /* In process.h which conflicts with the local copy. */
201 int _CRTAPI1
_spawnlp (int, const char *, const char *, ...);
202 int _CRTAPI1
_getpid (void);
205 #ifdef NONSYSTEM_DIR_LIBRARY
207 #endif /* NONSYSTEM_DIR_LIBRARY */
209 #include "syssignal.h"
216 #ifndef HAVE_STRUCT_UTIMBUF
217 /* We want to use utime rather than utimes, but we couldn't find the
218 structure declaration. We'll use the traditional one. */
226 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
232 #define LNOFLSH 0100000
235 static int baud_convert
[] =
240 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
241 1800, 2400, 4800, 9600, 19200, 38400
248 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
250 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
258 /* The file descriptor for Emacs's input terminal.
259 Under Unix, this is normally zero except when using X;
260 under VMS, we place the input channel number here. */
263 void croak
P_ ((char *));
270 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
272 SIGMASKTYPE sigprocmask_set
;
275 /* Specify a different file descriptor for further input operations. */
284 /* Discard pending input on descriptor input_fd. */
290 struct emacs_tty buf
;
295 /* Discarding input is not safe when the input could contain
296 replies from the X server. So don't do it. */
297 if (read_socket_hook
)
302 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
303 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
309 ioctl (input_fd
, TIOCFLUSH
, &zero
);
311 #else /* not Apollo */
312 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
313 while (dos_keyread () != -1)
315 #else /* not MSDOS */
316 EMACS_GET_TTY (input_fd
, &buf
);
317 EMACS_SET_TTY (input_fd
, &buf
, 0);
318 #endif /* not MSDOS */
319 #endif /* not Apollo */
321 #endif /* not WINDOWSNT */
326 /* Arrange for character C to be read as the next input from
337 if (read_socket_hook
)
340 /* Should perhaps error if in batch mode */
342 ioctl (input_fd
, TIOCSTI
, &c
);
343 #else /* no TIOCSTI */
344 error ("Cannot stuff terminal input characters in this version of Unix");
345 #endif /* no TIOCSTI */
357 #ifdef INIT_BAUD_RATE
362 #else /* not DOS_NT */
366 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
367 &sg
.class, 12, 0, 0, 0, 0 );
368 emacs_ospeed
= sg
.xmit_baud
;
374 tcgetattr (input_fd
, &sg
);
375 emacs_ospeed
= cfgetospeed (&sg
);
376 #if defined (USE_GETOBAUD) && defined (getobaud)
377 /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
378 if (emacs_ospeed
== 0)
379 emacs_ospeed
= getobaud (sg
.c_cflag
);
381 #else /* neither VMS nor TERMIOS */
387 tcgetattr (input_fd
, &sg
);
389 ioctl (input_fd
, TCGETA
, &sg
);
391 emacs_ospeed
= sg
.c_cflag
& CBAUD
;
392 #else /* neither VMS nor TERMIOS nor TERMIO */
395 sg
.sg_ospeed
= B9600
;
396 if (ioctl (input_fd
, TIOCGETP
, &sg
) < 0)
398 emacs_ospeed
= sg
.sg_ospeed
;
399 #endif /* not HAVE_TERMIO */
400 #endif /* not HAVE_TERMIOS */
402 #endif /* not DOS_NT */
403 #endif /* not INIT_BAUD_RATE */
406 baud_rate
= (emacs_ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
407 ? baud_convert
[emacs_ospeed
] : 9600);
414 set_exclusive_use (fd
)
418 ioctl (fd
, FIOCLEX
, 0);
420 /* Ok to do nothing if this feature does not exist */
425 wait_without_blocking ()
428 wait3 (0, WNOHANG
| WUNTRACED
, 0);
430 croak ("wait_without_blocking");
432 synch_process_alive
= 0;
435 #endif /* not subprocesses */
437 int wait_debugging
; /* Set nonzero to make following function work under dbx
438 (at least for bsd). */
441 wait_for_termination_signal ()
444 /* Wait for subprocess with process id `pid' to terminate and
445 make sure it will get eliminated (not remain forever as a zombie) */
448 wait_for_termination (pid
)
457 status
= SYS$
FORCEX (&pid
, 0, 0);
460 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
461 /* Note that kill returns -1 even if the process is just a zombie now.
462 But inevitably a SIGCHLD interrupt should be generated
463 and child_sig will do wait3 and make the process go away. */
464 /* There is some indication that there is a bug involved with
465 termination of subprocesses, perhaps involving a kernel bug too,
466 but no idea what it is. Just as a hunch we signal SIGCHLD to see
467 if that causes the problem to go away or get worse. */
468 sigsetmask (sigmask (SIGCHLD
));
469 if (0 > kill (pid
, 0))
471 sigsetmask (SIGEMPTYMASK
);
472 kill (getpid (), SIGCHLD
);
478 sigpause (SIGEMPTYMASK
);
479 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
480 #if defined (UNIPLUS)
481 if (0 > kill (pid
, 0))
484 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
485 #ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */
486 sigblock (sigmask (SIGCHLD
));
488 if (kill (pid
, 0) == -1 && errno
== ESRCH
)
490 sigunblock (sigmask (SIGCHLD
));
494 sigsuspend (&empty_mask
);
495 #else /* not POSIX_SIGNALS */
496 #ifdef HAVE_SYSV_SIGPAUSE
498 if (0 > kill (pid
, 0))
504 #else /* not HAVE_SYSV_SIGPAUSE */
508 #else /* not WINDOWSNT */
509 if (0 > kill (pid
, 0))
511 /* Using sleep instead of pause avoids timing error.
512 If the inferior dies just before the sleep,
513 we lose just one second. */
515 #endif /* not WINDOWSNT */
516 #endif /* not HAVE_SYSV_SIGPAUSE */
517 #endif /* not POSIX_SIGNALS */
518 #endif /* not UNIPLUS */
519 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
521 #else /* not subprocesses */
524 #else /* not __DJGPP__ > 1 */
526 if (kill (pid
, 0) < 0)
532 if (status
== pid
|| status
== -1)
535 #endif /* not __DJGPP__ > 1*/
536 #endif /* not subprocesses */
543 * flush any pending output
544 * (may flush input as well; it does not matter the way we use it)
548 flush_pending_output (channel
)
552 /* If we try this, we get hit with SIGTTIN, because
553 the child's tty belongs to the child's pgrp. */
556 ioctl (channel
, TCFLSH
, 1);
560 /* 3rd arg should be ignored
561 but some 4.2 kernels actually want the address of an int
562 and nonzero means something different. */
563 ioctl (channel
, TIOCFLUSH
, &zero
);
570 /* Set up the terminal at the other end of a pseudo-terminal that
571 we will be controlling an inferior through.
572 It should not echo or do line-editing, since that is done
573 in Emacs. No padding needed for insertion into an Emacs buffer. */
576 child_setup_tty (out
)
582 EMACS_GET_TTY (out
, &s
);
584 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
585 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
586 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
588 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
589 /* No output delays */
591 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
592 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
593 #if 0 /* This causes bugs in (for instance) telnet to certain sites. */
594 s
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
595 #ifdef INLCR /* Just being cautious, since I can't check how
596 widespread INLCR is--rms. */
597 s
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
601 s
.main
.c_iflag
&= ~IUCLC
; /* Disable downcasing on input. */
604 s
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
607 s
.main
.c_oflag
&= ~OLCUC
; /* Disable upcasing on output. */
609 s
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
610 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CSIZE
) | CS8
; /* Don't strip 8th bit */
612 /* Said to be unnecessary: */
613 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
614 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
617 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
618 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
619 s
.main
.c_cc
[VERASE
] = CDISABLE
; /* disable erase processing */
620 s
.main
.c_cc
[VKILL
] = CDISABLE
; /* disable kill processing */
623 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
627 /* AIX enhanced edit loses NULs, so disable it */
630 s
.main
.c_iflag
&= ~ASCEDIT
;
632 /* Also, PTY overloads NUL and BREAK.
633 don't ignore break, but don't signal either, so it looks like NUL. */
634 s
.main
.c_iflag
&= ~IGNBRK
;
635 s
.main
.c_iflag
&= ~BRKINT
;
636 /* QUIT and INTR work better as signals, so disable character forms */
637 s
.main
.c_cc
[VINTR
] = 0377;
638 #ifdef SIGNALS_VIA_CHARACTERS
639 /* the QUIT and INTR character are used in process_send_signal
640 so set them here to something useful. */
641 if (s
.main
.c_cc
[VQUIT
] == 0377)
642 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
643 if (s
.main
.c_cc
[VINTR
] == 0377)
644 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
645 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
646 /* QUIT and INTR work better as signals, so disable character forms */
647 s
.main
.c_cc
[VQUIT
] = 0377;
648 s
.main
.c_cc
[VINTR
] = 0377;
649 s
.main
.c_lflag
&= ~ISIG
;
650 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
651 s
.main
.c_cc
[VEOL
] = 0377;
652 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
655 #else /* not HAVE_TERMIO */
657 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
659 s
.main
.sg_flags
|= LPASS8
;
660 s
.main
.sg_erase
= 0377;
661 s
.main
.sg_kill
= 0377;
662 s
.lmode
= LLITOUT
| s
.lmode
; /* Don't strip 8th bit */
664 #endif /* not HAVE_TERMIO */
666 EMACS_SET_TTY (out
, &s
, 0);
675 ioctl (out
, FIOASYNC
, &zero
);
678 #endif /* not DOS_NT */
682 #endif /* subprocesses */
684 /* Record a signal code and the handler for it. */
688 SIGTYPE (*handler
) P_ ((int));
691 static void save_signal_handlers
P_ ((struct save_signal
*));
692 static void restore_signal_handlers
P_ ((struct save_signal
*));
694 /* Suspend the Emacs process; give terminal to its superior. */
700 /* "Foster" parentage allows emacs to return to a subprocess that attached
701 to the current emacs as a cheaper than starting a whole new process. This
702 is set up by KEPTEDITOR.COM. */
703 unsigned long parent_id
, foster_parent_id
;
706 fpid_string
= getenv ("EMACS_PARENT_PID");
707 if (fpid_string
!= NULL
)
709 sscanf (fpid_string
, "%x", &foster_parent_id
);
710 if (foster_parent_id
!= 0)
711 parent_id
= foster_parent_id
;
713 parent_id
= getppid ();
716 parent_id
= getppid ();
718 xfree (fpid_string
); /* On VMS, this was malloc'd */
720 if (parent_id
&& parent_id
!= 0xffffffff)
722 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
723 int status
= LIB$
ATTACH (&parent_id
) & 1;
724 signal (SIGINT
, oldsig
);
733 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
734 d_prompt
.a
= "Emacs: "; /* Just a reminder */
735 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
740 #if defined (SIGTSTP) && !defined (MSDOS)
743 int pgrp
= EMACS_GETPGRP (0);
744 EMACS_KILLPG (pgrp
, SIGTSTP
);
747 #else /* No SIGTSTP */
748 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
749 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
750 kill (getpid (), SIGQUIT
);
752 #else /* No SIGTSTP or USG_JOBCTRL */
754 /* On a system where suspending is not implemented,
755 instead fork a subshell and let it talk directly to the terminal
759 #endif /* no USG_JOBCTRL */
760 #endif /* no SIGTSTP */
764 /* Fork a subshell. */
771 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
773 char oldwd
[MAXPATHLEN
+1]; /* Fixed length is safe on MSDOS. */
776 struct save_signal saved_handlers
[5];
778 unsigned char *str
= 0;
781 saved_handlers
[0].code
= SIGINT
;
782 saved_handlers
[1].code
= SIGQUIT
;
783 saved_handlers
[2].code
= SIGTERM
;
785 saved_handlers
[3].code
= SIGIO
;
786 saved_handlers
[4].code
= 0;
788 saved_handlers
[3].code
= 0;
791 /* Mentioning current_buffer->buffer would mean including buffer.h,
792 which somehow wedges the hp compiler. So instead... */
794 dir
= intern ("default-directory");
795 if (NILP (Fboundp (dir
)))
797 dir
= Fsymbol_value (dir
);
801 dir
= expand_and_dir_to_file (Funhandled_file_name_directory (dir
), Qnil
);
802 str
= (unsigned char *) alloca (SCHARS (dir
) + 2);
804 bcopy (SDATA (dir
), str
, len
);
805 if (str
[len
- 1] != '/') str
[len
++] = '/';
812 save_signal_handlers (saved_handlers
);
813 synch_process_alive
= 1;
814 #endif /* __DJGPP__ > 1 */
818 error ("Can't spawn subshell");
825 #ifdef DOS_NT /* MW, Aug 1993 */
828 sh
= (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
831 sh
= (char *) egetenv ("SHELL");
835 /* Use our buffer's default directory for the subshell. */
837 chdir ((char *) str
);
840 close_process_descs (); /* Close Emacs's pipes/ptys */
843 #ifdef SET_EMACS_PRIORITY
845 extern EMACS_INT emacs_priority
;
847 if (emacs_priority
< 0)
848 nice (-emacs_priority
);
852 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
854 char *epwd
= getenv ("PWD");
855 char old_pwd
[MAXPATHLEN
+1+4];
857 /* If PWD is set, pass it with corrected value. */
860 strcpy (old_pwd
, epwd
);
861 if (str
[len
- 1] == '/')
863 setenv ("PWD", str
, 1);
868 putenv (old_pwd
); /* restore previous value */
870 #if 0 /* This is also reported if last command executed in subshell failed, KFS */
872 report_file_error ("Can't execute subshell", Fcons (build_string (sh
), Qnil
));
874 #else /* not MSDOS */
876 /* Waits for process completion */
877 pid
= _spawnlp (_P_WAIT
, sh
, sh
, NULL
);
880 write (1, "Can't execute subshell", 22);
881 #else /* not WINDOWSNT */
883 write (1, "Can't execute subshell", 22);
885 #endif /* not WINDOWSNT */
886 #endif /* not MSDOS */
889 /* Do this now if we did not do it before. */
890 #if !defined (MSDOS) || __DJGPP__ == 1
891 save_signal_handlers (saved_handlers
);
892 synch_process_alive
= 1;
896 wait_for_termination (pid
);
898 restore_signal_handlers (saved_handlers
);
899 synch_process_alive
= 0;
902 #endif /* !MAC_OS8 */
905 save_signal_handlers (saved_handlers
)
906 struct save_signal
*saved_handlers
;
908 while (saved_handlers
->code
)
910 saved_handlers
->handler
911 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers
->code
, SIG_IGN
);
917 restore_signal_handlers (saved_handlers
)
918 struct save_signal
*saved_handlers
;
920 while (saved_handlers
->code
)
922 signal (saved_handlers
->code
, saved_handlers
->handler
);
936 old_fcntl_flags
= fcntl (fd
, F_GETFL
, 0) & ~FASYNC
;
937 fcntl (fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
939 interrupts_deferred
= 0;
948 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
953 if (read_socket_hook
)
957 sigunblock (sigmask (SIGWINCH
));
959 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
961 interrupts_deferred
= 0;
967 if (read_socket_hook
)
971 sigblock (sigmask (SIGWINCH
));
973 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
);
974 interrupts_deferred
= 1;
977 #else /* no FASYNC */
978 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
985 if (read_socket_hook
)
988 ioctl (input_fd
, FIOASYNC
, &on
);
989 interrupts_deferred
= 0;
997 if (read_socket_hook
)
1000 ioctl (input_fd
, FIOASYNC
, &off
);
1001 interrupts_deferred
= 1;
1004 #else /* not FASYNC, not STRIDE */
1008 #include <termios.h>
1016 if (read_socket_hook
)
1020 sigaddset (&st
, SIGIO
);
1021 ioctl (input_fd
, FIOASYNC
, &on
);
1022 interrupts_deferred
= 0;
1023 sigprocmask (SIG_UNBLOCK
, &st
, (sigset_t
*)0);
1031 if (read_socket_hook
)
1034 ioctl (input_fd
, FIOASYNC
, &off
);
1035 interrupts_deferred
= 1;
1038 #else /* ! _CX_UX */
1044 if (read_socket_hook
)
1047 croak ("request_sigio");
1053 if (read_socket_hook
)
1056 croak ("unrequest_sigio");
1063 #endif /* F_SETFL */
1065 /* Saving and restoring the process group of Emacs's terminal. */
1069 /* The process group of which Emacs was a member when it initially
1072 If Emacs was in its own process group (i.e. inherited_pgroup ==
1073 getpid ()), then we know we're running under a shell with job
1074 control (Emacs would never be run as part of a pipeline).
1077 If Emacs was not in its own process group, then we know we're
1078 running under a shell (or a caller) that doesn't know how to
1079 separate itself from Emacs (like sh). Emacs must be in its own
1080 process group in order to receive SIGIO correctly. In this
1081 situation, we put ourselves in our own pgroup, forcibly set the
1082 tty's pgroup to our pgroup, and make sure to restore and reinstate
1083 the tty's pgroup just like any other terminal setting. If
1084 inherited_group was not the tty's pgroup, then we'll get a
1085 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1086 it goes foreground in the future, which is what should happen. */
1087 int inherited_pgroup
;
1089 /* Split off the foreground process group to Emacs alone.
1090 When we are in the foreground, but not started in our own process
1091 group, redirect the TTY to point to our own process group. We need
1092 to be in our own process group to receive SIGIO properly. */
1094 narrow_foreground_group ()
1098 setpgrp (0, inherited_pgroup
);
1099 if (inherited_pgroup
!= me
)
1100 EMACS_SET_TTY_PGRP (input_fd
, &me
);
1104 /* Set the tty to our original foreground group. */
1106 widen_foreground_group ()
1108 if (inherited_pgroup
!= getpid ())
1109 EMACS_SET_TTY_PGRP (input_fd
, &inherited_pgroup
);
1110 setpgrp (0, inherited_pgroup
);
1113 #endif /* BSD_PGRPS */
1115 /* Getting and setting emacs_tty structures. */
1117 /* Set *TC to the parameters associated with the terminal FD.
1118 Return zero if all's well, or -1 if we ran into an error we
1119 couldn't deal with. */
1121 emacs_get_tty (fd
, settings
)
1123 struct emacs_tty
*settings
;
1125 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1127 /* We have those nifty POSIX tcmumbleattr functions. */
1128 bzero (&settings
->main
, sizeof (settings
->main
));
1129 if (tcgetattr (fd
, &settings
->main
) < 0)
1134 /* The SYSV-style interface? */
1135 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
1140 /* Vehemently Monstrous System? :-) */
1141 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
1142 &settings
->main
.class, 12, 0, 0, 0, 0)
1148 /* I give up - I hope you have the BSD ioctls. */
1149 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
1151 #endif /* not DOS_NT */
1156 /* Suivant - Do we have to get struct ltchars data? */
1158 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
1162 /* How about a struct tchars and a wordful of lmode bits? */
1164 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
1165 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
1169 /* We have survived the tempest. */
1174 /* Set the parameters of the tty on FD according to the contents of
1175 *SETTINGS. If FLUSHP is non-zero, we discard input.
1176 Return 0 if all went well, and -1 if anything failed. */
1179 emacs_set_tty (fd
, settings
, flushp
)
1181 struct emacs_tty
*settings
;
1184 /* Set the primary parameters - baud rate, character size, etcetera. */
1187 /* We have those nifty POSIX tcmumbleattr functions.
1188 William J. Smith <wjs@wiis.wang.com> writes:
1189 "POSIX 1003.1 defines tcsetattr to return success if it was
1190 able to perform any of the requested actions, even if some
1191 of the requested actions could not be performed.
1192 We must read settings back to ensure tty setup properly.
1193 AIX requires this to keep tty from hanging occasionally." */
1194 /* This make sure that we don't loop indefinitely in here. */
1195 for (i
= 0 ; i
< 10 ; i
++)
1196 if (tcsetattr (fd
, flushp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
1207 bzero (&new, sizeof (new));
1208 /* Get the current settings, and see if they're what we asked for. */
1209 tcgetattr (fd
, &new);
1210 /* We cannot use memcmp on the whole structure here because under
1211 * aix386 the termios structure has some reserved field that may
1214 if ( new.c_iflag
== settings
->main
.c_iflag
1215 && new.c_oflag
== settings
->main
.c_oflag
1216 && new.c_cflag
== settings
->main
.c_cflag
1217 && new.c_lflag
== settings
->main
.c_lflag
1218 && memcmp (new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
1226 /* The SYSV-style interface? */
1227 if (ioctl (fd
, flushp
? TCSETAF
: TCSETAW
, &settings
->main
) < 0)
1232 /* Vehemently Monstrous System? :-) */
1233 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
1234 &settings
->main
.class, 12, 0, 0, 0, 0)
1240 /* I give up - I hope you have the BSD ioctls. */
1241 if (ioctl (fd
, (flushp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
1243 #endif /* not DOS_NT */
1249 /* Suivant - Do we have to get struct ltchars data? */
1251 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
1255 /* How about a struct tchars and a wordful of lmode bits? */
1257 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
1258 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
1262 /* We have survived the tempest. */
1267 /* The initial tty mode bits */
1268 struct emacs_tty old_tty
;
1270 /* 1 if we have been through init_sys_modes. */
1273 /* 1 if outer tty status has been recorded. */
1277 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1282 #ifndef F_SETOWN_BUG
1284 int old_fcntl_owner
;
1285 #endif /* F_SETOWN */
1286 #endif /* F_SETOWN_BUG */
1288 /* This may also be defined in stdio,
1289 but if so, this does no harm,
1290 and using the same name avoids wasting the other one's space. */
1293 extern char *_sobuf
;
1295 #if defined (USG) || defined (DGUX)
1296 unsigned char _sobuf
[BUFSIZ
+8];
1298 char _sobuf
[BUFSIZ
];
1303 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
1306 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
1312 struct emacs_tty tty
;
1315 /* cus-start.el complains if delete-exited-processes is not defined */
1316 #ifndef subprocesses
1317 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes
,
1318 doc
: /* *Non-nil means delete processes immediately when they exit.
1319 nil means don't delete them until `list-processes' is run. */);
1320 delete_exited_processes
= 0;
1322 #endif /* MAC_OS8 */
1326 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
1327 extern int (*interrupt_signal
) ();
1331 Vtty_erase_char
= Qnil
;
1338 input_ef
= get_kbd_event_flag ();
1339 /* LIB$GET_EF (&input_ef); */
1340 SYS$
CLREF (input_ef
);
1341 waiting_for_ast
= 0;
1343 timer_ef
= get_timer_event_flag ();
1344 /* LIB$GET_EF (&timer_ef); */
1345 SYS$
CLREF (timer_ef
);
1349 LIB$
GET_EF (&process_ef
);
1350 SYS$
CLREF (process_ef
);
1352 if (input_ef
/ 32 != process_ef
/ 32)
1353 croak ("Input and process event flags in different clusters.");
1355 if (input_ef
/ 32 != timer_ef
/ 32)
1356 croak ("Input and timer event flags in different clusters.");
1358 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1359 ((unsigned) 1 << (process_ef
% 32));
1361 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1362 ((unsigned) 1 << (timer_ef
% 32));
1364 sys_access_reinit ();
1366 #endif /* not VMS */
1369 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1370 narrow_foreground_group ();
1373 #ifdef HAVE_WINDOW_SYSTEM
1374 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1375 needs the initialization code below. */
1376 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1379 EMACS_GET_TTY (input_fd
, &old_tty
);
1385 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1386 XSETINT (Vtty_erase_char
, old_tty
.main
.c_cc
[VERASE
]);
1389 /* This allows meta to be sent on 8th bit. */
1390 tty
.main
.c_iflag
&= ~INPCK
; /* don't check input for parity */
1392 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1393 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1394 #ifdef INLCR /* I'm just being cautious,
1395 since I can't check how widespread INLCR is--rms. */
1396 tty
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
1399 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1401 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1402 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1404 tty
.main
.c_lflag
&= ~IEXTEN
; /* Disable other editing characters. */
1406 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1409 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1411 tty
.main
.c_iflag
&= ~IXANY
;
1415 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1416 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1418 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1422 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1423 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1426 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1427 /* Set up C-g for both SIGQUIT and SIGINT.
1428 We don't know which we will get, but we handle both alike
1429 so which one it really gives us does not matter. */
1430 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1431 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1432 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1434 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1438 #if defined (mips) || defined (HAVE_TCATTR)
1440 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1443 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1444 #endif /* V_DSUSP */
1445 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1446 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1449 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1452 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1453 #endif /* VREPRINT */
1455 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1456 #endif /* VWERASE */
1458 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1459 #endif /* VDISCARD */
1464 tty
.main
.c_cc
[VSTART
] = '\021';
1467 tty
.main
.c_cc
[VSTOP
] = '\023';
1473 tty
.main
.c_cc
[VSTART
] = CDISABLE
;
1476 tty
.main
.c_cc
[VSTOP
] = CDISABLE
;
1479 #endif /* mips or HAVE_TCATTR */
1481 #ifdef SET_LINE_DISCIPLINE
1482 /* Need to explicitly request TERMIODISC line discipline or
1483 Ultrix's termios does not work correctly. */
1484 tty
.main
.c_line
= SET_LINE_DISCIPLINE
;
1488 /* AIX enhanced edit loses NULs, so disable it. */
1489 tty
.main
.c_line
= 0;
1490 tty
.main
.c_iflag
&= ~ASCEDIT
;
1492 tty
.main
.c_cc
[VSTRT
] = 255;
1493 tty
.main
.c_cc
[VSTOP
] = 255;
1494 tty
.main
.c_cc
[VSUSP
] = 255;
1495 tty
.main
.c_cc
[VDSUSP
] = 255;
1496 #endif /* IBMR2AIX */
1500 tty
.main
.c_cc
[VSTART
] = '\021';
1503 tty
.main
.c_cc
[VSTOP
] = '\023';
1506 /* Also, PTY overloads NUL and BREAK.
1507 don't ignore break, but don't signal either, so it looks like NUL.
1508 This really serves a purpose only if running in an XTERM window
1509 or via TELNET or the like, but does no harm elsewhere. */
1510 tty
.main
.c_iflag
&= ~IGNBRK
;
1511 tty
.main
.c_iflag
&= ~BRKINT
;
1513 #else /* if not HAVE_TERMIO */
1515 tty
.main
.tt_char
|= TT$M_NOECHO
;
1517 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1519 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1521 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1522 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1523 #else /* not VMS (BSD, that is) */
1525 XSETINT (Vtty_erase_char
, tty
.main
.sg_erase
);
1526 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1528 tty
.main
.sg_flags
|= ANYP
;
1529 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1530 #endif /* not DOS_NT */
1531 #endif /* not VMS (BSD, that is) */
1532 #endif /* not HAVE_TERMIO */
1534 /* If going to use CBREAK mode, we must request C-g to interrupt
1535 and turn off start and stop chars, etc. If not going to use
1536 CBREAK mode, do this anyway so as to turn off local flow
1537 control for user coming over network on 4.2; in this case,
1538 only t_stopc and t_startc really matter. */
1541 /* Note: if not using CBREAK mode, it makes no difference how we
1543 tty
.tchars
= new_tchars
;
1544 tty
.tchars
.t_intrc
= quit_char
;
1547 tty
.tchars
.t_startc
= '\021';
1548 tty
.tchars
.t_stopc
= '\023';
1551 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1553 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1554 anything, and leaving it in breaks the meta key. Go figure. */
1555 tty
.lmode
&= ~LLITOUT
;
1562 #endif /* HAVE_TCHARS */
1563 #endif /* not HAVE_TERMIO */
1566 tty
.ltchars
= new_ltchars
;
1567 #endif /* HAVE_LTCHARS */
1568 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1570 internal_terminal_init ();
1574 EMACS_SET_TTY (input_fd
, &tty
, 0);
1576 /* This code added to insure that, if flow-control is not to be used,
1577 we have an unlocked terminal at the start. */
1580 if (!flow_control
) ioctl (input_fd
, TCXONC
, 1);
1584 if (!flow_control
) ioctl (input_fd
, TIOCSTART
, 0);
1588 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1590 if (!flow_control
) tcflow (input_fd
, TCOON
);
1598 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1599 to be only LF. This is the way that is done. */
1602 if (ioctl (1, HFTGETID
, &tty
) != -1)
1603 write (1, "\033[20l", 5);
1609 /* Appears to do nothing when in PASTHRU mode.
1610 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1611 interrupt_signal, oob_chars, 0, 0, 0, 0);
1613 queue_kbd_input (0);
1618 #ifndef F_SETOWN_BUG
1619 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1621 && ! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1623 old_fcntl_owner
= fcntl (input_fd
, F_GETOWN
, 0);
1624 fcntl (input_fd
, F_SETOWN
, getpid ());
1625 init_sigio (input_fd
);
1627 #endif /* F_GETOWN */
1628 #endif /* F_SETOWN_BUG */
1629 #endif /* F_SETFL */
1632 if (interrupt_input
)
1633 init_sigio (input_fd
);
1636 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1640 /* This symbol is defined on recent USG systems.
1641 Someone says without this call USG won't really buffer the file
1642 even with a call to setbuf. */
1643 setvbuf (stdout
, (char *) _sobuf
, _IOFBF
, sizeof _sobuf
);
1645 setbuf (stdout
, (char *) _sobuf
);
1647 #ifdef HAVE_WINDOW_SYSTEM
1648 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1649 needs the initialization code below. */
1650 if (EQ (Vwindow_system
, Qnil
)
1652 /* When running in tty mode on NT/Win95, we have a read_socket
1653 hook, but still need the rest of the initialization code below. */
1654 && (! read_socket_hook
)
1658 set_terminal_modes ();
1661 && FRAMEP (Vterminal_frame
)
1662 && FRAME_TERMCAP_P (XFRAME (Vterminal_frame
)))
1663 init_frame_faces (XFRAME (Vterminal_frame
));
1665 if (term_initted
&& no_redraw_on_reenter
)
1667 if (display_completed
)
1668 direct_output_forward_char (0);
1673 if (FRAMEP (Vterminal_frame
))
1674 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1680 /* Return nonzero if safe to use tabs in output.
1681 At the time this is called, init_sys_modes has not been done yet. */
1686 struct emacs_tty tty
;
1688 EMACS_GET_TTY (input_fd
, &tty
);
1689 return EMACS_TTY_TABS_OK (&tty
);
1692 /* Get terminal size from system.
1693 Store number of lines into *HEIGHTP and width into *WIDTHP.
1694 We store 0 if there's no valid information. */
1697 get_frame_size (widthp
, heightp
)
1698 int *widthp
, *heightp
;
1704 struct winsize size
;
1706 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1707 *widthp
= *heightp
= 0;
1710 *widthp
= size
.ws_col
;
1711 *heightp
= size
.ws_row
;
1717 /* SunOS - style. */
1718 struct ttysize size
;
1720 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1721 *widthp
= *heightp
= 0;
1724 *widthp
= size
.ts_cols
;
1725 *heightp
= size
.ts_lines
;
1731 struct sensemode tty
;
1733 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1734 &tty
.class, 12, 0, 0, 0, 0);
1735 *widthp
= tty
.scr_wid
;
1736 *heightp
= tty
.scr_len
;
1740 *widthp
= ScreenCols ();
1741 *heightp
= ScreenRows ();
1742 #else /* system doesn't know size */
1747 #endif /* not VMS */
1748 #endif /* not SunOS-style */
1749 #endif /* not BSD-style */
1752 /* Set the logical window size associated with descriptor FD
1753 to HEIGHT and WIDTH. This is used mainly with ptys. */
1756 set_window_size (fd
, height
, width
)
1757 int fd
, height
, width
;
1762 struct winsize size
;
1763 size
.ws_row
= height
;
1764 size
.ws_col
= width
;
1766 if (ioctl (fd
, TIOCSWINSZ
, &size
) == -1)
1767 return 0; /* error */
1774 /* SunOS - style. */
1775 struct ttysize size
;
1776 size
.ts_lines
= height
;
1777 size
.ts_cols
= width
;
1779 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1785 #endif /* not SunOS-style */
1786 #endif /* not BSD-style */
1790 /* Prepare the terminal for exiting Emacs; move the cursor to the
1791 bottom of the frame, turn off interrupt-driven I/O, etc. */
1804 #ifdef HAVE_WINDOW_SYSTEM
1805 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1806 needs the clean-up code below. */
1807 if (!EQ (Vwindow_system
, Qnil
)
1809 /* When running in tty mode on NT/Win95, we have a read_socket
1810 hook, but still need the rest of the clean-up code below. */
1816 sf
= SELECTED_FRAME ();
1817 cursor_to (FRAME_HEIGHT (sf
) - 1, 0);
1818 clear_end_of_line (FRAME_WIDTH (sf
));
1819 /* clear_end_of_line may move the cursor */
1820 cursor_to (FRAME_HEIGHT (sf
) - 1, 0);
1821 #if defined (IBMR2AIX) && defined (AIXHFT)
1823 /* HFT devices normally use ^J as a LF/CR. We forced it to
1824 do the LF only. Now, we need to reset it. */
1827 if (ioctl (1, HFTGETID
, &tty
) != -1)
1828 write (1, "\033[20h", 5);
1832 reset_terminal_modes ();
1836 /* Avoid possible loss of output when changing terminal modes. */
1837 fsync (fileno (stdout
));
1842 #ifndef F_SETOWN_BUG
1843 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1844 if (interrupt_input
)
1847 fcntl (input_fd
, F_SETOWN
, old_fcntl_owner
);
1849 #endif /* F_SETOWN */
1850 #endif /* F_SETOWN_BUG */
1852 fcntl (input_fd
, F_SETFL
, fcntl (input_fd
, F_GETFL
, 0) & ~O_NDELAY
);
1854 #endif /* F_SETFL */
1856 if (interrupt_input
)
1861 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1864 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1868 #ifdef SET_LINE_DISCIPLINE
1869 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1870 A different old line discipline is therefore not restored, yet.
1871 Restore the old line discipline by hand. */
1872 ioctl (0, TIOCSETD
, &old_tty
.main
.c_line
);
1880 widen_foreground_group ();
1886 /* Set up the proper status flags for use of a pty. */
1892 /* I'm told that TOICREMOTE does not mean control chars
1893 "can't be sent" but rather that they don't have
1894 input-editing or signaling effects.
1895 That should be good, because we have other ways
1896 to do those things in Emacs.
1897 However, telnet mode seems not to work on 4.2.
1898 So TIOCREMOTE is turned off now. */
1900 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1901 will hang. In particular, the "timeout" feature (which
1902 causes a read to return if there is no data available)
1903 does this. Also it is known that telnet mode will hang
1904 in such a way that Emacs must be stopped (perhaps this
1905 is the same problem).
1907 If TIOCREMOTE is turned off, then there is a bug in
1908 hp-ux which sometimes loses data. Apparently the
1909 code which blocks the master process when the internal
1910 buffer fills up does not work. Other than this,
1911 though, everything else seems to work fine.
1913 Since the latter lossage is more benign, we may as well
1914 lose that way. -- cph */
1916 #if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
1919 ioctl (fd
, FIONBIO
, &on
);
1924 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1925 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1926 /* cause EMACS not to die when it should, i.e., when its own controlling */
1927 /* tty goes away. I've complained to the AIX developers, and they may */
1928 /* change this behavior, but I'm not going to hold my breath. */
1929 signal (SIGHUP
, SIG_IGN
);
1932 #endif /* HAVE_PTYS */
1936 /* Assigning an input channel is done at the start of Emacs execution.
1937 This is called each time Emacs is resumed, also, but does nothing
1938 because input_chain is no longer zero. */
1947 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1953 /* Deassigning the input channel is done before exiting. */
1958 return SYS$
DASSGN (input_fd
);
1963 /* Request reading one character into the keyboard buffer.
1964 This is done as soon as the buffer becomes empty. */
1970 extern kbd_input_ast ();
1972 waiting_for_ast
= 0;
1974 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1975 &input_iosb
, kbd_input_ast
, 1,
1976 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1981 /* Ast routine that is called when keyboard input comes in
1982 in accord with the SYS$QIO above. */
1987 register int c
= -1;
1988 int old_errno
= errno
;
1989 extern EMACS_TIME
*input_available_clear_time
;
1991 if (waiting_for_ast
)
1992 SYS$
SETEF (input_ef
);
1993 waiting_for_ast
= 0;
1996 if (input_count
== 25)
1998 printf ("Ast # %d,", input_count
);
1999 printf (" iosb = %x, %x, %x, %x",
2000 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
2003 if (input_iosb
.offset
)
2007 printf (", char = 0%o", c
);
2019 struct input_event e
;
2020 e
.kind
= ASCII_KEYSTROKE_EVENT
;
2021 XSETINT (e
.code
, c
);
2022 e
.frame_or_window
= selected_frame
;
2023 kbd_buffer_store_event (&e
);
2025 if (input_available_clear_time
)
2026 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
2030 /* Wait until there is something in kbd_buffer. */
2033 wait_for_kbd_input ()
2035 extern int have_process_input
, process_exited
;
2037 /* If already something, avoid doing system calls. */
2038 if (detect_input_pending ())
2042 /* Clear a flag, and tell ast routine above to set it. */
2043 SYS$
CLREF (input_ef
);
2044 waiting_for_ast
= 1;
2045 /* Check for timing error: ast happened while we were doing that. */
2046 if (!detect_input_pending ())
2048 /* No timing error: wait for flag to be set. */
2049 set_waiting_for_input (0);
2050 SYS$
WFLOR (input_ef
, input_eflist
);
2051 clear_waiting_for_input ();
2052 if (!detect_input_pending ())
2053 /* Check for subprocess input availability */
2055 int dsp
= have_process_input
|| process_exited
;
2057 SYS$
CLREF (process_ef
);
2058 if (have_process_input
)
2059 process_command_input ();
2064 update_mode_lines
++;
2065 prepare_menu_bars ();
2066 redisplay_preserve_echo_area (18);
2070 waiting_for_ast
= 0;
2073 /* Get rid of any pending QIO, when we are about to suspend
2074 or when we want to throw away pending input.
2075 We wait for a positive sign that the AST routine has run
2076 and therefore there is no I/O request queued when we return.
2077 SYS$SETAST is used to avoid a timing error. */
2083 printf ("At end_kbd_input.\n");
2087 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2089 SYS$
CANCEL (input_fd
);
2094 /* Clear a flag, and tell ast routine above to set it. */
2095 SYS$
CLREF (input_ef
);
2096 waiting_for_ast
= 1;
2098 SYS$
CANCEL (input_fd
);
2100 SYS$
WAITFR (input_ef
);
2101 waiting_for_ast
= 0;
2104 /* Wait for either input available or time interval expiry. */
2107 input_wait_timeout (timeval
)
2108 int timeval
; /* Time to wait, in seconds */
2111 static int zero
= 0;
2112 static int large
= -10000000;
2114 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2116 /* If already something, avoid doing system calls. */
2117 if (detect_input_pending ())
2121 /* Clear a flag, and tell ast routine above to set it. */
2122 SYS$
CLREF (input_ef
);
2123 waiting_for_ast
= 1;
2124 /* Check for timing error: ast happened while we were doing that. */
2125 if (!detect_input_pending ())
2127 /* No timing error: wait for flag to be set. */
2129 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2130 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
2132 waiting_for_ast
= 0;
2135 /* The standard `sleep' routine works some other way
2136 and it stops working if you have ever quit out of it.
2137 This one continues to work. */
2143 static int zero
= 0;
2144 static int large
= -10000000;
2146 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2149 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2150 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
2168 croak ("request sigio");
2174 croak ("unrequest sigio");
2179 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2184 #ifndef SYSTEM_MALLOC
2191 /* Some systems that cannot dump also cannot implement these. */
2194 * Return the address of the start of the text segment prior to
2195 * doing an unexec. After unexec the return value is undefined.
2196 * See crt0.c for further explanation and _start.
2200 #if !(defined (__NetBSD__) && defined (__ELF__))
2201 #ifndef HAVE_TEXT_START
2206 return ((char *) TEXT_START
);
2210 return ((char *) csrt
);
2211 #else /* not GOULD */
2212 extern int _start ();
2213 return ((char *) _start
);
2215 #endif /* TEXT_START */
2217 #endif /* not HAVE_TEXT_START */
2221 * Return the address of the start of the data segment prior to
2222 * doing an unexec. After unexec the return value is undefined.
2223 * See crt0.c for further information and definition of data_start.
2225 * Apparently, on BSD systems this is etext at startup. On
2226 * USG systems (swapping) this is highly mmu dependent and
2227 * is also dependent on whether or not the program is running
2228 * with shared text. Generally there is a (possibly large)
2229 * gap between end of text and start of data with shared text.
2231 * On Uniplus+ systems with shared text, data starts at a
2232 * fixed address. Each port (from a given oem) is generally
2233 * different, and the specific value of the start of data can
2234 * be obtained via the UniPlus+ specific "uvar" system call,
2235 * however the method outlined in crt0.c seems to be more portable.
2237 * Probably what will have to happen when a USG unexec is available,
2238 * at least on UniPlus, is temacs will have to be made unshared so
2239 * that text and data are contiguous. Then once loadup is complete,
2240 * unexec will produce a shared executable where the data can be
2241 * at the normal shared text boundary and the startofdata variable
2242 * will be patched by unexec to the correct value.
2246 #ifndef start_of_data
2251 return ((char *) DATA_START
);
2253 #ifdef ORDINARY_LINK
2255 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2256 * data_start isn't defined. We take the address of environ, which
2257 * is known to live at or near the start of the system crt0.c, and
2258 * we don't sweat the handful of bytes that might lose.
2260 extern char **environ
;
2262 return ((char *) &environ
);
2264 extern int data_start
;
2265 return ((char *) &data_start
);
2266 #endif /* ORDINARY_LINK */
2267 #endif /* DATA_START */
2269 #endif /* start_of_data */
2270 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2272 /* init_system_name sets up the string for the Lisp function
2273 system-name to return. */
2279 extern Lisp_Object Vsystem_name
;
2284 #include <sys/socket.h>
2286 #endif /* HAVE_SOCKETS */
2287 #endif /* not VMS */
2288 #endif /* not BSD4_1 */
2291 #ifndef HAVE_H_ERRNO
2294 #endif /* TRY_AGAIN */
2300 Vsystem_name
= build_string (sysname
);
2304 if ((sp
= egetenv ("SYS$NODE")) == 0)
2305 Vsystem_name
= build_string ("vax-vms");
2306 else if ((end
= index (sp
, ':')) == 0)
2307 Vsystem_name
= build_string (sp
);
2309 Vsystem_name
= make_string (sp
, end
- sp
);
2311 #ifndef HAVE_GETHOSTNAME
2314 Vsystem_name
= build_string (uts
.nodename
);
2315 #else /* HAVE_GETHOSTNAME */
2316 unsigned int hostname_size
= 256;
2317 char *hostname
= (char *) alloca (hostname_size
);
2319 /* Try to get the host name; if the buffer is too short, try
2320 again. Apparently, the only indication gethostname gives of
2321 whether the buffer was large enough is the presence or absence
2322 of a '\0' in the string. Eech. */
2325 gethostname (hostname
, hostname_size
- 1);
2326 hostname
[hostname_size
- 1] = '\0';
2328 /* Was the buffer large enough for the '\0'? */
2329 if (strlen (hostname
) < hostname_size
- 1)
2332 hostname_size
<<= 1;
2333 hostname
= (char *) alloca (hostname_size
);
2336 /* Turn the hostname into the official, fully-qualified hostname.
2337 Don't do this if we're going to dump; this can confuse system
2338 libraries on some machines and make the dumped emacs core dump. */
2341 #endif /* not CANNOT_DUMP */
2342 if (! index (hostname
, '.'))
2346 for (count
= 0;; count
++)
2351 hp
= gethostbyname (hostname
);
2353 if (! (hp
== 0 && h_errno
== TRY_AGAIN
))
2358 Fsleep_for (make_number (1), Qnil
);
2362 char *fqdn
= (char *) hp
->h_name
;
2367 if (!index (fqdn
, '.'))
2369 /* We still don't have a fully qualified domain name.
2370 Try to find one in the list of alternate names */
2371 char **alias
= hp
->h_aliases
;
2372 while (*alias
&& !index (*alias
, '.'))
2379 /* Convert the host name to lower case. */
2380 /* Using ctype.h here would introduce a possible locale
2381 dependence that is probably wrong for hostnames. */
2385 if (*p
>= 'A' && *p
<= 'Z')
2392 #endif /* HAVE_SOCKETS */
2393 /* We used to try using getdomainname here,
2394 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2395 getdomainname gets the NIS/YP domain which often is not the same
2396 as in Internet domain name. */
2397 #if 0 /* Turned off because sysinfo is not really likely to return the
2398 correct Internet domain. */
2399 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2400 if (! index (hostname
, '.'))
2402 /* The hostname is not fully qualified. Append the domain name. */
2404 int hostlen
= strlen (hostname
);
2405 int domain_size
= 256;
2409 char *domain
= (char *) alloca (domain_size
+ 1);
2410 char *fqdn
= (char *) alloca (hostlen
+ 1 + domain_size
+ 1);
2411 int sys_domain_size
= sysinfo (SI_SRPC_DOMAIN
, domain
, domain_size
);
2412 if (sys_domain_size
<= 0)
2414 if (domain_size
< sys_domain_size
)
2416 domain_size
= sys_domain_size
;
2419 strcpy (fqdn
, hostname
);
2420 if (domain
[0] == '.')
2421 strcpy (fqdn
+ hostlen
, domain
);
2422 else if (domain
[0] != 0)
2424 fqdn
[hostlen
] = '.';
2425 strcpy (fqdn
+ hostlen
+ 1, domain
);
2431 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2433 Vsystem_name
= build_string (hostname
);
2434 #endif /* HAVE_GETHOSTNAME */
2439 for (p
= SDATA (Vsystem_name
); *p
; p
++)
2440 if (*p
== ' ' || *p
== '\t')
2447 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2449 #include "sysselect.h"
2452 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2453 /* Cause explanatory error message at compile time,
2454 since the select emulation is not good enough for X. */
2455 int *x
= &x_windows_lose_if_no_select_system_call
;
2458 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2459 * Only checks read descriptors.
2461 /* How long to wait between checking fds in select */
2462 #define SELECT_PAUSE 1
2465 /* For longjmp'ing back to read_input_waiting. */
2467 jmp_buf read_alarm_throw
;
2469 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2470 The read_socket_hook function sets this to 1 while it is waiting. */
2472 int read_alarm_should_throw
;
2480 #else /* not BSD4_1 */
2481 signal (SIGALRM
, SIG_IGN
);
2482 #endif /* not BSD4_1 */
2483 if (read_alarm_should_throw
)
2484 longjmp (read_alarm_throw
, 1);
2488 /* Only rfds are checked. */
2490 sys_select (nfds
, rfds
, wfds
, efds
, timeout
)
2492 SELECT_TYPE
*rfds
, *wfds
, *efds
;
2493 EMACS_TIME
*timeout
;
2499 extern int proc_buffered_char
[];
2500 #ifndef subprocesses
2501 int process_tick
= 0, update_tick
= 0;
2503 extern int process_tick
, update_tick
;
2507 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2508 /* If we're using X, then the native select will work; we only need the
2509 emulation for non-X usage. */
2510 if (!NILP (Vwindow_system
))
2511 return select (nfds
, rfds
, wfds
, efds
, timeout
);
2513 timeoutval
= timeout
? EMACS_SECS (*timeout
) : 100000;
2514 local_timeout
= &timeoutval
;
2526 /* If we are looking only for the terminal, with no timeout,
2527 just read it and wait -- that's more efficient. */
2528 if (*local_timeout
== 100000 && process_tick
== update_tick
2529 && FD_ISSET (0, &orfds
))
2532 for (fd
= 1; fd
< nfds
; ++fd
)
2533 if (FD_ISSET (fd
, &orfds
))
2535 if (! detect_input_pending ())
2536 read_input_waiting ();
2542 /* Once a second, till the timer expires, check all the flagged read
2543 * descriptors to see if any input is available. If there is some then
2544 * set the corresponding bit in the return copy of rfds.
2548 register int to_check
, fd
;
2552 for (to_check
= nfds
, fd
= 0; --to_check
>= 0; fd
++)
2554 if (FD_ISSET (fd
, &orfds
))
2556 int avail
= 0, status
= 0;
2559 avail
= detect_input_pending (); /* Special keyboard handler */
2563 status
= ioctl (fd
, FIONREAD
, &avail
);
2564 #else /* no FIONREAD */
2565 /* Hoping it will return -1 if nothing available
2566 or 0 if all 0 chars requested are read. */
2567 if (proc_buffered_char
[fd
] >= 0)
2571 avail
= read (fd
, &buf
, 1);
2573 proc_buffered_char
[fd
] = buf
;
2575 #endif /* no FIONREAD */
2577 if (status
>= 0 && avail
> 0)
2585 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2588 turn_on_atimers (0);
2589 signal (SIGALRM
, select_alarm
);
2591 alarm (SELECT_PAUSE
);
2593 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2594 while (select_alarmed
== 0 && *local_timeout
!= 0
2595 && process_tick
== update_tick
)
2597 /* If we are interested in terminal input,
2598 wait by reading the terminal.
2599 That makes instant wakeup for terminal input at least. */
2600 if (FD_ISSET (0, &orfds
))
2602 read_input_waiting ();
2603 if (detect_input_pending ())
2609 (*local_timeout
) -= SELECT_PAUSE
;
2611 /* Reset the old alarm if there was one. */
2612 turn_on_atimers (1);
2614 if (*local_timeout
== 0) /* Stop on timer being cleared */
2619 #endif /* not WINDOWSNT */
2621 /* Read keyboard input into the standard buffer,
2622 waiting for at least one character. */
2624 /* Make all keyboard buffers much bigger when using a window system. */
2625 #ifdef HAVE_WINDOW_SYSTEM
2626 #define BUFFER_SIZE_FACTOR 16
2628 #define BUFFER_SIZE_FACTOR 1
2632 read_input_waiting ()
2634 struct input_event e
;
2636 extern int quit_char
;
2638 if (read_socket_hook
)
2640 struct input_event buf
[256];
2642 read_alarm_should_throw
= 0;
2643 if (! setjmp (read_alarm_throw
))
2644 nread
= (*read_socket_hook
) (0, buf
, 256, 1);
2648 /* Scan the chars for C-g and store them in kbd_buffer. */
2649 for (i
= 0; i
< nread
; i
++)
2651 kbd_buffer_store_event (&buf
[i
]);
2652 /* Don't look at input that follows a C-g too closely.
2653 This reduces lossage due to autorepeat on C-g. */
2654 if (buf
[i
].kind
== ASCII_KEYSTROKE_EVENT
2655 && buf
[i
].code
== quit_char
)
2662 nread
= read (fileno (stdin
), buf
, 1);
2664 /* Scan the chars for C-g and store them in kbd_buffer. */
2665 e
.kind
= ASCII_KEYSTROKE_EVENT
;
2666 e
.frame_or_window
= selected_frame
;
2668 for (i
= 0; i
< nread
; i
++)
2670 /* Convert chars > 0177 to meta events if desired.
2671 We do this under the same conditions that read_avail_input does. */
2672 if (read_socket_hook
== 0)
2674 /* If the user says she has a meta key, then believe her. */
2675 if (meta_key
== 1 && (buf
[i
] & 0x80))
2676 e
.modifiers
= meta_modifier
;
2681 XSETINT (e
.code
, buf
[i
]);
2682 kbd_buffer_store_event (&e
);
2683 /* Don't look at input that follows a C-g too closely.
2684 This reduces lossage due to autorepeat on C-g. */
2685 if (buf
[i
] == quit_char
)
2691 #endif /* not HAVE_SELECT */
2692 #endif /* not VMS */
2693 #endif /* not MSDOS */
2702 lmode
= LINTRUP
| lmode
;
2703 ioctl (fd
, TIOCLSET
, &lmode
);
2711 lmode
= ~LINTRUP
& lmode
;
2712 ioctl (0, TIOCLSET
, &lmode
);
2720 interrupts_deferred
= 0;
2728 interrupts_deferred
= 1;
2731 /* still inside #ifdef BSD4_1 */
2734 int sigheld
; /* Mask of held signals */
2740 sigheld
|= sigbit (signum
);
2748 sigheld
|= sigbit (signum
);
2755 sigheld
&= ~sigbit (signum
);
2760 sigfree () /* Free all held signals */
2763 for (i
= 0; i
< NSIG
; i
++)
2764 if (sigheld
& sigbit (i
))
2772 return 1 << (i
- 1);
2774 #endif /* subprocesses */
2777 /* POSIX signals support - DJB */
2778 /* Anyone with POSIX signals should have ANSI C declarations */
2780 #ifdef POSIX_SIGNALS
2782 sigset_t empty_mask
, full_mask
;
2785 sys_signal (int signal_number
, signal_handler_t action
)
2787 struct sigaction new_action
, old_action
;
2788 sigemptyset (&new_action
.sa_mask
);
2789 new_action
.sa_handler
= action
;
2790 #if defined (SA_RESTART) && ! defined (BROKEN_SA_RESTART)
2791 /* Emacs mostly works better with restartable system services. If this
2792 flag exists, we probably want to turn it on here.
2793 However, on some systems this resets the timeout of `select'
2794 which means that `select' never finishes if it keeps getting signals.
2795 BROKEN_SA_RESTART is defined on those systems. */
2796 new_action
.sa_flags
= SA_RESTART
;
2798 new_action
.sa_flags
= 0;
2800 sigaction (signal_number
, &new_action
, &old_action
);
2801 return (old_action
.sa_handler
);
2805 /* If we're compiling with GCC, we don't need this function, since it
2806 can be written as a macro. */
2808 sys_sigmask (int sig
)
2811 sigemptyset (&mask
);
2812 sigaddset (&mask
, sig
);
2817 /* I'd like to have these guys return pointers to the mask storage in here,
2818 but there'd be trouble if the code was saving multiple masks. I'll be
2819 safe and pass the structure. It normally won't be more than 2 bytes
2823 sys_sigblock (sigset_t new_mask
)
2826 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2831 sys_sigunblock (sigset_t new_mask
)
2834 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2839 sys_sigsetmask (sigset_t new_mask
)
2842 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2846 #endif /* POSIX_SIGNALS */
2848 #if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
2849 static char *my_sys_siglist
[NSIG
];
2853 # define sys_siglist my_sys_siglist
2859 #ifdef POSIX_SIGNALS
2860 sigemptyset (&empty_mask
);
2861 sigfillset (&full_mask
);
2864 #if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
2868 sys_siglist
[SIGABRT
] = "Aborted";
2871 sys_siglist
[SIGAIO
] = "LAN I/O interrupt";
2874 sys_siglist
[SIGALRM
] = "Alarm clock";
2877 sys_siglist
[SIGBUS
] = "Bus error";
2880 sys_siglist
[SIGCLD
] = "Child status changed";
2883 sys_siglist
[SIGCHLD
] = "Child status changed";
2886 sys_siglist
[SIGCONT
] = "Continued";
2889 sys_siglist
[SIGDANGER
] = "Swap space dangerously low";
2892 sys_siglist
[SIGDGNOTIFY
] = "Notification message in queue";
2895 sys_siglist
[SIGEMT
] = "Emulation trap";
2898 sys_siglist
[SIGFPE
] = "Arithmetic exception";
2901 sys_siglist
[SIGFREEZE
] = "SIGFREEZE";
2904 sys_siglist
[SIGGRANT
] = "Monitor mode granted";
2907 sys_siglist
[SIGHUP
] = "Hangup";
2910 sys_siglist
[SIGILL
] = "Illegal instruction";
2913 sys_siglist
[SIGINT
] = "Interrupt";
2916 sys_siglist
[SIGIO
] = "I/O possible";
2919 sys_siglist
[SIGIOINT
] = "I/O intervention required";
2922 sys_siglist
[SIGIOT
] = "IOT trap";
2925 sys_siglist
[SIGKILL
] = "Killed";
2928 sys_siglist
[SIGLOST
] = "Resource lost";
2931 sys_siglist
[SIGLWP
] = "SIGLWP";
2934 sys_siglist
[SIGMSG
] = "Monitor mode data available";
2937 sys_siglist
[SIGWIND
] = "SIGPHONE";
2940 sys_siglist
[SIGPIPE
] = "Broken pipe";
2943 sys_siglist
[SIGPOLL
] = "Pollable event occurred";
2946 sys_siglist
[SIGPROF
] = "Profiling timer expired";
2949 sys_siglist
[SIGPTY
] = "PTY I/O interrupt";
2952 sys_siglist
[SIGPWR
] = "Power-fail restart";
2955 sys_siglist
[SIGQUIT
] = "Quit";
2958 sys_siglist
[SIGRETRACT
] = "Need to relinguish monitor mode";
2961 sys_siglist
[SIGSAK
] = "Secure attention";
2964 sys_siglist
[SIGSEGV
] = "Segmentation violation";
2967 sys_siglist
[SIGSOUND
] = "Sound completed";
2970 sys_siglist
[SIGSTOP
] = "Stopped (signal)";
2973 sys_siglist
[SIGSTP
] = "Stopped (user)";
2976 sys_siglist
[SIGSYS
] = "Bad argument to system call";
2979 sys_siglist
[SIGTERM
] = "Terminated";
2982 sys_siglist
[SIGTHAW
] = "SIGTHAW";
2985 sys_siglist
[SIGTRAP
] = "Trace/breakpoint trap";
2988 sys_siglist
[SIGTSTP
] = "Stopped (user)";
2991 sys_siglist
[SIGTTIN
] = "Stopped (tty input)";
2994 sys_siglist
[SIGTTOU
] = "Stopped (tty output)";
2997 sys_siglist
[SIGURG
] = "Urgent I/O condition";
3000 sys_siglist
[SIGUSR1
] = "User defined signal 1";
3003 sys_siglist
[SIGUSR2
] = "User defined signal 2";
3006 sys_siglist
[SIGVTALRM
] = "Virtual timer expired";
3009 sys_siglist
[SIGWAITING
] = "Process's LWPs are blocked";
3012 sys_siglist
[SIGWINCH
] = "Window size changed";
3015 sys_siglist
[SIGWIND
] = "SIGWIND";
3018 sys_siglist
[SIGXCPU
] = "CPU time limit exceeded";
3021 sys_siglist
[SIGXFSZ
] = "File size limit exceeded";
3024 #endif /* !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED */
3033 /* Figure out how many bits the system's random number generator uses.
3034 `random' and `lrand48' are assumed to return 31 usable bits.
3035 BSD `rand' returns a 31 bit value but the low order bits are unusable;
3036 so we'll shift it and treat it like the 15-bit USG `rand'. */
3040 # define RAND_BITS 31
3041 # else /* !HAVE_RANDOM */
3042 # ifdef HAVE_LRAND48
3043 # define RAND_BITS 31
3044 # define random lrand48
3045 # else /* !HAVE_LRAND48 */
3046 # define RAND_BITS 15
3047 # if RAND_MAX == 32767
3048 # define random rand
3049 # else /* RAND_MAX != 32767 */
3050 # if RAND_MAX == 2147483647
3051 # define random() (rand () >> 16)
3052 # else /* RAND_MAX != 2147483647 */
3054 # define random rand
3056 # define random() (rand () >> 16)
3058 # endif /* RAND_MAX != 2147483647 */
3059 # endif /* RAND_MAX != 32767 */
3060 # endif /* !HAVE_LRAND48 */
3061 # endif /* !HAVE_RANDOM */
3062 #endif /* !RAND_BITS */
3069 srandom ((unsigned int)arg
);
3071 # ifdef HAVE_LRAND48
3074 srand ((unsigned int)arg
);
3080 * Build a full Emacs-sized word out of whatever we've got.
3081 * This suffices even for a 64-bit architecture with a 15-bit rand.
3086 long val
= random ();
3087 #if VALBITS > RAND_BITS
3088 val
= (val
<< RAND_BITS
) ^ random ();
3089 #if VALBITS > 2*RAND_BITS
3090 val
= (val
<< RAND_BITS
) ^ random ();
3091 #if VALBITS > 3*RAND_BITS
3092 val
= (val
<< RAND_BITS
) ^ random ();
3093 #if VALBITS > 4*RAND_BITS
3094 val
= (val
<< RAND_BITS
) ^ random ();
3095 #endif /* need at least 5 */
3096 #endif /* need at least 4 */
3097 #endif /* need at least 3 */
3098 #endif /* need at least 2 */
3099 return val
& ((1L << VALBITS
) - 1);
3102 #ifdef WRONG_NAME_INSQUE
3115 /* If any place else asks for the TERM variable,
3116 allow it to be overridden with the EMACS_TERM variable
3117 before attempting to translate the logical name TERM. As a last
3118 resort, ask for VAX C's special idea of the TERM variable. */
3125 static char buf
[256];
3126 static struct dsc$descriptor_s equiv
3127 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
3128 static struct dsc$descriptor_s d_name
3129 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
3132 if (!strcmp (name
, "TERM"))
3134 val
= (char *) getenv ("EMACS_TERM");
3139 d_name
.dsc$w_length
= strlen (name
);
3140 d_name
.dsc$a_pointer
= name
;
3141 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
3143 char *str
= (char *) xmalloc (eqlen
+ 1);
3144 bcopy (buf
, str
, eqlen
);
3146 /* This is a storage leak, but a pain to fix. With luck,
3147 no one will ever notice. */
3150 return (char *) getenv (name
);
3155 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
3156 to force a call on the debugger from within the image. */
3161 LIB$
SIGNAL (SS$_DEBUG
);
3167 #ifdef LINK_CRTL_SHARE
3168 #ifdef SHARABLE_LIB_BUG
3169 /* Variables declared noshare and initialized in sharable libraries
3170 cannot be shared. The VMS linker incorrectly forces you to use a private
3171 version which is uninitialized... If not for this "feature", we
3172 could use the C library definition of sys_nerr and sys_errlist. */
3174 char *sys_errlist
[] =
3178 "no such file or directory",
3180 "interrupted system call",
3182 "no such device or address",
3183 "argument list too long",
3184 "exec format error",
3187 "no more processes",
3188 "not enough memory",
3189 "permission denied",
3191 "block device required",
3192 "mount devices busy",
3194 "cross-device link",
3199 "file table overflow",
3200 "too many open files",
3204 "no space left on device",
3206 "read-only file system",
3212 "vax/vms specific error code nontranslatable error"
3214 #endif /* SHARABLE_LIB_BUG */
3215 #endif /* LINK_CRTL_SHARE */
3218 #ifndef HAVE_STRERROR
3224 extern char *sys_errlist
[];
3225 extern int sys_nerr
;
3227 if (errnum
>= 0 && errnum
< sys_nerr
)
3228 return sys_errlist
[errnum
];
3229 return (char *) "Unknown error";
3231 #endif /* not WINDOWSNT */
3232 #endif /* ! HAVE_STRERROR */
3235 emacs_open (path
, oflag
, mode
)
3239 register int rtnval
;
3242 if (oflag
& O_CREAT
)
3243 return creat (path
, mode
);
3246 while ((rtnval
= open (path
, oflag
, mode
)) == -1
3247 && (errno
== EINTR
));
3256 register int rtnval
;
3258 while ((rtnval
= close (fd
)) == -1
3259 && (errno
== EINTR
))
3262 /* If close is interrupted SunOS 4.1 may or may not have closed the
3263 file descriptor. If it did the second close will fail with
3264 errno = EBADF. That means we have succeeded. */
3265 if (rtnval
== -1 && did_retry
&& errno
== EBADF
)
3272 emacs_read (fildes
, buf
, nbyte
)
3277 register int rtnval
;
3279 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
3280 && (errno
== EINTR
));
3285 emacs_write (fildes
, buf
, nbyte
)
3290 register int rtnval
, bytes_written
;
3296 rtnval
= write (fildes
, buf
, nbyte
);
3303 return (bytes_written
? bytes_written
: -1);
3308 bytes_written
+= rtnval
;
3310 return (bytes_written
);
3315 * All of the following are for USG.
3317 * On USG systems the system calls are INTERRUPTIBLE by signals
3318 * that the user program has elected to catch. Thus the system call
3319 * must be retried in these cases. To handle this without massive
3320 * changes in the source code, we remap the standard system call names
3321 * to names for our own functions in sysdep.c that do the system call
3322 * with retries. Actually, for portability reasons, it is good
3323 * programming practice, as this example shows, to limit all actual
3324 * system calls to a single occurrence in the source. Sure, this
3325 * adds an extra level of function call overhead but it is almost
3326 * always negligible. Fred Fish, Unisoft Systems Inc.
3330 * Warning, this function may not duplicate 4.2 action properly
3331 * under error conditions.
3335 /* In 4.1, param.h fails to define this. */
3336 #define MAXPATHLEN 1024
3345 char *npath
, *spath
;
3346 extern char *getcwd ();
3348 BLOCK_INPUT
; /* getcwd uses malloc */
3349 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
3355 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3356 up to first slash. Should be harmless on other systems. */
3357 while (*npath
&& *npath
!= '/')
3359 strcpy (pathname
, npath
);
3360 free (spath
); /* getcwd uses malloc */
3365 #endif /* HAVE_GETWD */
3368 * Emulate rename using unlink/link. Note that this is
3369 * only partially correct. Also, doesn't enforce restriction
3370 * that files be of same type (regular->regular, dir->dir, etc).
3379 if (access (from
, 0) == 0)
3382 if (link (from
, to
) == 0)
3383 if (unlink (from
) == 0)
3395 /* HPUX curses library references perror, but as far as we know
3396 it won't be called. Anyway this definition will do for now. */
3402 #endif /* not HAVE_PERROR */
3408 * Emulate BSD dup2. First close newd if it already exists.
3409 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3410 * until we are, then close the unsuccessful ones.
3417 register int fd
, ret
;
3422 return fcntl (oldd
, F_DUPFD
, newd
);
3429 ret
= dup2 (old
,new);
3435 #endif /* not HAVE_DUP2 */
3438 * Gettimeofday. Simulate as much as possible. Only accurate
3439 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3440 * Only needed when subprocesses are defined.
3445 #ifndef HAVE_GETTIMEOFDAY
3450 gettimeofday (tp
, tzp
)
3452 struct timezone
*tzp
;
3454 extern long time ();
3456 tp
->tv_sec
= time ((long *)0);
3459 tzp
->tz_minuteswest
= -1;
3466 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3469 * This function will go away as soon as all the stubs fixed. (fnf)
3476 printf ("%s not yet implemented\r\n", badfunc
);
3483 /* Directory routines for systems that don't have them. */
3485 #ifdef SYSV_SYSTEM_DIR
3489 #if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
3493 register DIR *dirp
; /* stream from opendir */
3497 rtnval
= emacs_close (dirp
->dd_fd
);
3499 /* Some systems (like Solaris) allocate the buffer and the DIR all
3500 in one block. Why in the world are we freeing this ourselves
3502 #if ! (defined (sun) && defined (USG5_4))
3503 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
3505 xfree ((char *) dirp
);
3509 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3510 #endif /* SYSV_SYSTEM_DIR */
3512 #ifdef NONSYSTEM_DIR_LIBRARY
3516 char *filename
; /* name of directory */
3518 register DIR *dirp
; /* -> malloc'ed storage */
3519 register int fd
; /* file descriptor for read */
3520 struct stat sbuf
; /* result of fstat */
3522 fd
= emacs_open (filename
, O_RDONLY
, 0);
3527 if (fstat (fd
, &sbuf
) < 0
3528 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
3529 || (dirp
= (DIR *) xmalloc (sizeof (DIR))) == 0)
3533 return 0; /* bad luck today */
3538 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
3545 register DIR *dirp
; /* stream from opendir */
3547 emacs_close (dirp
->dd_fd
);
3548 xfree ((char *) dirp
);
3556 ino_t od_ino
; /* inode */
3557 char od_name
[DIRSIZ
]; /* filename */
3559 #endif /* not VMS */
3561 struct direct dir_static
; /* simulated directory contents */
3566 register DIR *dirp
; /* stream from opendir */
3569 register struct olddir
*dp
; /* -> directory data */
3571 register struct dir$_name
*dp
; /* -> directory data */
3572 register struct dir$_version
*dv
; /* -> version data */
3577 if (dirp
->dd_loc
>= dirp
->dd_size
)
3578 dirp
->dd_loc
= dirp
->dd_size
= 0;
3580 if (dirp
->dd_size
== 0 /* refill buffer */
3581 && (dirp
->dd_size
= emacs_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3585 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3586 dirp
->dd_loc
+= sizeof (struct olddir
);
3588 if (dp
->od_ino
!= 0) /* not deleted entry */
3590 dir_static
.d_ino
= dp
->od_ino
;
3591 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3592 dir_static
.d_name
[DIRSIZ
] = '\0';
3593 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3594 dir_static
.d_reclen
= sizeof (struct direct
)
3596 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3597 return &dir_static
; /* -> simulated structure */
3600 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3601 if (dirp
->dd_loc
== 0)
3602 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3603 : dp
->dir$b_namecount
;
3604 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3605 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3606 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3607 dir_static
.d_reclen
= sizeof (struct direct
)
3609 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3610 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3611 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3612 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3619 /* readdirver is just like readdir except it returns all versions of a file
3620 as separate entries. */
3625 register DIR *dirp
; /* stream from opendir */
3627 register struct dir$_name
*dp
; /* -> directory data */
3628 register struct dir$_version
*dv
; /* -> version data */
3630 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3631 dirp
->dd_loc
= dirp
->dd_size
= 0;
3633 if (dirp
->dd_size
== 0 /* refill buffer */
3634 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3637 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3638 if (dirp
->dd_loc
== 0)
3639 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3640 : dp
->dir$b_namecount
;
3641 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3642 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3643 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3644 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3645 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3646 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3647 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3648 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3654 #endif /* NONSYSTEM_DIR_LIBRARY */
3658 set_file_times (filename
, atime
, mtime
)
3659 const char *filename
;
3660 EMACS_TIME atime
, mtime
;
3663 struct timeval tv
[2];
3666 return utimes (filename
, tv
);
3667 #else /* not HAVE_UTIMES */
3669 utb
.actime
= EMACS_SECS (atime
);
3670 utb
.modtime
= EMACS_SECS (mtime
);
3671 return utime (filename
, &utb
);
3672 #endif /* not HAVE_UTIMES */
3675 /* mkdir and rmdir functions, for systems which don't have them. */
3679 * Written by Robert Rother, Mariah Corporation, August 1985.
3681 * If you want it, it's yours. All I ask in return is that if you
3682 * figure out how to do this in a Bourne Shell script you send me
3684 * sdcsvax!rmr or rmr@uscd
3686 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3687 * subroutine. 11Mar86; hoptoad!gnu
3689 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3690 * subroutine didn't return EEXIST. It does now.
3696 #ifdef MKDIR_PROTOTYPE
3700 mkdir (dpath
, dmode
)
3705 int cpid
, status
, fd
;
3706 struct stat statbuf
;
3708 if (stat (dpath
, &statbuf
) == 0)
3710 errno
= EEXIST
; /* Stat worked, so it already exists */
3714 /* If stat fails for a reason other than non-existence, return error */
3715 if (errno
!= ENOENT
)
3718 synch_process_alive
= 1;
3719 switch (cpid
= fork ())
3722 case -1: /* Error in fork */
3723 return (-1); /* Errno is set already */
3725 case 0: /* Child process */
3727 * Cheap hack to set mode of new directory. Since this
3728 * child process is going away anyway, we zap its umask.
3729 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3730 * directory. Does anybody care?
3732 status
= umask (0); /* Get current umask */
3733 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3734 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3741 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3742 _exit (-1); /* Can't exec /bin/mkdir */
3744 default: /* Parent process */
3745 wait_for_termination (cpid
);
3748 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3750 errno
= EIO
; /* We don't know why, but */
3751 return -1; /* /bin/mkdir failed */
3756 #endif /* not HAVE_MKDIR */
3763 int cpid
, status
, fd
;
3764 struct stat statbuf
;
3766 if (stat (dpath
, &statbuf
) != 0)
3768 /* Stat just set errno. We don't have to */
3772 synch_process_alive
= 1;
3773 switch (cpid
= fork ())
3776 case -1: /* Error in fork */
3777 return (-1); /* Errno is set already */
3779 case 0: /* Child process */
3780 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3787 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
3788 _exit (-1); /* Can't exec /bin/rmdir */
3790 default: /* Parent process */
3791 wait_for_termination (cpid
);
3794 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3796 errno
= EIO
; /* We don't know why, but */
3797 return -1; /* /bin/rmdir failed */
3802 #endif /* !HAVE_RMDIR */
3806 /* Functions for VMS */
3808 #include "vms-pwd.h"
3813 /* Return as a string the VMS error string pertaining to STATUS.
3814 Reuses the same static buffer each time it is called. */
3818 int status
; /* VMS status code */
3822 static char buf
[257];
3824 bufadr
[0] = sizeof buf
- 1;
3825 bufadr
[1] = (int) buf
;
3826 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3827 return "untranslatable VMS error status";
3835 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3836 * not work correctly. (It also doesn't work well in version 2.3.)
3841 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3842 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3846 unsigned short s_buflen
;
3847 unsigned short s_code
;
3849 unsigned short *s_retlenadr
;
3853 #define buflen s.s_buflen
3854 #define code s.s_code
3855 #define bufadr s.s_bufadr
3856 #define retlenadr s.s_retlenadr
3858 #define R_OK 4 /* test for read permission */
3859 #define W_OK 2 /* test for write permission */
3860 #define X_OK 1 /* test for execute (search) permission */
3861 #define F_OK 0 /* test for presence of file */
3864 sys_access (path
, mode
)
3868 static char *user
= NULL
;
3871 /* translate possible directory spec into .DIR file name, so brain-dead
3872 * access can treat the directory like a file. */
3873 if (directory_file_name (path
, dir_fn
))
3877 return access (path
, mode
);
3878 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3884 unsigned short int dummy
;
3886 static int constant
= ACL$C_FILE
;
3887 DESCRIPTOR (path_desc
, path
);
3888 DESCRIPTOR (user_desc
, user
);
3892 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3895 acces
|= CHP$M_READ
;
3897 acces
|= CHP$M_WRITE
;
3898 itemlst
[0].buflen
= sizeof (int);
3899 itemlst
[0].code
= CHP$_FLAGS
;
3900 itemlst
[0].bufadr
= (char *) &flags
;
3901 itemlst
[0].retlenadr
= &dummy
;
3902 itemlst
[1].buflen
= sizeof (int);
3903 itemlst
[1].code
= CHP$_ACCESS
;
3904 itemlst
[1].bufadr
= (char *) &acces
;
3905 itemlst
[1].retlenadr
= &dummy
;
3906 itemlst
[2].end
= CHP$_END
;
3907 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3908 return stat
== SS$_NORMAL
? 0 : -1;
3912 #else /* not VMS4_4 */
3915 #define ACE$M_WRITE 2
3916 #define ACE$C_KEYID 1
3918 static unsigned short memid
, grpid
;
3919 static unsigned int uic
;
3921 /* Called from init_sys_modes, so it happens not very often
3922 but at least each time Emacs is loaded. */
3924 sys_access_reinit ()
3930 sys_access (filename
, type
)
3936 int status
, size
, i
, typecode
, acl_controlled
;
3937 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3938 union prvdef prvmask
;
3940 /* Get UIC and GRP values for protection checking. */
3943 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3946 memid
= uic
& 0xFFFF;
3950 if (type
!= 2) /* not checking write access */
3951 return access (filename
, type
);
3953 /* Check write protection. */
3955 #define CHECKPRIV(bit) (prvmask.bit)
3956 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3958 /* Find privilege bits */
3959 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3961 error ("Unable to find privileges: %s", vmserrstr (status
));
3962 if (CHECKPRIV (PRV$V_BYPASS
))
3963 return 0; /* BYPASS enabled */
3965 fab
.fab$b_fac
= FAB$M_GET
;
3966 fab
.fab$l_fna
= filename
;
3967 fab
.fab$b_fns
= strlen (filename
);
3968 fab
.fab$l_xab
= &xab
;
3969 xab
= cc$rms_xabpro
;
3970 xab
.xab$l_aclbuf
= aclbuf
;
3971 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3972 status
= SYS$
OPEN (&fab
, 0, 0);
3975 SYS$
CLOSE (&fab
, 0, 0);
3976 /* Check system access */
3977 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITABLE (XAB$V_SYS
))
3979 /* Check ACL entries, if any */
3981 if (xab
.xab$w_acllen
> 0)
3984 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3985 while (*aclptr
&& aclptr
< aclend
)
3987 size
= (*aclptr
& 0xff) / 4;
3988 typecode
= (*aclptr
>> 8) & 0xff;
3989 if (typecode
== ACE$C_KEYID
)
3990 for (i
= size
- 1; i
> 1; i
--)
3991 if (aclptr
[i
] == uic
)
3994 if (aclptr
[1] & ACE$M_WRITE
)
3995 return 0; /* Write access through ACL */
3997 aclptr
= &aclptr
[size
];
3999 if (acl_controlled
) /* ACL specified, prohibits write access */
4002 /* No ACL entries specified, check normal protection */
4003 if (WRITABLE (XAB$V_WLD
)) /* World writable */
4005 if (WRITABLE (XAB$V_GRP
) &&
4006 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
4007 return 0; /* Group writable */
4008 if (WRITABLE (XAB$V_OWN
) &&
4009 (xab
.xab$l_uic
& 0xFFFF) == memid
)
4010 return 0; /* Owner writable */
4012 return -1; /* Not writable */
4014 #endif /* not VMS4_4 */
4017 static char vtbuf
[NAM$C_MAXRSS
+1];
4019 /* translate a vms file spec to a unix path */
4021 sys_translate_vms (vfile
)
4032 /* leading device or logical name is a root directory */
4033 if (p
= strchr (vfile
, ':'))
4042 if (*p
== '[' || *p
== '<')
4044 while (*++vfile
!= *p
+ 2)
4048 if (vfile
[-1] == *p
)
4071 static char utbuf
[NAM$C_MAXRSS
+1];
4073 /* translate a unix path to a VMS file spec */
4075 sys_translate_unix (ufile
)
4098 if (index (&ufile
[1], '/'))
4105 if (index (&ufile
[1], '/'))
4112 if (strncmp (ufile
, "./", 2) == 0)
4119 ufile
++; /* skip the dot */
4120 if (index (&ufile
[1], '/'))
4125 else if (strncmp (ufile
, "../", 3) == 0)
4133 ufile
+= 2; /* skip the dots */
4134 if (index (&ufile
[1], '/'))
4159 extern char *getcwd ();
4161 #define MAXPATHLEN 1024
4163 ptr
= xmalloc (MAXPATHLEN
);
4164 val
= getcwd (ptr
, MAXPATHLEN
);
4170 strcpy (pathname
, ptr
);
4179 long item_code
= JPI$_OWNER
;
4180 unsigned long parent_id
;
4183 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
4186 vaxc$errno
= status
;
4196 return (getgid () << 16) | getuid ();
4201 sys_read (fildes
, buf
, nbyte
)
4206 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
4211 sys_write (fildes
, buf
, nbyte
)
4216 register int nwrote
, rtnval
= 0;
4218 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
4224 return rtnval
? rtnval
: -1;
4225 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
4226 return rtnval
? rtnval
: -1;
4227 return (rtnval
+ nwrote
);
4232 * VAX/VMS VAX C RTL really loses. It insists that records
4233 * end with a newline (carriage return) character, and if they
4234 * don't it adds one (nice of it isn't it!)
4236 * Thus we do this stupidity below.
4241 sys_write (fildes
, buf
, nbytes
)
4244 unsigned int nbytes
;
4251 fstat (fildes
, &st
);
4257 /* Handle fixed-length files with carriage control. */
4258 if (st
.st_fab_rfm
== FAB$C_FIX
4259 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
4261 len
= st
.st_fab_mrs
;
4262 retval
= write (fildes
, p
, min (len
, nbytes
));
4265 retval
++; /* This skips the implied carriage control */
4269 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4270 while (*e
!= '\n' && e
> p
) e
--;
4271 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
4272 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4274 retval
= write (fildes
, p
, len
);
4285 /* Create file NEW copying its attributes from file OLD. If
4286 OLD is 0 or does not exist, create based on the value of
4289 /* Protection value the file should ultimately have.
4290 Set by create_copy_attrs, and use by rename_sansversions. */
4291 static unsigned short int fab_final_pro
;
4294 creat_copy_attrs (old
, new)
4297 struct FAB fab
= cc$rms_fab
;
4298 struct XABPRO xabpro
;
4299 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
4300 extern int vms_stmlf_recfm
;
4304 fab
.fab$b_fac
= FAB$M_GET
;
4305 fab
.fab$l_fna
= old
;
4306 fab
.fab$b_fns
= strlen (old
);
4307 fab
.fab$l_xab
= (char *) &xabpro
;
4308 xabpro
= cc$rms_xabpro
;
4309 xabpro
.xab$l_aclbuf
= aclbuf
;
4310 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
4311 /* Call $OPEN to fill in the fab & xabpro fields. */
4312 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4314 SYS$
CLOSE (&fab
, 0, 0);
4315 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
4316 if (xabpro
.xab$w_acllen
> 0)
4318 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
4319 /* If the acl buffer was too short, redo open with longer one.
4320 Wouldn't need to do this if there were some system imposed
4321 limit on the size of an ACL, but I can't find any such. */
4323 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
4324 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
4325 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4326 SYS$
CLOSE (&fab
, 0, 0);
4332 xabpro
.xab$l_aclbuf
= 0;
4337 fab
.fab$l_fna
= new;
4338 fab
.fab$b_fns
= strlen (new);
4342 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
4343 fab
.fab$b_rat
= FAB$M_CR
;
4346 /* Set the file protections such that we will be able to manipulate
4347 this file. Once we are done writing and renaming it, we will set
4348 the protections back. */
4350 fab_final_pro
= xabpro
.xab$w_pro
;
4352 SYS$
SETDFPROT (0, &fab_final_pro
);
4353 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
4355 /* Create the new file with either default attrs or attrs copied
4357 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
4359 SYS$
CLOSE (&fab
, 0, 0);
4360 /* As this is a "replacement" for creat, return a file descriptor
4361 opened for writing. */
4362 return open (new, O_WRONLY
);
4367 #include <varargs.h>
4370 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4375 sys_creat (va_alist
)
4378 va_list list_incrementer
;
4381 int rfd
; /* related file descriptor */
4382 int fd
; /* Our new file descriptor */
4389 extern int vms_stmlf_recfm
;
4392 va_start (list_incrementer
);
4393 name
= va_arg (list_incrementer
, char *);
4394 mode
= va_arg (list_incrementer
, int);
4396 rfd
= va_arg (list_incrementer
, int);
4397 va_end (list_incrementer
);
4400 /* Use information from the related file descriptor to set record
4401 format of the newly created file. */
4402 fstat (rfd
, &st_buf
);
4403 switch (st_buf
.st_fab_rfm
)
4406 strcpy (rfm
, "rfm = fix");
4407 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
4408 strcpy (rat
, "rat = ");
4409 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4411 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4412 strcat (rat
, "ftn");
4413 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4414 strcat (rat
, "prn");
4415 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4416 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4417 strcat (rat
, ", blk");
4419 strcat (rat
, "blk");
4420 return creat (name
, 0, rfm
, rat
, mrs
);
4423 strcpy (rfm
, "rfm = vfc");
4424 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
4425 strcpy (rat
, "rat = ");
4426 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4428 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4429 strcat (rat
, "ftn");
4430 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4431 strcat (rat
, "prn");
4432 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4433 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4434 strcat (rat
, ", blk");
4436 strcat (rat
, "blk");
4437 return creat (name
, 0, rfm
, rat
, fsz
);
4440 strcpy (rfm
, "rfm = stm");
4444 strcpy (rfm
, "rfm = stmcr");
4448 strcpy (rfm
, "rfm = stmlf");
4452 strcpy (rfm
, "rfm = udf");
4456 strcpy (rfm
, "rfm = var");
4459 strcpy (rat
, "rat = ");
4460 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4462 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4463 strcat (rat
, "ftn");
4464 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4465 strcat (rat
, "prn");
4466 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4467 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4468 strcat (rat
, ", blk");
4470 strcat (rat
, "blk");
4474 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
4475 strcpy (rat
, "rat=cr");
4477 /* Until the VAX C RTL fixes the many bugs with modes, always use
4478 mode 0 to get the user's default protection. */
4479 fd
= creat (name
, 0, rfm
, rat
);
4480 if (fd
< 0 && errno
== EEXIST
)
4482 if (unlink (name
) < 0)
4483 report_file_error ("delete", build_string (name
));
4484 fd
= creat (name
, 0, rfm
, rat
);
4490 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4492 sys_fwrite (ptr
, size
, num
, fp
)
4493 register char * ptr
;
4496 register int tot
= num
* size
;
4504 * The VMS C library routine creat actually creates a new version of an
4505 * existing file rather than truncating the old version. There are times
4506 * when this is not the desired behavior, for instance, when writing an
4507 * auto save file (you only want one version), or when you don't have
4508 * write permission in the directory containing the file (but the file
4509 * itself is writable). Hence this routine, which is equivalent to
4510 * "close (creat (fn, 0));" on Unix if fn already exists.
4516 struct FAB xfab
= cc$rms_fab
;
4517 struct RAB xrab
= cc$rms_rab
;
4520 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
4521 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
4522 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
4523 xfab
.fab$l_fna
= fn
;
4524 xfab
.fab$b_fns
= strlen (fn
);
4525 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
4527 xrab
.rab$l_fab
= &xfab
;
4529 /* This gibberish opens the file, positions to the first record, and
4530 deletes all records from there until the end of file. */
4531 if ((SYS$
OPEN (&xfab
) & 01) == 01)
4533 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
4534 (SYS$
FIND (&xrab
) & 01) == 01 &&
4535 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
4546 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4547 SYSPRV or a readable SYSUAF.DAT. */
4553 * Routine to read the VMS User Authorization File and return
4554 * a specific user's record.
4557 static struct UAF retuaf
;
4560 get_uaf_name (uname
)
4567 uaf_fab
= cc$rms_fab
;
4568 uaf_rab
= cc$rms_rab
;
4569 /* initialize fab fields */
4570 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4571 uaf_fab
.fab$b_fns
= 21;
4572 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4573 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4574 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4575 /* initialize rab fields */
4576 uaf_rab
.rab$l_fab
= &uaf_fab
;
4577 /* open the User Authorization File */
4578 status
= SYS$
OPEN (&uaf_fab
);
4582 vaxc$errno
= status
;
4585 status
= SYS$
CONNECT (&uaf_rab
);
4589 vaxc$errno
= status
;
4592 /* read the requested record - index is in uname */
4593 uaf_rab
.rab$l_kbf
= uname
;
4594 uaf_rab
.rab$b_ksz
= strlen (uname
);
4595 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4596 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4597 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4598 status
= SYS$
GET (&uaf_rab
);
4602 vaxc$errno
= status
;
4605 /* close the User Authorization File */
4606 status
= SYS$
DISCONNECT (&uaf_rab
);
4610 vaxc$errno
= status
;
4613 status
= SYS$
CLOSE (&uaf_fab
);
4617 vaxc$errno
= status
;
4631 uaf_fab
= cc$rms_fab
;
4632 uaf_rab
= cc$rms_rab
;
4633 /* initialize fab fields */
4634 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4635 uaf_fab
.fab$b_fns
= 21;
4636 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4637 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4638 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4639 /* initialize rab fields */
4640 uaf_rab
.rab$l_fab
= &uaf_fab
;
4641 /* open the User Authorization File */
4642 status
= SYS$
OPEN (&uaf_fab
);
4646 vaxc$errno
= status
;
4649 status
= SYS$
CONNECT (&uaf_rab
);
4653 vaxc$errno
= status
;
4656 /* read the requested record - index is in uic */
4657 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4658 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4659 uaf_rab
.rab$b_ksz
= sizeof uic
;
4660 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4661 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4662 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4663 status
= SYS$
GET (&uaf_rab
);
4667 vaxc$errno
= status
;
4670 /* close the User Authorization File */
4671 status
= SYS$
DISCONNECT (&uaf_rab
);
4675 vaxc$errno
= status
;
4678 status
= SYS$
CLOSE (&uaf_fab
);
4682 vaxc$errno
= status
;
4688 static struct passwd retpw
;
4696 /* copy these out first because if the username is 32 chars, the next
4697 section will overwrite the first byte of the UIC */
4698 retpw
.pw_uid
= up
->uaf$w_mem
;
4699 retpw
.pw_gid
= up
->uaf$w_grp
;
4701 /* I suppose this is not the best style, to possibly overwrite one
4702 byte beyond the end of the field, but what the heck... */
4703 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4704 while (ptr
[-1] == ' ')
4707 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4709 /* the rest of these are counted ascii strings */
4710 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4711 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4712 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4713 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4714 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4715 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4716 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4717 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4721 #else /* not READ_SYSUAF */
4722 static struct passwd retpw
;
4723 #endif /* not READ_SYSUAF */
4734 unsigned char * full
;
4735 #endif /* READ_SYSUAF */
4740 if ('a' <= *ptr
&& *ptr
<= 'z')
4745 if (!(up
= get_uaf_name (name
)))
4747 return cnv_uaf_pw (up
);
4749 if (strcmp (name
, getenv ("USER")) == 0)
4751 retpw
.pw_uid
= getuid ();
4752 retpw
.pw_gid
= getgid ();
4753 strcpy (retpw
.pw_name
, name
);
4754 if (full
= egetenv ("FULLNAME"))
4755 strcpy (retpw
.pw_gecos
, full
);
4757 *retpw
.pw_gecos
= '\0';
4758 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4759 *retpw
.pw_shell
= '\0';
4764 #endif /* not READ_SYSUAF */
4774 if (!(up
= get_uaf_uic (uid
)))
4776 return cnv_uaf_pw (up
);
4778 if (uid
== sys_getuid ())
4779 return getpwnam (egetenv ("USER"));
4782 #endif /* not READ_SYSUAF */
4785 /* return total address space available to the current process. This is
4786 the sum of the current p0 size, p1 size and free page table entries
4792 unsigned long free_pages
;
4793 unsigned long frep0va
;
4794 unsigned long frep1va
;
4797 item_code
= JPI$_FREPTECNT
;
4798 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4801 vaxc$errno
= status
;
4806 item_code
= JPI$_FREP0VA
;
4807 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4810 vaxc$errno
= status
;
4813 item_code
= JPI$_FREP1VA
;
4814 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4817 vaxc$errno
= status
;
4821 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4825 define_logical_name (varname
, string
)
4829 struct dsc$descriptor_s strdsc
=
4830 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4831 struct dsc$descriptor_s envdsc
=
4832 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4833 struct dsc$descriptor_s lnmdsc
=
4834 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4836 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4840 delete_logical_name (varname
)
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$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4866 error ("execvp system call not implemented");
4875 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4876 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4877 char from_esn
[NAM$C_MAXRSS
];
4878 char to_esn
[NAM$C_MAXRSS
];
4880 from_fab
.fab$l_fna
= from
;
4881 from_fab
.fab$b_fns
= strlen (from
);
4882 from_fab
.fab$l_nam
= &from_nam
;
4883 from_fab
.fab$l_fop
= FAB$M_NAM
;
4885 from_nam
.nam$l_esa
= from_esn
;
4886 from_nam
.nam$b_ess
= sizeof from_esn
;
4888 to_fab
.fab$l_fna
= to
;
4889 to_fab
.fab$b_fns
= strlen (to
);
4890 to_fab
.fab$l_nam
= &to_nam
;
4891 to_fab
.fab$l_fop
= FAB$M_NAM
;
4893 to_nam
.nam$l_esa
= to_esn
;
4894 to_nam
.nam$b_ess
= sizeof to_esn
;
4896 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4902 if (status
== RMS$_DEV
)
4906 vaxc$errno
= status
;
4911 /* This function renames a file like `rename', but it strips
4912 the version number from the "to" filename, such that the "to" file is
4913 will always be a new version. It also sets the file protection once it is
4914 finished. The protection that we will use is stored in fab_final_pro,
4915 and was set when we did a creat_copy_attrs to create the file that we
4918 We could use the chmod function, but Eunichs uses 3 bits per user category
4919 to describe the protection, and VMS uses 4 (write and delete are separate
4920 bits). To maintain portability, the VMS implementation of `chmod' wires
4921 the W and D bits together. */
4924 static struct fibdef fib
; /* We need this initialized to zero */
4925 char vms_file_written
[NAM$C_MAXRSS
];
4928 rename_sans_version (from
,to
)
4935 struct FAB to_fab
= cc$rms_fab
;
4936 struct NAM to_nam
= cc$rms_nam
;
4937 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4938 struct dsc$descriptor fib_attr
[2]
4939 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4940 char to_esn
[NAM$C_MAXRSS
];
4942 $
DESCRIPTOR (disk
,to_esn
);
4944 to_fab
.fab$l_fna
= to
;
4945 to_fab
.fab$b_fns
= strlen (to
);
4946 to_fab
.fab$l_nam
= &to_nam
;
4947 to_fab
.fab$l_fop
= FAB$M_NAM
;
4949 to_nam
.nam$l_esa
= to_esn
;
4950 to_nam
.nam$b_ess
= sizeof to_esn
;
4952 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4954 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4955 *(to_nam
.nam$l_ver
) = '\0';
4957 stat
= rename (from
, to_esn
);
4961 strcpy (vms_file_written
, to_esn
);
4963 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4964 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4966 /* Now set the file protection to the correct value */
4967 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4969 /* Copy these fields into the fib */
4970 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4971 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4972 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4974 SYS$
CLOSE (&to_fab
, 0, 0);
4976 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4979 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4980 0, 0, 0, &fib_attr
, 0);
4983 stat
= SYS$
DASSGN (chan
);
4986 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4997 unsigned short fid
[3];
4998 char esa
[NAM$C_MAXRSS
];
5001 fab
.fab$l_fop
= FAB$M_OFP
;
5002 fab
.fab$l_fna
= file
;
5003 fab
.fab$b_fns
= strlen (file
);
5004 fab
.fab$l_nam
= &nam
;
5007 nam
.nam$l_esa
= esa
;
5008 nam
.nam$b_ess
= NAM$C_MAXRSS
;
5010 status
= SYS$
PARSE (&fab
);
5011 if ((status
& 1) == 0)
5014 vaxc$errno
= status
;
5017 status
= SYS$
SEARCH (&fab
);
5018 if ((status
& 1) == 0)
5021 vaxc$errno
= status
;
5025 fid
[0] = nam
.nam$w_fid
[0];
5026 fid
[1] = nam
.nam$w_fid
[1];
5027 fid
[2] = nam
.nam$w_fid
[2];
5029 fab
.fab$l_fna
= new;
5030 fab
.fab$b_fns
= strlen (new);
5032 status
= SYS$
PARSE (&fab
);
5033 if ((status
& 1) == 0)
5036 vaxc$errno
= status
;
5040 nam
.nam$w_fid
[0] = fid
[0];
5041 nam
.nam$w_fid
[1] = fid
[1];
5042 nam
.nam$w_fid
[2] = fid
[2];
5044 nam
.nam$l_esa
= nam
.nam$l_name
;
5045 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
5047 status
= SYS$
ENTER (&fab
);
5048 if ((status
& 1) == 0)
5051 vaxc$errno
= status
;
5062 printf ("%s not yet implemented\r\n", badfunc
);
5070 /* Arrange to return a range centered on zero. */
5071 return rand () - (1 << 30);
5083 /* Called from init_sys_modes. */
5089 /* If we're not on an HFT we shouldn't do any of this. We determine
5090 if we are on an HFT by trying to get an HFT error code. If this
5091 call fails, we're not on an HFT. */
5093 if (ioctl (0, HFQERROR
, &junk
) < 0)
5095 #else /* not IBMR2AIX */
5096 if (ioctl (0, HFQEIO
, 0) < 0)
5098 #endif /* not IBMR2AIX */
5100 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5101 as the rubout key's ASCII code. Here this is changed. The bug is that
5102 there's no way to determine the old mapping, so in reset_sys_modes
5103 we need to assume that the normal map had been present. Of course, this
5104 code also doesn't help if on a terminal emulator which doesn't understand
5108 struct hfkeymap keymap
;
5110 buf
.hf_bufp
= (char *)&keymap
;
5111 buf
.hf_buflen
= sizeof (keymap
);
5112 keymap
.hf_nkeys
= 2;
5113 keymap
.hfkey
[0].hf_kpos
= 15;
5114 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5116 keymap
.hfkey
[0].hf_keyidh
= '<';
5117 #else /* not IBMR2AIX */
5118 keymap
.hfkey
[0].hf_page
= '<';
5119 #endif /* not IBMR2AIX */
5120 keymap
.hfkey
[0].hf_char
= 127;
5121 keymap
.hfkey
[1].hf_kpos
= 15;
5122 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5124 keymap
.hfkey
[1].hf_keyidh
= '<';
5125 #else /* not IBMR2AIX */
5126 keymap
.hfkey
[1].hf_page
= '<';
5127 #endif /* not IBMR2AIX */
5128 keymap
.hfkey
[1].hf_char
= 127;
5129 hftctl (0, HFSKBD
, &buf
);
5131 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
5133 line_ins_del_ok
= char_ins_del_ok
= 0;
5136 /* Reset the rubout key to backspace. */
5142 struct hfkeymap keymap
;
5146 if (ioctl (0, HFQERROR
, &junk
) < 0)
5148 #else /* not IBMR2AIX */
5149 if (ioctl (0, HFQEIO
, 0) < 0)
5151 #endif /* not IBMR2AIX */
5153 buf
.hf_bufp
= (char *)&keymap
;
5154 buf
.hf_buflen
= sizeof (keymap
);
5155 keymap
.hf_nkeys
= 2;
5156 keymap
.hfkey
[0].hf_kpos
= 15;
5157 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5159 keymap
.hfkey
[0].hf_keyidh
= '<';
5160 #else /* not IBMR2AIX */
5161 keymap
.hfkey
[0].hf_page
= '<';
5162 #endif /* not IBMR2AIX */
5163 keymap
.hfkey
[0].hf_char
= 8;
5164 keymap
.hfkey
[1].hf_kpos
= 15;
5165 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5167 keymap
.hfkey
[1].hf_keyidh
= '<';
5168 #else /* not IBMR2AIX */
5169 keymap
.hfkey
[1].hf_page
= '<';
5170 #endif /* not IBMR2AIX */
5171 keymap
.hfkey
[1].hf_char
= 8;
5172 hftctl (0, HFSKBD
, &buf
);
5179 /* These are included on Sunos 4.1 when we do not use shared libraries.
5180 X11 libraries may refer to these functions but (we hope) do not
5181 actually call them. */
5201 #endif /* USE_DL_STUBS */
5210 register int length
;
5214 long max_str
= 65535;
5216 while (length
> max_str
) {
5217 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5222 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5224 while (length
-- > 0)
5226 #endif /* not VMS */
5229 #endif /* no bzero */
5230 #endif /* BSTRING */
5232 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5235 /* Saying `void' requires a declaration, above, where bcopy is used
5236 and that declaration causes pain for systems where bcopy is a macro. */
5237 bcopy (b1
, b2
, length
)
5240 register int length
;
5243 long max_str
= 65535;
5245 while (length
> max_str
) {
5246 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
5252 (void) LIB$
MOVC3 (&length
, b1
, b2
);
5254 while (length
-- > 0)
5256 #endif /* not VMS */
5258 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5263 bcmp (b1
, b2
, length
) /* This could be a macro! */
5266 register int length
;
5269 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
5270 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
5272 return STR$
COMPARE (&src1
, &src2
);
5274 while (length
-- > 0)
5279 #endif /* not VMS */
5281 #endif /* no bcmp */
5282 #endif /* not BSTRING */
5284 #ifndef HAVE_STRSIGNAL
5291 if (0 <= code
&& code
< NSIG
)
5294 signame
= sys_errlist
[code
];
5296 /* Cast to suppress warning if the table has const char *. */
5297 signame
= (char *) sys_siglist
[code
];
5303 #endif /* HAVE_STRSIGNAL */