1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 86,87,88,93,94,95,1999,2000,01,2003
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
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>
89 #if !defined (USG) || defined (BSD_PGRPS)
91 #define setpgrp setpgid
95 /* Get SI_SRPC_DOMAIN, if it is available. */
96 #ifdef HAVE_SYS_SYSTEMINFO_H
97 #include <sys/systeminfo.h>
100 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
104 #include <sys/param.h>
108 extern unsigned start
__asm__ ("start");
130 #include <sys/file.h>
138 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
142 #include <sys/file.h>
150 #include <sys/ioctl.h>
156 #ifdef BROKEN_TIOCGWINSZ
161 #if defined (USG) || defined (DGUX)
162 #include <sys/utsname.h>
163 #ifndef MEMORY_IN_STRING_H
166 #if defined (TIOCGWINSZ) || defined (ISC4_0)
168 #include <sys/sioctl.h>
171 #include <sys/stream.h>
172 #include <sys/ptem.h>
174 #endif /* TIOCGWINSZ or ISC4_0 */
175 #endif /* USG or DGUX */
177 extern int quit_char
;
179 #include "keyboard.h"
182 #include "termhooks.h"
183 #include "termchar.h"
184 #include "termopts.h"
185 #include "dispextern.h"
187 #include "cm.h" /* for reset_sys_modes */
191 /* In process.h which conflicts with the local copy. */
193 int _CRTAPI1
_spawnlp (int, const char *, const char *, ...);
194 int _CRTAPI1
_getpid (void);
197 #ifdef NONSYSTEM_DIR_LIBRARY
199 #endif /* NONSYSTEM_DIR_LIBRARY */
201 #include "syssignal.h"
208 #ifndef HAVE_STRUCT_UTIMBUF
209 /* We want to use utime rather than utimes, but we couldn't find the
210 structure declaration. We'll use the traditional one. */
218 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
224 #define LNOFLSH 0100000
227 static int baud_convert
[] =
232 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
233 1800, 2400, 4800, 9600, 19200, 38400
240 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
242 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
250 void croak
P_ ((char *));
253 void hft_init
P_ ((struct tty_output
*));
254 void hft_reset
P_ ((struct tty_output
*));
257 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
259 SIGMASKTYPE sigprocmask_set
;
262 /* Discard pending input on all input descriptors. */
268 struct emacs_tty buf
;
273 /* Discarding input is not safe when the input could contain
274 replies from the X server. So don't do it. */
275 if (read_socket_hook
)
280 SYS$
QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
281 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
286 struct tty_output
*tty
;
287 for (tty
= tty_list
; tty
; tty
= tty
->next
)
290 ioctl (fileno (TTY_INPUT (tty
)), TIOCFLUSH
, &zero
);
293 #else /* not Apollo */
294 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
295 while (dos_keyread () != -1)
297 #else /* not MSDOS */
299 struct tty_output
*tty
;
300 for (tty
= tty_list
; tty
; tty
= tty
->next
)
302 EMACS_GET_TTY (fileno (TTY_INPUT (tty
)), &buf
);
303 EMACS_SET_TTY (fileno (TTY_INPUT (tty
)), &buf
, 0);
306 #endif /* not MSDOS */
307 #endif /* not Apollo */
309 #endif /* not WINDOWSNT */
314 /* Arrange for character C to be read as the next input from
320 if (read_socket_hook
)
323 /* Should perhaps error if in batch mode */
325 ioctl (fileno (TTY_INPUT (CURTTY())), TIOCSTI
, &c
);
326 #else /* no TIOCSTI */
327 error ("Cannot stuff terminal input characters in this version of Unix");
328 #endif /* no TIOCSTI */
334 init_baud_rate (struct tty_output
*tty
)
340 #ifdef INIT_BAUD_RATE
345 #else /* not DOS_NT */
349 SYS$
QIOW (0, fileno (TTY_INPUT (tty
)), IO$_SENSEMODE
, &sg
, 0, 0,
350 &sg
.class, 12, 0, 0, 0, 0 );
351 emacs_ospeed
= sg
.xmit_baud
;
357 tcgetattr (fileno (TTY_INPUT (tty
)), &sg
);
358 emacs_ospeed
= cfgetospeed (&sg
);
359 #if defined (USE_GETOBAUD) && defined (getobaud)
360 /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
361 if (emacs_ospeed
== 0)
362 emacs_ospeed
= getobaud (sg
.c_cflag
);
364 #else /* neither VMS nor TERMIOS */
370 tcgetattr (fileno (TTY_INPUT (tty
)), &sg
);
372 ioctl (fileno (TTY_INPUT (tty
)), TCGETA
, &sg
);
374 emacs_ospeed
= sg
.c_cflag
& CBAUD
;
375 #else /* neither VMS nor TERMIOS nor TERMIO */
378 sg
.sg_ospeed
= B9600
;
379 if (ioctl (fileno (TTY_INPUT (tty
)), TIOCGETP
, &sg
) < 0)
381 emacs_ospeed
= sg
.sg_ospeed
;
382 #endif /* not HAVE_TERMIO */
383 #endif /* not HAVE_TERMIOS */
385 #endif /* not DOS_NT */
386 #endif /* not INIT_BAUD_RATE */
389 baud_rate
= (emacs_ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
390 ? baud_convert
[emacs_ospeed
] : 9600);
397 set_exclusive_use (fd
)
401 ioctl (fd
, FIOCLEX
, 0);
403 /* Ok to do nothing if this feature does not exist */
408 wait_without_blocking ()
411 wait3 (0, WNOHANG
| WUNTRACED
, 0);
413 croak ("wait_without_blocking");
415 synch_process_alive
= 0;
418 #endif /* not subprocesses */
420 int wait_debugging
; /* Set nonzero to make following function work under dbx
421 (at least for bsd). */
424 wait_for_termination_signal ()
427 /* Wait for subprocess with process id `pid' to terminate and
428 make sure it will get eliminated (not remain forever as a zombie) */
431 wait_for_termination (pid
)
440 status
= SYS$
FORCEX (&pid
, 0, 0);
443 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
444 /* Note that kill returns -1 even if the process is just a zombie now.
445 But inevitably a SIGCHLD interrupt should be generated
446 and child_sig will do wait3 and make the process go away. */
447 /* There is some indication that there is a bug involved with
448 termination of subprocesses, perhaps involving a kernel bug too,
449 but no idea what it is. Just as a hunch we signal SIGCHLD to see
450 if that causes the problem to go away or get worse. */
451 sigsetmask (sigmask (SIGCHLD
));
452 if (0 > kill (pid
, 0))
454 sigsetmask (SIGEMPTYMASK
);
455 kill (getpid (), SIGCHLD
);
461 sigpause (SIGEMPTYMASK
);
462 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
463 #if defined (UNIPLUS)
464 if (0 > kill (pid
, 0))
467 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
468 #ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */
469 sigblock (sigmask (SIGCHLD
));
471 if (kill (pid
, 0) == -1 && errno
== ESRCH
)
473 sigunblock (sigmask (SIGCHLD
));
477 sigsuspend (&empty_mask
);
478 #else /* not POSIX_SIGNALS */
479 #ifdef HAVE_SYSV_SIGPAUSE
481 if (0 > kill (pid
, 0))
487 #else /* not HAVE_SYSV_SIGPAUSE */
491 #else /* not WINDOWSNT */
492 if (0 > kill (pid
, 0))
494 /* Using sleep instead of pause avoids timing error.
495 If the inferior dies just before the sleep,
496 we lose just one second. */
498 #endif /* not WINDOWSNT */
499 #endif /* not HAVE_SYSV_SIGPAUSE */
500 #endif /* not POSIX_SIGNALS */
501 #endif /* not UNIPLUS */
502 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
504 #else /* not subprocesses */
507 #else /* not __DJGPP__ > 1 */
509 if (kill (pid
, 0) < 0)
515 if (status
== pid
|| status
== -1)
518 #endif /* not __DJGPP__ > 1*/
519 #endif /* not subprocesses */
526 * flush any pending output
527 * (may flush input as well; it does not matter the way we use it)
531 flush_pending_output (channel
)
535 /* If we try this, we get hit with SIGTTIN, because
536 the child's tty belongs to the child's pgrp. */
539 ioctl (channel
, TCFLSH
, 1);
543 /* 3rd arg should be ignored
544 but some 4.2 kernels actually want the address of an int
545 and nonzero means something different. */
546 ioctl (channel
, TIOCFLUSH
, &zero
);
553 /* Set up the terminal at the other end of a pseudo-terminal that
554 we will be controlling an inferior through.
555 It should not echo or do line-editing, since that is done
556 in Emacs. No padding needed for insertion into an Emacs buffer. */
559 child_setup_tty (out
)
565 EMACS_GET_TTY (out
, &s
);
567 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
568 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
569 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
571 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
572 /* No output delays */
574 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
575 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
576 #if 0 /* This causes bugs in (for instance) telnet to certain sites. */
577 s
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
578 #ifdef INLCR /* Just being cautious, since I can't check how
579 widespread INLCR is--rms. */
580 s
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
584 s
.main
.c_iflag
&= ~IUCLC
; /* Disable downcasing on input. */
587 s
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
590 s
.main
.c_oflag
&= ~OLCUC
; /* Disable upcasing on output. */
592 s
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
593 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CSIZE
) | CS8
; /* Don't strip 8th bit */
595 /* Said to be unnecessary: */
596 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
597 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
600 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
601 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
602 s
.main
.c_cc
[VERASE
] = CDISABLE
; /* disable erase processing */
603 s
.main
.c_cc
[VKILL
] = CDISABLE
; /* disable kill processing */
606 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
610 /* AIX enhanced edit loses NULs, so disable it */
613 s
.main
.c_iflag
&= ~ASCEDIT
;
615 /* Also, PTY overloads NUL and BREAK.
616 don't ignore break, but don't signal either, so it looks like NUL. */
617 s
.main
.c_iflag
&= ~IGNBRK
;
618 s
.main
.c_iflag
&= ~BRKINT
;
619 /* QUIT and INTR work better as signals, so disable character forms */
620 s
.main
.c_cc
[VINTR
] = 0377;
621 #ifdef SIGNALS_VIA_CHARACTERS
622 /* the QUIT and INTR character are used in process_send_signal
623 so set them here to something useful. */
624 if (s
.main
.c_cc
[VQUIT
] == 0377)
625 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
626 if (s
.main
.c_cc
[VINTR
] == 0377)
627 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
628 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
629 /* QUIT and INTR work better as signals, so disable character forms */
630 s
.main
.c_cc
[VQUIT
] = 0377;
631 s
.main
.c_cc
[VINTR
] = 0377;
632 s
.main
.c_lflag
&= ~ISIG
;
633 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
634 s
.main
.c_cc
[VEOL
] = 0377;
635 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
638 #else /* not HAVE_TERMIO */
640 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
642 s
.main
.sg_flags
|= LPASS8
;
643 s
.main
.sg_erase
= 0377;
644 s
.main
.sg_kill
= 0377;
645 s
.lmode
= LLITOUT
| s
.lmode
; /* Don't strip 8th bit */
647 #endif /* not HAVE_TERMIO */
649 EMACS_SET_TTY (out
, &s
, 0);
658 ioctl (out
, FIOASYNC
, &zero
);
661 #endif /* not DOS_NT */
665 #endif /* subprocesses */
667 /* Record a signal code and the handler for it. */
671 SIGTYPE (*handler
) P_ ((int));
674 static void save_signal_handlers
P_ ((struct save_signal
*));
675 static void restore_signal_handlers
P_ ((struct save_signal
*));
677 /* Suspend the Emacs process; give terminal to its superior. */
683 /* "Foster" parentage allows emacs to return to a subprocess that attached
684 to the current emacs as a cheaper than starting a whole new process. This
685 is set up by KEPTEDITOR.COM. */
686 unsigned long parent_id
, foster_parent_id
;
689 fpid_string
= getenv ("EMACS_PARENT_PID");
690 if (fpid_string
!= NULL
)
692 sscanf (fpid_string
, "%x", &foster_parent_id
);
693 if (foster_parent_id
!= 0)
694 parent_id
= foster_parent_id
;
696 parent_id
= getppid ();
699 parent_id
= getppid ();
701 xfree (fpid_string
); /* On VMS, this was malloc'd */
703 if (parent_id
&& parent_id
!= 0xffffffff)
705 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
706 int status
= LIB$
ATTACH (&parent_id
) & 1;
707 signal (SIGINT
, oldsig
);
716 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
717 d_prompt
.a
= "Emacs: "; /* Just a reminder */
718 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
723 #if defined (SIGTSTP) && !defined (MSDOS)
726 int pgrp
= EMACS_GETPGRP (0);
727 EMACS_KILLPG (pgrp
, SIGTSTP
);
730 #else /* No SIGTSTP */
731 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
732 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
733 kill (getpid (), SIGQUIT
);
735 #else /* No SIGTSTP or USG_JOBCTRL */
737 /* On a system where suspending is not implemented,
738 instead fork a subshell and let it talk directly to the terminal
742 #endif /* no USG_JOBCTRL */
743 #endif /* no SIGTSTP */
747 /* Fork a subshell. */
754 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
756 char oldwd
[MAXPATHLEN
+1]; /* Fixed length is safe on MSDOS. */
759 struct save_signal saved_handlers
[5];
761 unsigned char *str
= 0;
764 saved_handlers
[0].code
= SIGINT
;
765 saved_handlers
[1].code
= SIGQUIT
;
766 saved_handlers
[2].code
= SIGTERM
;
768 saved_handlers
[3].code
= SIGIO
;
769 saved_handlers
[4].code
= 0;
771 saved_handlers
[3].code
= 0;
774 /* Mentioning current_buffer->buffer would mean including buffer.h,
775 which somehow wedges the hp compiler. So instead... */
777 dir
= intern ("default-directory");
778 if (NILP (Fboundp (dir
)))
780 dir
= Fsymbol_value (dir
);
784 dir
= expand_and_dir_to_file (Funhandled_file_name_directory (dir
), Qnil
);
785 str
= (unsigned char *) alloca (SCHARS (dir
) + 2);
787 bcopy (SDATA (dir
), str
, len
);
788 if (str
[len
- 1] != '/') str
[len
++] = '/';
795 save_signal_handlers (saved_handlers
);
796 synch_process_alive
= 1;
797 #endif /* __DJGPP__ > 1 */
801 error ("Can't spawn subshell");
808 #ifdef DOS_NT /* MW, Aug 1993 */
811 sh
= (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
814 sh
= (char *) egetenv ("SHELL");
818 /* Use our buffer's default directory for the subshell. */
820 chdir ((char *) str
);
823 close_process_descs (); /* Close Emacs's pipes/ptys */
826 #ifdef SET_EMACS_PRIORITY
828 extern EMACS_INT emacs_priority
;
830 if (emacs_priority
< 0)
831 nice (-emacs_priority
);
835 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
837 char *epwd
= getenv ("PWD");
838 char old_pwd
[MAXPATHLEN
+1+4];
840 /* If PWD is set, pass it with corrected value. */
843 strcpy (old_pwd
, epwd
);
844 if (str
[len
- 1] == '/')
846 setenv ("PWD", str
, 1);
851 putenv (old_pwd
); /* restore previous value */
853 #if 0 /* This is also reported if last command executed in subshell failed, KFS */
855 report_file_error ("Can't execute subshell", Fcons (build_string (sh
), Qnil
));
857 #else /* not MSDOS */
859 /* Waits for process completion */
860 pid
= _spawnlp (_P_WAIT
, sh
, sh
, NULL
);
863 write (1, "Can't execute subshell", 22);
864 #else /* not WINDOWSNT */
866 write (1, "Can't execute subshell", 22);
868 #endif /* not WINDOWSNT */
869 #endif /* not MSDOS */
872 /* Do this now if we did not do it before. */
873 #if !defined (MSDOS) || __DJGPP__ == 1
874 save_signal_handlers (saved_handlers
);
875 synch_process_alive
= 1;
879 wait_for_termination (pid
);
881 restore_signal_handlers (saved_handlers
);
882 synch_process_alive
= 0;
885 #endif /* !MAC_OS8 */
888 save_signal_handlers (saved_handlers
)
889 struct save_signal
*saved_handlers
;
891 while (saved_handlers
->code
)
893 saved_handlers
->handler
894 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers
->code
, SIG_IGN
);
900 restore_signal_handlers (saved_handlers
)
901 struct save_signal
*saved_handlers
;
903 while (saved_handlers
->code
)
905 signal (saved_handlers
->code
, saved_handlers
->handler
);
919 /* XXX What if we get called with more than one fds? */
920 old_fcntl_flags
= fcntl (fd
, F_GETFL
, 0) & ~FASYNC
;
921 fcntl (fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
923 interrupts_deferred
= 0;
930 fcntl (fd
, F_SETFL
, old_fcntl_flags
);
933 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
938 if (read_socket_hook
)
942 sigunblock (sigmask (SIGWINCH
));
944 sigunblock (sigmask (SIGIO
));
946 interrupts_deferred
= 0;
950 unrequest_sigio (void)
952 if (read_socket_hook
)
956 sigblock (sigmask (SIGWINCH
));
958 sigblock (sigmask (SIGIO
));
959 interrupts_deferred
= 1;
962 #else /* no FASYNC */
963 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
970 if (read_socket_hook
)
973 /* XXX CURTTY() is bogus here. */
974 ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC
, &on
);
975 interrupts_deferred
= 0;
979 unrequest_sigio (struct tty_output
*tty
)
983 if (read_socket_hook
)
986 /* XXX CURTTY() is bogus here. */
987 ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC
, &off
);
988 interrupts_deferred
= 1;
991 #else /* not FASYNC, not STRIDE */
1003 if (read_socket_hook
)
1007 sigaddset (&st
, SIGIO
);
1008 ioctl (0, FIOASYNC
, &on
); /* XXX This fails for multiple ttys. */
1009 interrupts_deferred
= 0;
1010 sigprocmask (SIG_UNBLOCK
, &st
, (sigset_t
*)0);
1018 if (read_socket_hook
)
1021 ioctl (0, FIOASYNC
, &off
); /* XXX This fails for multiple ttys. */
1022 interrupts_deferred
= 1;
1025 #else /* ! _CX_UX */
1031 if (read_socket_hook
)
1034 croak ("request_sigio");
1040 if (read_socket_hook
)
1043 croak ("unrequest_sigio");
1050 #endif /* F_SETFL */
1052 /* Saving and restoring the process group of Emacs's terminal. */
1056 /* The process group of which Emacs was a member when it initially
1059 If Emacs was in its own process group (i.e. inherited_pgroup ==
1060 getpid ()), then we know we're running under a shell with job
1061 control (Emacs would never be run as part of a pipeline).
1064 If Emacs was not in its own process group, then we know we're
1065 running under a shell (or a caller) that doesn't know how to
1066 separate itself from Emacs (like sh). Emacs must be in its own
1067 process group in order to receive SIGIO correctly. In this
1068 situation, we put ourselves in our own pgroup, forcibly set the
1069 tty's pgroup to our pgroup, and make sure to restore and reinstate
1070 the tty's pgroup just like any other terminal setting. If
1071 inherited_group was not the tty's pgroup, then we'll get a
1072 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1073 it goes foreground in the future, which is what should happen. */
1074 int inherited_pgroup
;
1076 /* Split off the foreground process group to Emacs alone.
1077 When we are in the foreground, but not started in our own process
1078 group, redirect the TTY to point to our own process group. We need
1079 to be in our own process group to receive SIGIO properly. */
1081 narrow_foreground_group (struct tty_output
*tty
)
1085 setpgrp (0, inherited_pgroup
);
1086 /* XXX This only works on the controlling tty. */
1087 if (inherited_pgroup
!= me
)
1088 EMACS_SET_TTY_PGRP (fileno (TTY_INPUT (tty
)), &me
);
1092 /* Set the tty to our original foreground group. */
1094 widen_foreground_group (struct tty_output
*tty
)
1096 if (inherited_pgroup
!= getpid ())
1097 EMACS_SET_TTY_PGRP (fileno (TTY_INPUT (tty
)), &inherited_pgroup
);
1098 setpgrp (0, inherited_pgroup
);
1101 #endif /* BSD_PGRPS */
1103 /* Getting and setting emacs_tty structures. */
1105 /* Set *TC to the parameters associated with the terminal FD.
1106 Return zero if all's well, or -1 if we ran into an error we
1107 couldn't deal with. */
1109 emacs_get_tty (fd
, settings
)
1111 struct emacs_tty
*settings
;
1113 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1115 /* We have those nifty POSIX tcmumbleattr functions. */
1116 bzero (&settings
->main
, sizeof (settings
->main
));
1117 if (tcgetattr (fd
, &settings
->main
) < 0)
1122 /* The SYSV-style interface? */
1123 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
1128 /* Vehemently Monstrous System? :-) */
1129 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
1130 &settings
->main
.class, 12, 0, 0, 0, 0)
1136 /* I give up - I hope you have the BSD ioctls. */
1137 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
1139 #endif /* not DOS_NT */
1144 /* Suivant - Do we have to get struct ltchars data? */
1146 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
1150 /* How about a struct tchars and a wordful of lmode bits? */
1152 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
1153 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
1157 /* We have survived the tempest. */
1162 /* Set the parameters of the tty on FD according to the contents of
1163 *SETTINGS. If FLUSHP is non-zero, we discard input.
1164 Return 0 if all went well, and -1 if anything failed. */
1167 emacs_set_tty (fd
, settings
, flushp
)
1169 struct emacs_tty
*settings
;
1172 /* Set the primary parameters - baud rate, character size, etcetera. */
1175 /* We have those nifty POSIX tcmumbleattr functions.
1176 William J. Smith <wjs@wiis.wang.com> writes:
1177 "POSIX 1003.1 defines tcsetattr to return success if it was
1178 able to perform any of the requested actions, even if some
1179 of the requested actions could not be performed.
1180 We must read settings back to ensure tty setup properly.
1181 AIX requires this to keep tty from hanging occasionally." */
1182 /* This make sure that we don't loop indefinitely in here. */
1183 for (i
= 0 ; i
< 10 ; i
++)
1184 if (tcsetattr (fd
, flushp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
1195 bzero (&new, sizeof (new));
1196 /* Get the current settings, and see if they're what we asked for. */
1197 tcgetattr (fd
, &new);
1198 /* We cannot use memcmp on the whole structure here because under
1199 * aix386 the termios structure has some reserved field that may
1202 if ( new.c_iflag
== settings
->main
.c_iflag
1203 && new.c_oflag
== settings
->main
.c_oflag
1204 && new.c_cflag
== settings
->main
.c_cflag
1205 && new.c_lflag
== settings
->main
.c_lflag
1206 && memcmp (new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
1214 /* The SYSV-style interface? */
1215 if (ioctl (fd
, flushp
? TCSETAF
: TCSETAW
, &settings
->main
) < 0)
1220 /* Vehemently Monstrous System? :-) */
1221 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
1222 &settings
->main
.class, 12, 0, 0, 0, 0)
1228 /* I give up - I hope you have the BSD ioctls. */
1229 if (ioctl (fd
, (flushp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
1231 #endif /* not DOS_NT */
1237 /* Suivant - Do we have to get struct ltchars data? */
1239 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
1243 /* How about a struct tchars and a wordful of lmode bits? */
1245 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
1246 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
1250 /* We have survived the tempest. */
1257 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1262 #ifndef F_SETOWN_BUG
1264 int old_fcntl_owner
;
1265 #endif /* F_SETOWN */
1266 #endif /* F_SETOWN_BUG */
1268 /* This may also be defined in stdio,
1269 but if so, this does no harm,
1270 and using the same name avoids wasting the other one's space. */
1273 extern char *_sobuf
;
1275 #if defined (USG) || defined (DGUX)
1276 unsigned char _sobuf
[BUFSIZ
+8];
1278 char _sobuf
[BUFSIZ
];
1283 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
1286 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
1290 init_all_sys_modes (void)
1292 struct tty_output
*tty
= tty_list
;
1294 init_sys_modes (tty
);
1300 init_sys_modes (tty_out
)
1301 struct tty_output
*tty_out
;
1303 struct emacs_tty tty
;
1306 /* cus-start.el complains if delete-exited-processes is not defined */
1307 #ifndef subprocesses
1308 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes
,
1309 doc
: /* *Non-nil means delete processes immediately when they exit.
1310 nil means don't delete them until `list-processes' is run. */);
1311 delete_exited_processes
= 0;
1313 #endif /* MAC_OS8 */
1317 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
1318 extern int (*interrupt_signal
) ();
1322 Vtty_erase_char
= Qnil
;
1329 input_ef
= get_kbd_event_flag ();
1330 /* LIB$GET_EF (&input_ef); */
1331 SYS$
CLREF (input_ef
);
1332 waiting_for_ast
= 0;
1334 timer_ef
= get_timer_event_flag ();
1335 /* LIB$GET_EF (&timer_ef); */
1336 SYS$
CLREF (timer_ef
);
1340 LIB$
GET_EF (&process_ef
);
1341 SYS$
CLREF (process_ef
);
1343 if (input_ef
/ 32 != process_ef
/ 32)
1344 croak ("Input and process event flags in different clusters.");
1346 if (input_ef
/ 32 != timer_ef
/ 32)
1347 croak ("Input and timer event flags in different clusters.");
1349 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1350 ((unsigned) 1 << (process_ef
% 32));
1352 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1353 ((unsigned) 1 << (timer_ef
% 32));
1355 sys_access_reinit ();
1360 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1361 narrow_foreground_group (tty_out
);
1364 #ifdef HAVE_WINDOW_SYSTEM
1365 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1366 needs the initialization code below. */
1367 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1370 if (! tty_out
->old_tty
)
1371 tty_out
->old_tty
= (struct emacs_tty
*) xmalloc (sizeof (struct emacs_tty
));
1373 EMACS_GET_TTY (fileno (TTY_INPUT (tty_out
)), tty_out
->old_tty
);
1375 tty
= *tty_out
->old_tty
;
1377 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1378 XSETINT (Vtty_erase_char
, tty
.main
.c_cc
[VERASE
]);
1381 /* This allows meta to be sent on 8th bit. */
1382 tty
.main
.c_iflag
&= ~INPCK
; /* don't check input for parity */
1384 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1385 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1386 #ifdef INLCR /* I'm just being cautious,
1387 since I can't check how widespread INLCR is--rms. */
1388 tty
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
1391 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1393 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1394 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1396 tty
.main
.c_lflag
&= ~IEXTEN
; /* Disable other editing characters. */
1398 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1401 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1403 tty
.main
.c_iflag
&= ~IXANY
;
1407 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1408 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1410 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1412 if (tty_out
->meta_key
)
1414 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1415 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1418 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1419 /* Set up C-g for both SIGQUIT and SIGINT.
1420 We don't know which we will get, but we handle both alike
1421 so which one it really gives us does not matter. */
1422 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1423 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1424 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1426 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1430 #if defined (mips) || defined (HAVE_TCATTR)
1432 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1435 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1436 #endif /* V_DSUSP */
1437 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1438 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1441 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1444 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1445 #endif /* VREPRINT */
1447 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1448 #endif /* VWERASE */
1450 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1451 #endif /* VDISCARD */
1456 tty
.main
.c_cc
[VSTART
] = '\021';
1459 tty
.main
.c_cc
[VSTOP
] = '\023';
1465 tty
.main
.c_cc
[VSTART
] = CDISABLE
;
1468 tty
.main
.c_cc
[VSTOP
] = CDISABLE
;
1471 #endif /* mips or HAVE_TCATTR */
1473 #ifdef SET_LINE_DISCIPLINE
1474 /* Need to explicitly request TERMIODISC line discipline or
1475 Ultrix's termios does not work correctly. */
1476 tty
.main
.c_line
= SET_LINE_DISCIPLINE
;
1480 /* AIX enhanced edit loses NULs, so disable it. */
1481 tty
.main
.c_line
= 0;
1482 tty
.main
.c_iflag
&= ~ASCEDIT
;
1484 tty
.main
.c_cc
[VSTRT
] = 255;
1485 tty
.main
.c_cc
[VSTOP
] = 255;
1486 tty
.main
.c_cc
[VSUSP
] = 255;
1487 tty
.main
.c_cc
[VDSUSP
] = 255;
1488 #endif /* IBMR2AIX */
1492 tty
.main
.c_cc
[VSTART
] = '\021';
1495 tty
.main
.c_cc
[VSTOP
] = '\023';
1498 /* Also, PTY overloads NUL and BREAK.
1499 don't ignore break, but don't signal either, so it looks like NUL.
1500 This really serves a purpose only if running in an XTERM window
1501 or via TELNET or the like, but does no harm elsewhere. */
1502 tty
.main
.c_iflag
&= ~IGNBRK
;
1503 tty
.main
.c_iflag
&= ~BRKINT
;
1505 #else /* if not HAVE_TERMIO */
1507 tty
.main
.tt_char
|= TT$M_NOECHO
;
1509 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1511 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1513 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1514 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1515 #else /* not VMS (BSD, that is) */
1517 XSETINT (Vtty_erase_char
, tty
.main
.sg_erase
);
1518 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1520 tty
.main
.sg_flags
|= ANYP
;
1521 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1522 #endif /* not DOS_NT */
1523 #endif /* not VMS (BSD, that is) */
1524 #endif /* not HAVE_TERMIO */
1526 /* If going to use CBREAK mode, we must request C-g to interrupt
1527 and turn off start and stop chars, etc. If not going to use
1528 CBREAK mode, do this anyway so as to turn off local flow
1529 control for user coming over network on 4.2; in this case,
1530 only t_stopc and t_startc really matter. */
1533 /* Note: if not using CBREAK mode, it makes no difference how we
1535 tty
.tchars
= new_tchars
;
1536 tty
.tchars
.t_intrc
= quit_char
;
1539 tty
.tchars
.t_startc
= '\021';
1540 tty
.tchars
.t_stopc
= '\023';
1543 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| tty_out
->old_tty
.lmode
;
1545 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1546 anything, and leaving it in breaks the meta key. Go figure. */
1547 tty
.lmode
&= ~LLITOUT
;
1554 #endif /* HAVE_TCHARS */
1555 #endif /* not HAVE_TERMIO */
1558 tty
.ltchars
= new_ltchars
;
1559 #endif /* HAVE_LTCHARS */
1560 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1561 if (!tty_out
->term_initted
)
1562 internal_terminal_init ();
1566 EMACS_SET_TTY (fileno (TTY_INPUT (tty_out
)), &tty
, 0);
1568 /* This code added to insure that, if flow-control is not to be used,
1569 we have an unlocked terminal at the start. */
1572 if (!flow_control
) ioctl (fileno (TTY_INPUT (tty_out
)), TCXONC
, 1);
1576 if (!flow_control
) ioctl (fileno (TTY_INPUT (tty_out
)), TIOCSTART
, 0);
1580 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1582 if (!flow_control
) tcflow (fileno (TTY_INPUT (tty_out
)), TCOON
);
1590 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1591 to be only LF. This is the way that is done. */
1594 if (ioctl (1, HFTGETID
, &tty
) != -1)
1595 write (1, "\033[20l", 5);
1601 /* Appears to do nothing when in PASTHRU mode.
1602 SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1603 interrupt_signal, oob_chars, 0, 0, 0, 0);
1605 queue_kbd_input (0);
1610 #ifndef F_SETOWN_BUG
1611 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1613 && ! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1615 old_fcntl_owner
= fcntl (fileno (TTY_INPUT (tty_out
)), F_GETOWN
, 0);
1616 fcntl (fileno (TTY_INPUT (tty_out
)), F_SETOWN
, getpid ());
1617 init_sigio (fileno (TTY_INPUT (tty_out
)));
1619 #endif /* F_GETOWN */
1620 #endif /* F_SETOWN_BUG */
1621 #endif /* F_SETFL */
1624 if (interrupt_input
)
1625 init_sigio (fileno (TTY_INPUT (tty_out
)));
1628 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1632 /* This symbol is defined on recent USG systems.
1633 Someone says without this call USG won't really buffer the file
1634 even with a call to setbuf. */
1635 setvbuf (TTY_OUTPUT (tty_out
), (char *) _sobuf
, _IOFBF
, sizeof _sobuf
);
1637 setbuf (TTY_OUTPUT (tty_out
), (char *) _sobuf
);
1639 #ifdef HAVE_WINDOW_SYSTEM
1640 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1641 needs the initialization code below. */
1642 if (EQ (Vwindow_system
, Qnil
)
1644 /* When running in tty mode on NT/Win95, we have a read_socket
1645 hook, but still need the rest of the initialization code below. */
1646 && (! read_socket_hook
)
1651 if (!tty_out
->term_initted
)
1653 Lisp_Object tail
, frame
;
1654 FOR_EACH_FRAME (tail
, frame
)
1656 if (FRAME_TERMCAP_P (XFRAME (frame
))
1657 && FRAME_TTY (XFRAME (frame
)) == tty_out
)
1658 init_frame_faces (XFRAME (frame
));
1662 if (tty_out
->term_initted
&& no_redraw_on_reenter
)
1664 if (display_completed
)
1665 direct_output_forward_char (0);
1669 Lisp_Object tail
, frame
;
1671 FOR_EACH_FRAME (tail
, frame
)
1673 if (FRAME_TERMCAP_P (XFRAME (frame
))
1674 && FRAME_TTY (XFRAME (frame
)) == tty_out
)
1675 FRAME_GARBAGED_P (XFRAME (frame
)) = 1;
1679 tty_out
->term_initted
= 1;
1682 /* Return nonzero if safe to use tabs in output.
1683 At the time this is called, init_sys_modes has not been done yet. */
1686 tabs_safe_p (struct tty_output
*tty
)
1688 struct emacs_tty etty
;
1690 EMACS_GET_TTY (fileno (TTY_INPUT (tty
)), &etty
);
1691 return EMACS_TTY_TABS_OK (&etty
);
1694 /* Get terminal size from system.
1695 Store number of lines into *HEIGHTP and width into *WIDTHP.
1696 We store 0 if there's no valid information. */
1699 get_tty_size (tty_out
, widthp
, heightp
)
1700 struct tty_output
*tty_out
;
1701 int *widthp
, *heightp
;
1707 struct winsize size
;
1709 if (ioctl (fileno (TTY_INPUT (tty_out
)), TIOCGWINSZ
, &size
) == -1)
1710 *widthp
= *heightp
= 0;
1713 *widthp
= size
.ws_col
;
1714 *heightp
= size
.ws_row
;
1720 /* SunOS - style. */
1721 struct ttysize size
;
1723 if (ioctl (fileno (TTY_INPUT (tty_out
)), TIOCGSIZE
, &size
) == -1)
1724 *widthp
= *heightp
= 0;
1727 *widthp
= size
.ts_cols
;
1728 *heightp
= size
.ts_lines
;
1734 struct sensemode tty
;
1736 SYS$
QIOW (0, fileno (TTY_INPUT (tty_out
)), IO$_SENSEMODE
, &tty
, 0, 0,
1737 &tty
.class, 12, 0, 0, 0, 0);
1738 *widthp
= tty
.scr_wid
;
1739 *heightp
= tty
.scr_len
;
1743 *widthp
= ScreenCols ();
1744 *heightp
= ScreenRows ();
1745 #else /* system doesn't know size */
1750 #endif /* not VMS */
1751 #endif /* not SunOS-style */
1752 #endif /* not BSD-style */
1755 /* Set the logical window size associated with descriptor FD
1756 to HEIGHT and WIDTH. This is used mainly with ptys. */
1759 set_window_size (fd
, height
, width
)
1760 int fd
, height
, width
;
1765 struct winsize size
;
1766 size
.ws_row
= height
;
1767 size
.ws_col
= width
;
1769 if (ioctl (fd
, TIOCSWINSZ
, &size
) == -1)
1770 return 0; /* error */
1777 /* SunOS - style. */
1778 struct ttysize size
;
1779 size
.ts_lines
= height
;
1780 size
.ts_cols
= width
;
1782 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1788 #endif /* not SunOS-style */
1789 #endif /* not BSD-style */
1794 reset_all_sys_modes (void)
1796 struct tty_output
*tty
= tty_list
;
1798 reset_sys_modes (tty
);
1803 /* Prepare the terminal for closing it; move the cursor to the
1804 bottom of the frame, turn off interrupt-driven I/O, etc. */
1806 reset_sys_modes (tty_out
)
1807 struct tty_output
*tty_out
;
1814 if (!tty_out
->term_initted
)
1816 #ifdef HAVE_WINDOW_SYSTEM
1817 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1818 needs the clean-up code below. */
1819 if (!EQ (Vwindow_system
, Qnil
)
1821 /* When running in tty mode on NT/Win95, we have a read_socket
1822 hook, but still need the rest of the clean-up code below. */
1828 cmgoto (tty_out
, FrameRows (tty_out
) - 1, 0);
1829 tty_clear_end_of_line (tty_out
, FrameCols (tty_out
));
1830 cmgoto (tty_out
, FrameRows (tty_out
) - 1, 0);
1831 #if defined (IBMR2AIX) && defined (AIXHFT)
1833 /* HFT devices normally use ^J as a LF/CR. We forced it to
1834 do the LF only. Now, we need to reset it. */
1837 if (ioctl (1, HFTGETID
, &tty
) != -1)
1838 write (1, "\033[20h", 5);
1842 tty_reset_terminal_modes (tty_out
);
1843 fflush (TTY_OUTPUT (tty_out
));
1846 /* Avoid possible loss of output when changing terminal modes. */
1847 fsync (TTY_OUTPUT (tty_out
));
1852 #ifndef F_SETOWN_BUG
1853 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1854 if (interrupt_input
)
1856 reset_sigio (tty_out
);
1857 fcntl (fileno (TTY_INPUT (tty_out
)), F_SETOWN
, old_fcntl_owner
);
1859 #endif /* F_SETOWN */
1860 #endif /* F_SETOWN_BUG */
1862 fcntl (fileno (TTY_INPUT (tty_out
)), F_SETFL
,
1863 fcntl (fileno (TTY_INPUT (tty_out
)), F_GETFL
, 0) & ~O_NDELAY
);
1865 #endif /* F_SETFL */
1867 if (interrupt_input
)
1868 reset_sigio (tty_out
);
1871 if (tty_out
->old_tty
)
1872 while (EMACS_SET_TTY (fileno (TTY_INPUT (tty_out
)),
1873 tty_out
->old_tty
, 0) < 0 && errno
== EINTR
)
1876 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1880 #ifdef SET_LINE_DISCIPLINE
1881 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1882 A different old line discipline is therefore not restored, yet.
1883 Restore the old line discipline by hand. */
1884 ioctl (0, TIOCSETD
, &tty_out
->old_tty
.main
.c_line
);
1892 widen_foreground_group (tty_out
);
1898 /* Set up the proper status flags for use of a pty. */
1904 /* I'm told that TOICREMOTE does not mean control chars
1905 "can't be sent" but rather that they don't have
1906 input-editing or signaling effects.
1907 That should be good, because we have other ways
1908 to do those things in Emacs.
1909 However, telnet mode seems not to work on 4.2.
1910 So TIOCREMOTE is turned off now. */
1912 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1913 will hang. In particular, the "timeout" feature (which
1914 causes a read to return if there is no data available)
1915 does this. Also it is known that telnet mode will hang
1916 in such a way that Emacs must be stopped (perhaps this
1917 is the same problem).
1919 If TIOCREMOTE is turned off, then there is a bug in
1920 hp-ux which sometimes loses data. Apparently the
1921 code which blocks the master process when the internal
1922 buffer fills up does not work. Other than this,
1923 though, everything else seems to work fine.
1925 Since the latter lossage is more benign, we may as well
1926 lose that way. -- cph */
1928 #if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
1931 ioctl (fd
, FIONBIO
, &on
);
1936 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1937 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1938 /* cause EMACS not to die when it should, i.e., when its own controlling */
1939 /* tty goes away. I've complained to the AIX developers, and they may */
1940 /* change this behavior, but I'm not going to hold my breath. */
1941 signal (SIGHUP
, SIG_IGN
);
1944 #endif /* HAVE_PTYS */
1948 /* Assigning an input channel is done at the start of Emacs execution.
1949 This is called each time Emacs is resumed, also, but does nothing
1950 because input_chain is no longer zero. */
1957 if (fileno (TTY_INPUT (CURTTY())) == 0)
1959 status
= SYS$
ASSIGN (&input_dsc
, &fileno (TTY_INPUT (CURTTY())), 0, 0);
1965 /* Deassigning the input channel is done before exiting. */
1970 return SYS$
DASSGN (fileno (TTY_INPUT (CURTTY())));
1975 /* Request reading one character into the keyboard buffer.
1976 This is done as soon as the buffer becomes empty. */
1982 extern kbd_input_ast ();
1984 waiting_for_ast
= 0;
1986 status
= SYS$
QIO (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK
,
1987 &input_iosb
, kbd_input_ast
, 1,
1988 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1993 /* Ast routine that is called when keyboard input comes in
1994 in accord with the SYS$QIO above. */
1999 register int c
= -1;
2000 int old_errno
= errno
;
2001 extern EMACS_TIME
*input_available_clear_time
;
2003 if (waiting_for_ast
)
2004 SYS$
SETEF (input_ef
);
2005 waiting_for_ast
= 0;
2008 if (input_count
== 25)
2010 printf ("Ast # %d,", input_count
);
2011 printf (" iosb = %x, %x, %x, %x",
2012 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
2015 if (input_iosb
.offset
)
2019 printf (", char = 0%o", c
);
2031 struct input_event e
;
2034 e
.kind
= ASCII_KEYSTROKE_EVENT
;
2035 XSETINT (e
.code
, c
);
2036 e
.frame_or_window
= selected_frame
;
2037 kbd_buffer_store_event (&e
);
2039 if (input_available_clear_time
)
2040 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
2044 /* Wait until there is something in kbd_buffer. */
2047 wait_for_kbd_input ()
2049 extern int have_process_input
, process_exited
;
2051 /* If already something, avoid doing system calls. */
2052 if (detect_input_pending ())
2056 /* Clear a flag, and tell ast routine above to set it. */
2057 SYS$
CLREF (input_ef
);
2058 waiting_for_ast
= 1;
2059 /* Check for timing error: ast happened while we were doing that. */
2060 if (!detect_input_pending ())
2062 /* No timing error: wait for flag to be set. */
2063 set_waiting_for_input (0);
2064 SYS$
WFLOR (input_ef
, input_eflist
);
2065 clear_waiting_for_input ();
2066 if (!detect_input_pending ())
2067 /* Check for subprocess input availability */
2069 int dsp
= have_process_input
|| process_exited
;
2071 SYS$
CLREF (process_ef
);
2072 if (have_process_input
)
2073 process_command_input ();
2078 update_mode_lines
++;
2079 prepare_menu_bars ();
2080 redisplay_preserve_echo_area (18);
2084 waiting_for_ast
= 0;
2087 /* Get rid of any pending QIO, when we are about to suspend
2088 or when we want to throw away pending input.
2089 We wait for a positive sign that the AST routine has run
2090 and therefore there is no I/O request queued when we return.
2091 SYS$SETAST is used to avoid a timing error. */
2097 printf ("At end_kbd_input.\n");
2101 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2103 SYS$
CANCEL (fileno (TTY_INPUT (CURTTY())));
2108 /* Clear a flag, and tell ast routine above to set it. */
2109 SYS$
CLREF (input_ef
);
2110 waiting_for_ast
= 1;
2112 SYS$
CANCEL (fileno (TTY_INPUT (CURTTY())));
2114 SYS$
WAITFR (input_ef
);
2115 waiting_for_ast
= 0;
2118 /* Wait for either input available or time interval expiry. */
2121 input_wait_timeout (timeval
)
2122 int timeval
; /* Time to wait, in seconds */
2125 static int zero
= 0;
2126 static int large
= -10000000;
2128 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2130 /* If already something, avoid doing system calls. */
2131 if (detect_input_pending ())
2135 /* Clear a flag, and tell ast routine above to set it. */
2136 SYS$
CLREF (input_ef
);
2137 waiting_for_ast
= 1;
2138 /* Check for timing error: ast happened while we were doing that. */
2139 if (!detect_input_pending ())
2141 /* No timing error: wait for flag to be set. */
2143 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2144 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
2146 waiting_for_ast
= 0;
2149 /* The standard `sleep' routine works some other way
2150 and it stops working if you have ever quit out of it.
2151 This one continues to work. */
2157 static int zero
= 0;
2158 static int large
= -10000000;
2160 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2163 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2164 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
2183 croak ("request sigio");
2189 croak ("unrequest sigio");
2194 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2199 #ifndef SYSTEM_MALLOC
2206 /* Some systems that cannot dump also cannot implement these. */
2209 * Return the address of the start of the text segment prior to
2210 * doing an unexec. After unexec the return value is undefined.
2211 * See crt0.c for further explanation and _start.
2215 #if !(defined (__NetBSD__) && defined (__ELF__))
2216 #ifndef HAVE_TEXT_START
2221 return ((char *) TEXT_START
);
2225 return ((char *) csrt
);
2226 #else /* not GOULD */
2227 extern int _start ();
2228 return ((char *) _start
);
2230 #endif /* TEXT_START */
2232 #endif /* not HAVE_TEXT_START */
2236 * Return the address of the start of the data segment prior to
2237 * doing an unexec. After unexec the return value is undefined.
2238 * See crt0.c for further information and definition of data_start.
2240 * Apparently, on BSD systems this is etext at startup. On
2241 * USG systems (swapping) this is highly mmu dependent and
2242 * is also dependent on whether or not the program is running
2243 * with shared text. Generally there is a (possibly large)
2244 * gap between end of text and start of data with shared text.
2246 * On Uniplus+ systems with shared text, data starts at a
2247 * fixed address. Each port (from a given oem) is generally
2248 * different, and the specific value of the start of data can
2249 * be obtained via the UniPlus+ specific "uvar" system call,
2250 * however the method outlined in crt0.c seems to be more portable.
2252 * Probably what will have to happen when a USG unexec is available,
2253 * at least on UniPlus, is temacs will have to be made unshared so
2254 * that text and data are contiguous. Then once loadup is complete,
2255 * unexec will produce a shared executable where the data can be
2256 * at the normal shared text boundary and the startofdata variable
2257 * will be patched by unexec to the correct value.
2261 #ifndef start_of_data
2266 return ((char *) DATA_START
);
2268 #ifdef ORDINARY_LINK
2270 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2271 * data_start isn't defined. We take the address of environ, which
2272 * is known to live at or near the start of the system crt0.c, and
2273 * we don't sweat the handful of bytes that might lose.
2275 extern char **environ
;
2277 return ((char *) &environ
);
2279 extern int data_start
;
2280 return ((char *) &data_start
);
2281 #endif /* ORDINARY_LINK */
2282 #endif /* DATA_START */
2284 #endif /* start_of_data */
2285 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2287 /* init_system_name sets up the string for the Lisp function
2288 system-name to return. */
2294 extern Lisp_Object Vsystem_name
;
2299 #include <sys/socket.h>
2301 #endif /* HAVE_SOCKETS */
2302 #endif /* not VMS */
2303 #endif /* not BSD4_1 */
2306 #ifndef HAVE_H_ERRNO
2309 #endif /* TRY_AGAIN */
2315 Vsystem_name
= build_string (sysname
);
2319 if ((sp
= egetenv ("SYS$NODE")) == 0)
2320 Vsystem_name
= build_string ("vax-vms");
2321 else if ((end
= index (sp
, ':')) == 0)
2322 Vsystem_name
= build_string (sp
);
2324 Vsystem_name
= make_string (sp
, end
- sp
);
2326 #ifndef HAVE_GETHOSTNAME
2329 Vsystem_name
= build_string (uts
.nodename
);
2330 #else /* HAVE_GETHOSTNAME */
2331 unsigned int hostname_size
= 256;
2332 char *hostname
= (char *) alloca (hostname_size
);
2334 /* Try to get the host name; if the buffer is too short, try
2335 again. Apparently, the only indication gethostname gives of
2336 whether the buffer was large enough is the presence or absence
2337 of a '\0' in the string. Eech. */
2340 gethostname (hostname
, hostname_size
- 1);
2341 hostname
[hostname_size
- 1] = '\0';
2343 /* Was the buffer large enough for the '\0'? */
2344 if (strlen (hostname
) < hostname_size
- 1)
2347 hostname_size
<<= 1;
2348 hostname
= (char *) alloca (hostname_size
);
2351 /* Turn the hostname into the official, fully-qualified hostname.
2352 Don't do this if we're going to dump; this can confuse system
2353 libraries on some machines and make the dumped emacs core dump. */
2356 #endif /* not CANNOT_DUMP */
2357 if (! index (hostname
, '.'))
2361 for (count
= 0;; count
++)
2366 hp
= gethostbyname (hostname
);
2368 if (! (hp
== 0 && h_errno
== TRY_AGAIN
))
2373 Fsleep_for (make_number (1), Qnil
);
2377 char *fqdn
= (char *) hp
->h_name
;
2382 if (!index (fqdn
, '.'))
2384 /* We still don't have a fully qualified domain name.
2385 Try to find one in the list of alternate names */
2386 char **alias
= hp
->h_aliases
;
2387 while (*alias
&& !index (*alias
, '.'))
2394 /* Convert the host name to lower case. */
2395 /* Using ctype.h here would introduce a possible locale
2396 dependence that is probably wrong for hostnames. */
2400 if (*p
>= 'A' && *p
<= 'Z')
2407 #endif /* HAVE_SOCKETS */
2408 /* We used to try using getdomainname here,
2409 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2410 getdomainname gets the NIS/YP domain which often is not the same
2411 as in Internet domain name. */
2412 #if 0 /* Turned off because sysinfo is not really likely to return the
2413 correct Internet domain. */
2414 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2415 if (! index (hostname
, '.'))
2417 /* The hostname is not fully qualified. Append the domain name. */
2419 int hostlen
= strlen (hostname
);
2420 int domain_size
= 256;
2424 char *domain
= (char *) alloca (domain_size
+ 1);
2425 char *fqdn
= (char *) alloca (hostlen
+ 1 + domain_size
+ 1);
2426 int sys_domain_size
= sysinfo (SI_SRPC_DOMAIN
, domain
, domain_size
);
2427 if (sys_domain_size
<= 0)
2429 if (domain_size
< sys_domain_size
)
2431 domain_size
= sys_domain_size
;
2434 strcpy (fqdn
, hostname
);
2435 if (domain
[0] == '.')
2436 strcpy (fqdn
+ hostlen
, domain
);
2437 else if (domain
[0] != 0)
2439 fqdn
[hostlen
] = '.';
2440 strcpy (fqdn
+ hostlen
+ 1, domain
);
2446 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2448 Vsystem_name
= build_string (hostname
);
2449 #endif /* HAVE_GETHOSTNAME */
2454 for (p
= SDATA (Vsystem_name
); *p
; p
++)
2455 if (*p
== ' ' || *p
== '\t')
2462 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2464 #include "sysselect.h"
2467 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2468 /* Cause explanatory error message at compile time,
2469 since the select emulation is not good enough for X. */
2470 int *x
= &x_windows_lose_if_no_select_system_call
;
2473 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2474 * Only checks read descriptors.
2476 /* How long to wait between checking fds in select */
2477 #define SELECT_PAUSE 1
2480 /* For longjmp'ing back to read_input_waiting. */
2482 jmp_buf read_alarm_throw
;
2484 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2485 The read_socket_hook function sets this to 1 while it is waiting. */
2487 int read_alarm_should_throw
;
2495 #else /* not BSD4_1 */
2496 signal (SIGALRM
, SIG_IGN
);
2497 #endif /* not BSD4_1 */
2498 if (read_alarm_should_throw
)
2499 longjmp (read_alarm_throw
, 1);
2503 /* Only rfds are checked. */
2505 sys_select (nfds
, rfds
, wfds
, efds
, timeout
)
2507 SELECT_TYPE
*rfds
, *wfds
, *efds
;
2508 EMACS_TIME
*timeout
;
2514 extern int proc_buffered_char
[];
2515 #ifndef subprocesses
2516 int process_tick
= 0, update_tick
= 0;
2518 extern int process_tick
, update_tick
;
2522 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2523 /* If we're using X, then the native select will work; we only need the
2524 emulation for non-X usage. */
2525 if (!NILP (Vwindow_system
))
2526 return select (nfds
, rfds
, wfds
, efds
, timeout
);
2528 timeoutval
= timeout
? EMACS_SECS (*timeout
) : 100000;
2529 local_timeout
= &timeoutval
;
2541 /* If we are looking only for the terminal, with no timeout,
2542 just read it and wait -- that's more efficient. */
2543 if (*local_timeout
== 100000 && process_tick
== update_tick
2544 && FD_ISSET (0, &orfds
))
2547 for (fd
= 1; fd
< nfds
; ++fd
)
2548 if (FD_ISSET (fd
, &orfds
))
2550 if (! detect_input_pending ())
2551 read_input_waiting ();
2557 /* Once a second, till the timer expires, check all the flagged read
2558 * descriptors to see if any input is available. If there is some then
2559 * set the corresponding bit in the return copy of rfds.
2563 register int to_check
, fd
;
2567 for (to_check
= nfds
, fd
= 0; --to_check
>= 0; fd
++)
2569 if (FD_ISSET (fd
, &orfds
))
2571 int avail
= 0, status
= 0;
2574 avail
= detect_input_pending (); /* Special keyboard handler */
2578 status
= ioctl (fd
, FIONREAD
, &avail
);
2579 #else /* no FIONREAD */
2580 /* Hoping it will return -1 if nothing available
2581 or 0 if all 0 chars requested are read. */
2582 if (proc_buffered_char
[fd
] >= 0)
2586 avail
= read (fd
, &buf
, 1);
2588 proc_buffered_char
[fd
] = buf
;
2590 #endif /* no FIONREAD */
2592 if (status
>= 0 && avail
> 0)
2600 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2603 turn_on_atimers (0);
2604 signal (SIGALRM
, select_alarm
);
2606 alarm (SELECT_PAUSE
);
2608 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2609 while (select_alarmed
== 0 && *local_timeout
!= 0
2610 && process_tick
== update_tick
)
2612 /* If we are interested in terminal input,
2613 wait by reading the terminal.
2614 That makes instant wakeup for terminal input at least. */
2615 if (FD_ISSET (0, &orfds
))
2617 read_input_waiting ();
2618 if (detect_input_pending ())
2624 (*local_timeout
) -= SELECT_PAUSE
;
2626 /* Reset the old alarm if there was one. */
2627 turn_on_atimers (1);
2629 if (*local_timeout
== 0) /* Stop on timer being cleared */
2634 #endif /* not WINDOWSNT */
2636 /* Read keyboard input into the standard buffer,
2637 waiting for at least one character. */
2639 /* Make all keyboard buffers much bigger when using a window system. */
2640 #ifdef HAVE_WINDOW_SYSTEM
2641 #define BUFFER_SIZE_FACTOR 16
2643 #define BUFFER_SIZE_FACTOR 1
2647 read_input_waiting ()
2650 extern int quit_char
;
2652 if (read_socket_hook
)
2654 struct input_event buf
[256];
2655 for (i
= 0; i
< 256; i
++)
2656 EVENT_INIT (buf
[i
]);
2658 read_alarm_should_throw
= 0;
2659 if (! setjmp (read_alarm_throw
))
2660 nread
= (*read_socket_hook
) (0, buf
, 256, 1);
2664 /* Scan the chars for C-g and store them in kbd_buffer. */
2665 for (i
= 0; i
< nread
; i
++)
2667 kbd_buffer_store_event (&buf
[i
]);
2668 /* Don't look at input that follows a C-g too closely.
2669 This reduces lossage due to autorepeat on C-g. */
2670 if (buf
[i
].kind
== ASCII_KEYSTROKE_EVENT
2671 && buf
[i
].code
== quit_char
)
2677 struct input_event e
;
2679 nread
= read (fileno (stdin
), buf
, 1);
2682 /* Scan the chars for C-g and store them in kbd_buffer. */
2683 e
.kind
= ASCII_KEYSTROKE_EVENT
;
2684 e
.frame_or_window
= selected_frame
;
2686 for (i
= 0; i
< nread
; i
++)
2688 /* Convert chars > 0177 to meta events if desired.
2689 We do this under the same conditions that read_avail_input does. */
2690 if (read_socket_hook
== 0)
2692 /* If the user says she has a meta key, then believe her. */
2693 if (meta_key
== 1 && (buf
[i
] & 0x80))
2694 e
.modifiers
= meta_modifier
;
2699 XSETINT (e
.code
, buf
[i
]);
2700 kbd_buffer_store_event (&e
);
2701 /* Don't look at input that follows a C-g too closely.
2702 This reduces lossage due to autorepeat on C-g. */
2703 if (buf
[i
] == quit_char
)
2709 #endif /* not HAVE_SELECT */
2710 #endif /* not VMS */
2711 #endif /* not MSDOS */
2720 lmode
= LINTRUP
| lmode
;
2721 ioctl (fd
, TIOCLSET
, &lmode
);
2730 lmode
= ~LINTRUP
& lmode
;
2731 ioctl (fd
, TIOCLSET
, &lmode
);
2739 interrupts_deferred
= 0;
2747 interrupts_deferred
= 1;
2750 /* still inside #ifdef BSD4_1 */
2753 int sigheld
; /* Mask of held signals */
2759 sigheld
|= sigbit (signum
);
2767 sigheld
|= sigbit (signum
);
2774 sigheld
&= ~sigbit (signum
);
2779 sigfree () /* Free all held signals */
2782 for (i
= 0; i
< NSIG
; i
++)
2783 if (sigheld
& sigbit (i
))
2791 return 1 << (i
- 1);
2793 #endif /* subprocesses */
2796 /* POSIX signals support - DJB */
2797 /* Anyone with POSIX signals should have ANSI C declarations */
2799 #ifdef POSIX_SIGNALS
2801 sigset_t empty_mask
, full_mask
;
2804 sys_signal (int signal_number
, signal_handler_t action
)
2806 struct sigaction new_action
, old_action
;
2807 sigemptyset (&new_action
.sa_mask
);
2808 new_action
.sa_handler
= action
;
2809 #if defined (SA_RESTART) && ! defined (BROKEN_SA_RESTART)
2810 /* Emacs mostly works better with restartable system services. If this
2811 flag exists, we probably want to turn it on here.
2812 However, on some systems this resets the timeout of `select'
2813 which means that `select' never finishes if it keeps getting signals.
2814 BROKEN_SA_RESTART is defined on those systems. */
2815 new_action
.sa_flags
= SA_RESTART
;
2817 new_action
.sa_flags
= 0;
2819 sigaction (signal_number
, &new_action
, &old_action
);
2820 return (old_action
.sa_handler
);
2824 /* If we're compiling with GCC, we don't need this function, since it
2825 can be written as a macro. */
2827 sys_sigmask (int sig
)
2830 sigemptyset (&mask
);
2831 sigaddset (&mask
, sig
);
2836 /* I'd like to have these guys return pointers to the mask storage in here,
2837 but there'd be trouble if the code was saving multiple masks. I'll be
2838 safe and pass the structure. It normally won't be more than 2 bytes
2842 sys_sigblock (sigset_t new_mask
)
2845 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2850 sys_sigunblock (sigset_t new_mask
)
2853 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2858 sys_sigsetmask (sigset_t new_mask
)
2861 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2865 #endif /* POSIX_SIGNALS */
2867 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2868 static char *my_sys_siglist
[NSIG
];
2872 # define sys_siglist my_sys_siglist
2878 #ifdef POSIX_SIGNALS
2879 sigemptyset (&empty_mask
);
2880 sigfillset (&full_mask
);
2883 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2887 sys_siglist
[SIGABRT
] = "Aborted";
2890 sys_siglist
[SIGAIO
] = "LAN I/O interrupt";
2893 sys_siglist
[SIGALRM
] = "Alarm clock";
2896 sys_siglist
[SIGBUS
] = "Bus error";
2899 sys_siglist
[SIGCLD
] = "Child status changed";
2902 sys_siglist
[SIGCHLD
] = "Child status changed";
2905 sys_siglist
[SIGCONT
] = "Continued";
2908 sys_siglist
[SIGDANGER
] = "Swap space dangerously low";
2911 sys_siglist
[SIGDGNOTIFY
] = "Notification message in queue";
2914 sys_siglist
[SIGEMT
] = "Emulation trap";
2917 sys_siglist
[SIGFPE
] = "Arithmetic exception";
2920 sys_siglist
[SIGFREEZE
] = "SIGFREEZE";
2923 sys_siglist
[SIGGRANT
] = "Monitor mode granted";
2926 sys_siglist
[SIGHUP
] = "Hangup";
2929 sys_siglist
[SIGILL
] = "Illegal instruction";
2932 sys_siglist
[SIGINT
] = "Interrupt";
2935 sys_siglist
[SIGIO
] = "I/O possible";
2938 sys_siglist
[SIGIOINT
] = "I/O intervention required";
2941 sys_siglist
[SIGIOT
] = "IOT trap";
2944 sys_siglist
[SIGKILL
] = "Killed";
2947 sys_siglist
[SIGLOST
] = "Resource lost";
2950 sys_siglist
[SIGLWP
] = "SIGLWP";
2953 sys_siglist
[SIGMSG
] = "Monitor mode data available";
2956 sys_siglist
[SIGWIND
] = "SIGPHONE";
2959 sys_siglist
[SIGPIPE
] = "Broken pipe";
2962 sys_siglist
[SIGPOLL
] = "Pollable event occurred";
2965 sys_siglist
[SIGPROF
] = "Profiling timer expired";
2968 sys_siglist
[SIGPTY
] = "PTY I/O interrupt";
2971 sys_siglist
[SIGPWR
] = "Power-fail restart";
2974 sys_siglist
[SIGQUIT
] = "Quit";
2977 sys_siglist
[SIGRETRACT
] = "Need to relinguish monitor mode";
2980 sys_siglist
[SIGSAK
] = "Secure attention";
2983 sys_siglist
[SIGSEGV
] = "Segmentation violation";
2986 sys_siglist
[SIGSOUND
] = "Sound completed";
2989 sys_siglist
[SIGSTOP
] = "Stopped (signal)";
2992 sys_siglist
[SIGSTP
] = "Stopped (user)";
2995 sys_siglist
[SIGSYS
] = "Bad argument to system call";
2998 sys_siglist
[SIGTERM
] = "Terminated";
3001 sys_siglist
[SIGTHAW
] = "SIGTHAW";
3004 sys_siglist
[SIGTRAP
] = "Trace/breakpoint trap";
3007 sys_siglist
[SIGTSTP
] = "Stopped (user)";
3010 sys_siglist
[SIGTTIN
] = "Stopped (tty input)";
3013 sys_siglist
[SIGTTOU
] = "Stopped (tty output)";
3016 sys_siglist
[SIGURG
] = "Urgent I/O condition";
3019 sys_siglist
[SIGUSR1
] = "User defined signal 1";
3022 sys_siglist
[SIGUSR2
] = "User defined signal 2";
3025 sys_siglist
[SIGVTALRM
] = "Virtual timer expired";
3028 sys_siglist
[SIGWAITING
] = "Process's LWPs are blocked";
3031 sys_siglist
[SIGWINCH
] = "Window size changed";
3034 sys_siglist
[SIGWIND
] = "SIGWIND";
3037 sys_siglist
[SIGXCPU
] = "CPU time limit exceeded";
3040 sys_siglist
[SIGXFSZ
] = "File size limit exceeded";
3043 #endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
3052 /* Figure out how many bits the system's random number generator uses.
3053 `random' and `lrand48' are assumed to return 31 usable bits.
3054 BSD `rand' returns a 31 bit value but the low order bits are unusable;
3055 so we'll shift it and treat it like the 15-bit USG `rand'. */
3059 # define RAND_BITS 31
3060 # else /* !HAVE_RANDOM */
3061 # ifdef HAVE_LRAND48
3062 # define RAND_BITS 31
3063 # define random lrand48
3064 # else /* !HAVE_LRAND48 */
3065 # define RAND_BITS 15
3066 # if RAND_MAX == 32767
3067 # define random rand
3068 # else /* RAND_MAX != 32767 */
3069 # if RAND_MAX == 2147483647
3070 # define random() (rand () >> 16)
3071 # else /* RAND_MAX != 2147483647 */
3073 # define random rand
3075 # define random() (rand () >> 16)
3077 # endif /* RAND_MAX != 2147483647 */
3078 # endif /* RAND_MAX != 32767 */
3079 # endif /* !HAVE_LRAND48 */
3080 # endif /* !HAVE_RANDOM */
3081 #endif /* !RAND_BITS */
3088 srandom ((unsigned int)arg
);
3090 # ifdef HAVE_LRAND48
3093 srand ((unsigned int)arg
);
3099 * Build a full Emacs-sized word out of whatever we've got.
3100 * This suffices even for a 64-bit architecture with a 15-bit rand.
3105 long val
= random ();
3106 #if VALBITS > RAND_BITS
3107 val
= (val
<< RAND_BITS
) ^ random ();
3108 #if VALBITS > 2*RAND_BITS
3109 val
= (val
<< RAND_BITS
) ^ random ();
3110 #if VALBITS > 3*RAND_BITS
3111 val
= (val
<< RAND_BITS
) ^ random ();
3112 #if VALBITS > 4*RAND_BITS
3113 val
= (val
<< RAND_BITS
) ^ random ();
3114 #endif /* need at least 5 */
3115 #endif /* need at least 4 */
3116 #endif /* need at least 3 */
3117 #endif /* need at least 2 */
3118 return val
& ((1L << VALBITS
) - 1);
3121 #ifdef WRONG_NAME_INSQUE
3134 /* If any place else asks for the TERM variable,
3135 allow it to be overridden with the EMACS_TERM variable
3136 before attempting to translate the logical name TERM. As a last
3137 resort, ask for VAX C's special idea of the TERM variable. */
3144 static char buf
[256];
3145 static struct dsc$descriptor_s equiv
3146 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
3147 static struct dsc$descriptor_s d_name
3148 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
3151 if (!strcmp (name
, "TERM"))
3153 val
= (char *) getenv ("EMACS_TERM");
3158 d_name
.dsc$w_length
= strlen (name
);
3159 d_name
.dsc$a_pointer
= name
;
3160 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
3162 char *str
= (char *) xmalloc (eqlen
+ 1);
3163 bcopy (buf
, str
, eqlen
);
3165 /* This is a storage leak, but a pain to fix. With luck,
3166 no one will ever notice. */
3169 return (char *) getenv (name
);
3174 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
3175 to force a call on the debugger from within the image. */
3179 reset_all_sys_modes ();
3180 LIB$
SIGNAL (SS$_DEBUG
);
3186 #ifdef LINK_CRTL_SHARE
3187 #ifdef SHARABLE_LIB_BUG
3188 /* Variables declared noshare and initialized in sharable libraries
3189 cannot be shared. The VMS linker incorrectly forces you to use a private
3190 version which is uninitialized... If not for this "feature", we
3191 could use the C library definition of sys_nerr and sys_errlist. */
3193 char *sys_errlist
[] =
3197 "no such file or directory",
3199 "interrupted system call",
3201 "no such device or address",
3202 "argument list too long",
3203 "exec format error",
3206 "no more processes",
3207 "not enough memory",
3208 "permission denied",
3210 "block device required",
3211 "mount devices busy",
3213 "cross-device link",
3218 "file table overflow",
3219 "too many open files",
3223 "no space left on device",
3225 "read-only file system",
3231 "vax/vms specific error code nontranslatable error"
3233 #endif /* SHARABLE_LIB_BUG */
3234 #endif /* LINK_CRTL_SHARE */
3237 #ifndef HAVE_STRERROR
3243 extern char *sys_errlist
[];
3244 extern int sys_nerr
;
3246 if (errnum
>= 0 && errnum
< sys_nerr
)
3247 return sys_errlist
[errnum
];
3248 return (char *) "Unknown error";
3250 #endif /* not WINDOWSNT */
3251 #endif /* ! HAVE_STRERROR */
3254 emacs_open (path
, oflag
, mode
)
3258 register int rtnval
;
3261 if (oflag
& O_CREAT
)
3262 return creat (path
, mode
);
3265 while ((rtnval
= open (path
, oflag
, mode
)) == -1
3266 && (errno
== EINTR
));
3275 register int rtnval
;
3277 while ((rtnval
= close (fd
)) == -1
3278 && (errno
== EINTR
))
3281 /* If close is interrupted SunOS 4.1 may or may not have closed the
3282 file descriptor. If it did the second close will fail with
3283 errno = EBADF. That means we have succeeded. */
3284 if (rtnval
== -1 && did_retry
&& errno
== EBADF
)
3291 emacs_read (fildes
, buf
, nbyte
)
3296 register int rtnval
;
3298 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
3299 && (errno
== EINTR
));
3304 emacs_write (fildes
, buf
, nbyte
)
3309 register int rtnval
, bytes_written
;
3315 rtnval
= write (fildes
, buf
, nbyte
);
3322 return (bytes_written
? bytes_written
: -1);
3327 bytes_written
+= rtnval
;
3329 return (bytes_written
);
3334 * All of the following are for USG.
3336 * On USG systems the system calls are INTERRUPTIBLE by signals
3337 * that the user program has elected to catch. Thus the system call
3338 * must be retried in these cases. To handle this without massive
3339 * changes in the source code, we remap the standard system call names
3340 * to names for our own functions in sysdep.c that do the system call
3341 * with retries. Actually, for portability reasons, it is good
3342 * programming practice, as this example shows, to limit all actual
3343 * system calls to a single occurrence in the source. Sure, this
3344 * adds an extra level of function call overhead but it is almost
3345 * always negligible. Fred Fish, Unisoft Systems Inc.
3349 * Warning, this function may not duplicate 4.2 action properly
3350 * under error conditions.
3354 /* In 4.1, param.h fails to define this. */
3355 #define MAXPATHLEN 1024
3364 char *npath
, *spath
;
3365 extern char *getcwd ();
3367 BLOCK_INPUT
; /* getcwd uses malloc */
3368 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
3374 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3375 up to first slash. Should be harmless on other systems. */
3376 while (*npath
&& *npath
!= '/')
3378 strcpy (pathname
, npath
);
3379 free (spath
); /* getcwd uses malloc */
3384 #endif /* HAVE_GETWD */
3387 * Emulate rename using unlink/link. Note that this is
3388 * only partially correct. Also, doesn't enforce restriction
3389 * that files be of same type (regular->regular, dir->dir, etc).
3398 if (access (from
, 0) == 0)
3401 if (link (from
, to
) == 0)
3402 if (unlink (from
) == 0)
3414 /* HPUX curses library references perror, but as far as we know
3415 it won't be called. Anyway this definition will do for now. */
3421 #endif /* not HAVE_PERROR */
3427 * Emulate BSD dup2. First close newd if it already exists.
3428 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3429 * until we are, then close the unsuccessful ones.
3436 register int fd
, ret
;
3441 return fcntl (oldd
, F_DUPFD
, newd
);
3448 ret
= dup2 (old
,new);
3454 #endif /* not HAVE_DUP2 */
3457 * Gettimeofday. Simulate as much as possible. Only accurate
3458 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3459 * Only needed when subprocesses are defined.
3464 #ifndef HAVE_GETTIMEOFDAY
3469 gettimeofday (tp
, tzp
)
3471 struct timezone
*tzp
;
3473 extern long time ();
3475 tp
->tv_sec
= time ((long *)0);
3478 tzp
->tz_minuteswest
= -1;
3485 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3488 * This function will go away as soon as all the stubs fixed. (fnf)
3495 printf ("%s not yet implemented\r\n", badfunc
);
3496 reset_all_sys_modes ();
3502 /* Directory routines for systems that don't have them. */
3504 #ifdef SYSV_SYSTEM_DIR
3508 #if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
3512 register DIR *dirp
; /* stream from opendir */
3516 rtnval
= emacs_close (dirp
->dd_fd
);
3518 /* Some systems (like Solaris) allocate the buffer and the DIR all
3519 in one block. Why in the world are we freeing this ourselves
3521 #if ! (defined (sun) && defined (USG5_4))
3522 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
3524 xfree ((char *) dirp
);
3528 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3529 #endif /* SYSV_SYSTEM_DIR */
3531 #ifdef NONSYSTEM_DIR_LIBRARY
3535 char *filename
; /* name of directory */
3537 register DIR *dirp
; /* -> malloc'ed storage */
3538 register int fd
; /* file descriptor for read */
3539 struct stat sbuf
; /* result of fstat */
3541 fd
= emacs_open (filename
, O_RDONLY
, 0);
3546 if (fstat (fd
, &sbuf
) < 0
3547 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
3548 || (dirp
= (DIR *) xmalloc (sizeof (DIR))) == 0)
3552 return 0; /* bad luck today */
3557 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
3564 register DIR *dirp
; /* stream from opendir */
3566 emacs_close (dirp
->dd_fd
);
3567 xfree ((char *) dirp
);
3575 ino_t od_ino
; /* inode */
3576 char od_name
[DIRSIZ
]; /* filename */
3578 #endif /* not VMS */
3580 struct direct dir_static
; /* simulated directory contents */
3585 register DIR *dirp
; /* stream from opendir */
3588 register struct olddir
*dp
; /* -> directory data */
3590 register struct dir$_name
*dp
; /* -> directory data */
3591 register struct dir$_version
*dv
; /* -> version data */
3596 if (dirp
->dd_loc
>= dirp
->dd_size
)
3597 dirp
->dd_loc
= dirp
->dd_size
= 0;
3599 if (dirp
->dd_size
== 0 /* refill buffer */
3600 && (dirp
->dd_size
= emacs_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3604 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3605 dirp
->dd_loc
+= sizeof (struct olddir
);
3607 if (dp
->od_ino
!= 0) /* not deleted entry */
3609 dir_static
.d_ino
= dp
->od_ino
;
3610 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3611 dir_static
.d_name
[DIRSIZ
] = '\0';
3612 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3613 dir_static
.d_reclen
= sizeof (struct direct
)
3615 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3616 return &dir_static
; /* -> simulated structure */
3619 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3620 if (dirp
->dd_loc
== 0)
3621 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3622 : dp
->dir$b_namecount
;
3623 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3624 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3625 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3626 dir_static
.d_reclen
= sizeof (struct direct
)
3628 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3629 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3630 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3631 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3638 /* readdirver is just like readdir except it returns all versions of a file
3639 as separate entries. */
3644 register DIR *dirp
; /* stream from opendir */
3646 register struct dir$_name
*dp
; /* -> directory data */
3647 register struct dir$_version
*dv
; /* -> version data */
3649 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3650 dirp
->dd_loc
= dirp
->dd_size
= 0;
3652 if (dirp
->dd_size
== 0 /* refill buffer */
3653 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3656 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3657 if (dirp
->dd_loc
== 0)
3658 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3659 : dp
->dir$b_namecount
;
3660 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3661 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3662 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3663 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3664 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3665 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3666 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3667 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3673 #endif /* NONSYSTEM_DIR_LIBRARY */
3677 set_file_times (filename
, atime
, mtime
)
3678 const char *filename
;
3679 EMACS_TIME atime
, mtime
;
3682 struct timeval tv
[2];
3685 return utimes (filename
, tv
);
3686 #else /* not HAVE_UTIMES */
3688 utb
.actime
= EMACS_SECS (atime
);
3689 utb
.modtime
= EMACS_SECS (mtime
);
3690 return utime (filename
, &utb
);
3691 #endif /* not HAVE_UTIMES */
3694 /* mkdir and rmdir functions, for systems which don't have them. */
3698 * Written by Robert Rother, Mariah Corporation, August 1985.
3700 * If you want it, it's yours. All I ask in return is that if you
3701 * figure out how to do this in a Bourne Shell script you send me
3703 * sdcsvax!rmr or rmr@uscd
3705 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3706 * subroutine. 11Mar86; hoptoad!gnu
3708 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3709 * subroutine didn't return EEXIST. It does now.
3715 #ifdef MKDIR_PROTOTYPE
3719 mkdir (dpath
, dmode
)
3724 int cpid
, status
, fd
;
3725 struct stat statbuf
;
3727 if (stat (dpath
, &statbuf
) == 0)
3729 errno
= EEXIST
; /* Stat worked, so it already exists */
3733 /* If stat fails for a reason other than non-existence, return error */
3734 if (errno
!= ENOENT
)
3737 synch_process_alive
= 1;
3738 switch (cpid
= fork ())
3741 case -1: /* Error in fork */
3742 return (-1); /* Errno is set already */
3744 case 0: /* Child process */
3746 * Cheap hack to set mode of new directory. Since this
3747 * child process is going away anyway, we zap its umask.
3748 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3749 * directory. Does anybody care?
3751 status
= umask (0); /* Get current umask */
3752 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3753 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3760 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3761 _exit (-1); /* Can't exec /bin/mkdir */
3763 default: /* Parent process */
3764 wait_for_termination (cpid
);
3767 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3769 errno
= EIO
; /* We don't know why, but */
3770 return -1; /* /bin/mkdir failed */
3775 #endif /* not HAVE_MKDIR */
3782 int cpid
, status
, fd
;
3783 struct stat statbuf
;
3785 if (stat (dpath
, &statbuf
) != 0)
3787 /* Stat just set errno. We don't have to */
3791 synch_process_alive
= 1;
3792 switch (cpid
= fork ())
3795 case -1: /* Error in fork */
3796 return (-1); /* Errno is set already */
3798 case 0: /* Child process */
3799 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3806 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
3807 _exit (-1); /* Can't exec /bin/rmdir */
3809 default: /* Parent process */
3810 wait_for_termination (cpid
);
3813 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3815 errno
= EIO
; /* We don't know why, but */
3816 return -1; /* /bin/rmdir failed */
3821 #endif /* !HAVE_RMDIR */
3825 /* Functions for VMS */
3827 #include "vms-pwd.h"
3832 /* Return as a string the VMS error string pertaining to STATUS.
3833 Reuses the same static buffer each time it is called. */
3837 int status
; /* VMS status code */
3841 static char buf
[257];
3843 bufadr
[0] = sizeof buf
- 1;
3844 bufadr
[1] = (int) buf
;
3845 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3846 return "untranslatable VMS error status";
3854 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3855 * not work correctly. (It also doesn't work well in version 2.3.)
3860 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3861 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3865 unsigned short s_buflen
;
3866 unsigned short s_code
;
3868 unsigned short *s_retlenadr
;
3872 #define buflen s.s_buflen
3873 #define code s.s_code
3874 #define bufadr s.s_bufadr
3875 #define retlenadr s.s_retlenadr
3877 #define R_OK 4 /* test for read permission */
3878 #define W_OK 2 /* test for write permission */
3879 #define X_OK 1 /* test for execute (search) permission */
3880 #define F_OK 0 /* test for presence of file */
3883 sys_access (path
, mode
)
3887 static char *user
= NULL
;
3890 /* translate possible directory spec into .DIR file name, so brain-dead
3891 * access can treat the directory like a file. */
3892 if (directory_file_name (path
, dir_fn
))
3896 return access (path
, mode
);
3897 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3903 unsigned short int dummy
;
3905 static int constant
= ACL$C_FILE
;
3906 DESCRIPTOR (path_desc
, path
);
3907 DESCRIPTOR (user_desc
, user
);
3911 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3914 acces
|= CHP$M_READ
;
3916 acces
|= CHP$M_WRITE
;
3917 itemlst
[0].buflen
= sizeof (int);
3918 itemlst
[0].code
= CHP$_FLAGS
;
3919 itemlst
[0].bufadr
= (char *) &flags
;
3920 itemlst
[0].retlenadr
= &dummy
;
3921 itemlst
[1].buflen
= sizeof (int);
3922 itemlst
[1].code
= CHP$_ACCESS
;
3923 itemlst
[1].bufadr
= (char *) &acces
;
3924 itemlst
[1].retlenadr
= &dummy
;
3925 itemlst
[2].end
= CHP$_END
;
3926 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3927 return stat
== SS$_NORMAL
? 0 : -1;
3931 #else /* not VMS4_4 */
3934 #define ACE$M_WRITE 2
3935 #define ACE$C_KEYID 1
3937 static unsigned short memid
, grpid
;
3938 static unsigned int uic
;
3940 /* Called from init_sys_modes, so it happens not very often
3941 but at least each time Emacs is loaded. */
3943 sys_access_reinit ()
3949 sys_access (filename
, type
)
3955 int status
, size
, i
, typecode
, acl_controlled
;
3956 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3957 union prvdef prvmask
;
3959 /* Get UIC and GRP values for protection checking. */
3962 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3965 memid
= uic
& 0xFFFF;
3969 if (type
!= 2) /* not checking write access */
3970 return access (filename
, type
);
3972 /* Check write protection. */
3974 #define CHECKPRIV(bit) (prvmask.bit)
3975 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3977 /* Find privilege bits */
3978 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3980 error ("Unable to find privileges: %s", vmserrstr (status
));
3981 if (CHECKPRIV (PRV$V_BYPASS
))
3982 return 0; /* BYPASS enabled */
3984 fab
.fab$b_fac
= FAB$M_GET
;
3985 fab
.fab$l_fna
= filename
;
3986 fab
.fab$b_fns
= strlen (filename
);
3987 fab
.fab$l_xab
= &xab
;
3988 xab
= cc$rms_xabpro
;
3989 xab
.xab$l_aclbuf
= aclbuf
;
3990 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3991 status
= SYS$
OPEN (&fab
, 0, 0);
3994 SYS$
CLOSE (&fab
, 0, 0);
3995 /* Check system access */
3996 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITABLE (XAB$V_SYS
))
3998 /* Check ACL entries, if any */
4000 if (xab
.xab$w_acllen
> 0)
4003 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
4004 while (*aclptr
&& aclptr
< aclend
)
4006 size
= (*aclptr
& 0xff) / 4;
4007 typecode
= (*aclptr
>> 8) & 0xff;
4008 if (typecode
== ACE$C_KEYID
)
4009 for (i
= size
- 1; i
> 1; i
--)
4010 if (aclptr
[i
] == uic
)
4013 if (aclptr
[1] & ACE$M_WRITE
)
4014 return 0; /* Write access through ACL */
4016 aclptr
= &aclptr
[size
];
4018 if (acl_controlled
) /* ACL specified, prohibits write access */
4021 /* No ACL entries specified, check normal protection */
4022 if (WRITABLE (XAB$V_WLD
)) /* World writable */
4024 if (WRITABLE (XAB$V_GRP
) &&
4025 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
4026 return 0; /* Group writable */
4027 if (WRITABLE (XAB$V_OWN
) &&
4028 (xab
.xab$l_uic
& 0xFFFF) == memid
)
4029 return 0; /* Owner writable */
4031 return -1; /* Not writable */
4033 #endif /* not VMS4_4 */
4036 static char vtbuf
[NAM$C_MAXRSS
+1];
4038 /* translate a vms file spec to a unix path */
4040 sys_translate_vms (vfile
)
4051 /* leading device or logical name is a root directory */
4052 if (p
= strchr (vfile
, ':'))
4061 if (*p
== '[' || *p
== '<')
4063 while (*++vfile
!= *p
+ 2)
4067 if (vfile
[-1] == *p
)
4090 static char utbuf
[NAM$C_MAXRSS
+1];
4092 /* translate a unix path to a VMS file spec */
4094 sys_translate_unix (ufile
)
4117 if (index (&ufile
[1], '/'))
4124 if (index (&ufile
[1], '/'))
4131 if (strncmp (ufile
, "./", 2) == 0)
4138 ufile
++; /* skip the dot */
4139 if (index (&ufile
[1], '/'))
4144 else if (strncmp (ufile
, "../", 3) == 0)
4152 ufile
+= 2; /* skip the dots */
4153 if (index (&ufile
[1], '/'))
4178 extern char *getcwd ();
4180 #define MAXPATHLEN 1024
4182 ptr
= xmalloc (MAXPATHLEN
);
4183 val
= getcwd (ptr
, MAXPATHLEN
);
4189 strcpy (pathname
, ptr
);
4198 long item_code
= JPI$_OWNER
;
4199 unsigned long parent_id
;
4202 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
4205 vaxc$errno
= status
;
4215 return (getgid () << 16) | getuid ();
4220 sys_read (fildes
, buf
, nbyte
)
4225 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
4230 sys_write (fildes
, buf
, nbyte
)
4235 register int nwrote
, rtnval
= 0;
4237 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
4243 return rtnval
? rtnval
: -1;
4244 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
4245 return rtnval
? rtnval
: -1;
4246 return (rtnval
+ nwrote
);
4251 * VAX/VMS VAX C RTL really loses. It insists that records
4252 * end with a newline (carriage return) character, and if they
4253 * don't it adds one (nice of it isn't it!)
4255 * Thus we do this stupidity below.
4260 sys_write (fildes
, buf
, nbytes
)
4263 unsigned int nbytes
;
4270 fstat (fildes
, &st
);
4276 /* Handle fixed-length files with carriage control. */
4277 if (st
.st_fab_rfm
== FAB$C_FIX
4278 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
4280 len
= st
.st_fab_mrs
;
4281 retval
= write (fildes
, p
, min (len
, nbytes
));
4284 retval
++; /* This skips the implied carriage control */
4288 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4289 while (*e
!= '\n' && e
> p
) e
--;
4290 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
4291 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4293 retval
= write (fildes
, p
, len
);
4304 /* Create file NEW copying its attributes from file OLD. If
4305 OLD is 0 or does not exist, create based on the value of
4308 /* Protection value the file should ultimately have.
4309 Set by create_copy_attrs, and use by rename_sansversions. */
4310 static unsigned short int fab_final_pro
;
4313 creat_copy_attrs (old
, new)
4316 struct FAB fab
= cc$rms_fab
;
4317 struct XABPRO xabpro
;
4318 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
4319 extern int vms_stmlf_recfm
;
4323 fab
.fab$b_fac
= FAB$M_GET
;
4324 fab
.fab$l_fna
= old
;
4325 fab
.fab$b_fns
= strlen (old
);
4326 fab
.fab$l_xab
= (char *) &xabpro
;
4327 xabpro
= cc$rms_xabpro
;
4328 xabpro
.xab$l_aclbuf
= aclbuf
;
4329 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
4330 /* Call $OPEN to fill in the fab & xabpro fields. */
4331 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4333 SYS$
CLOSE (&fab
, 0, 0);
4334 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
4335 if (xabpro
.xab$w_acllen
> 0)
4337 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
4338 /* If the acl buffer was too short, redo open with longer one.
4339 Wouldn't need to do this if there were some system imposed
4340 limit on the size of an ACL, but I can't find any such. */
4342 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
4343 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
4344 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4345 SYS$
CLOSE (&fab
, 0, 0);
4351 xabpro
.xab$l_aclbuf
= 0;
4356 fab
.fab$l_fna
= new;
4357 fab
.fab$b_fns
= strlen (new);
4361 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
4362 fab
.fab$b_rat
= FAB$M_CR
;
4365 /* Set the file protections such that we will be able to manipulate
4366 this file. Once we are done writing and renaming it, we will set
4367 the protections back. */
4369 fab_final_pro
= xabpro
.xab$w_pro
;
4371 SYS$
SETDFPROT (0, &fab_final_pro
);
4372 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
4374 /* Create the new file with either default attrs or attrs copied
4376 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
4378 SYS$
CLOSE (&fab
, 0, 0);
4379 /* As this is a "replacement" for creat, return a file descriptor
4380 opened for writing. */
4381 return open (new, O_WRONLY
);
4386 #include <varargs.h>
4389 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4394 sys_creat (va_alist
)
4397 va_list list_incrementer
;
4400 int rfd
; /* related file descriptor */
4401 int fd
; /* Our new file descriptor */
4408 extern int vms_stmlf_recfm
;
4411 va_start (list_incrementer
);
4412 name
= va_arg (list_incrementer
, char *);
4413 mode
= va_arg (list_incrementer
, int);
4415 rfd
= va_arg (list_incrementer
, int);
4416 va_end (list_incrementer
);
4419 /* Use information from the related file descriptor to set record
4420 format of the newly created file. */
4421 fstat (rfd
, &st_buf
);
4422 switch (st_buf
.st_fab_rfm
)
4425 strcpy (rfm
, "rfm = fix");
4426 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
4427 strcpy (rat
, "rat = ");
4428 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4430 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4431 strcat (rat
, "ftn");
4432 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4433 strcat (rat
, "prn");
4434 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4435 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4436 strcat (rat
, ", blk");
4438 strcat (rat
, "blk");
4439 return creat (name
, 0, rfm
, rat
, mrs
);
4442 strcpy (rfm
, "rfm = vfc");
4443 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
4444 strcpy (rat
, "rat = ");
4445 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4447 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4448 strcat (rat
, "ftn");
4449 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4450 strcat (rat
, "prn");
4451 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4452 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4453 strcat (rat
, ", blk");
4455 strcat (rat
, "blk");
4456 return creat (name
, 0, rfm
, rat
, fsz
);
4459 strcpy (rfm
, "rfm = stm");
4463 strcpy (rfm
, "rfm = stmcr");
4467 strcpy (rfm
, "rfm = stmlf");
4471 strcpy (rfm
, "rfm = udf");
4475 strcpy (rfm
, "rfm = var");
4478 strcpy (rat
, "rat = ");
4479 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4481 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4482 strcat (rat
, "ftn");
4483 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4484 strcat (rat
, "prn");
4485 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4486 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4487 strcat (rat
, ", blk");
4489 strcat (rat
, "blk");
4493 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
4494 strcpy (rat
, "rat=cr");
4496 /* Until the VAX C RTL fixes the many bugs with modes, always use
4497 mode 0 to get the user's default protection. */
4498 fd
= creat (name
, 0, rfm
, rat
);
4499 if (fd
< 0 && errno
== EEXIST
)
4501 if (unlink (name
) < 0)
4502 report_file_error ("delete", build_string (name
));
4503 fd
= creat (name
, 0, rfm
, rat
);
4509 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4511 sys_fwrite (ptr
, size
, num
, fp
)
4512 register char * ptr
;
4515 register int tot
= num
* size
;
4523 * The VMS C library routine creat actually creates a new version of an
4524 * existing file rather than truncating the old version. There are times
4525 * when this is not the desired behavior, for instance, when writing an
4526 * auto save file (you only want one version), or when you don't have
4527 * write permission in the directory containing the file (but the file
4528 * itself is writable). Hence this routine, which is equivalent to
4529 * "close (creat (fn, 0));" on Unix if fn already exists.
4535 struct FAB xfab
= cc$rms_fab
;
4536 struct RAB xrab
= cc$rms_rab
;
4539 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
4540 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
4541 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
4542 xfab
.fab$l_fna
= fn
;
4543 xfab
.fab$b_fns
= strlen (fn
);
4544 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
4546 xrab
.rab$l_fab
= &xfab
;
4548 /* This gibberish opens the file, positions to the first record, and
4549 deletes all records from there until the end of file. */
4550 if ((SYS$
OPEN (&xfab
) & 01) == 01)
4552 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
4553 (SYS$
FIND (&xrab
) & 01) == 01 &&
4554 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
4565 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4566 SYSPRV or a readable SYSUAF.DAT. */
4572 * Routine to read the VMS User Authorization File and return
4573 * a specific user's record.
4576 static struct UAF retuaf
;
4579 get_uaf_name (uname
)
4586 uaf_fab
= cc$rms_fab
;
4587 uaf_rab
= cc$rms_rab
;
4588 /* initialize fab fields */
4589 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4590 uaf_fab
.fab$b_fns
= 21;
4591 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4592 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4593 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4594 /* initialize rab fields */
4595 uaf_rab
.rab$l_fab
= &uaf_fab
;
4596 /* open the User Authorization File */
4597 status
= SYS$
OPEN (&uaf_fab
);
4601 vaxc$errno
= status
;
4604 status
= SYS$
CONNECT (&uaf_rab
);
4608 vaxc$errno
= status
;
4611 /* read the requested record - index is in uname */
4612 uaf_rab
.rab$l_kbf
= uname
;
4613 uaf_rab
.rab$b_ksz
= strlen (uname
);
4614 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4615 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4616 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4617 status
= SYS$
GET (&uaf_rab
);
4621 vaxc$errno
= status
;
4624 /* close the User Authorization File */
4625 status
= SYS$
DISCONNECT (&uaf_rab
);
4629 vaxc$errno
= status
;
4632 status
= SYS$
CLOSE (&uaf_fab
);
4636 vaxc$errno
= status
;
4650 uaf_fab
= cc$rms_fab
;
4651 uaf_rab
= cc$rms_rab
;
4652 /* initialize fab fields */
4653 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4654 uaf_fab
.fab$b_fns
= 21;
4655 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4656 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4657 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4658 /* initialize rab fields */
4659 uaf_rab
.rab$l_fab
= &uaf_fab
;
4660 /* open the User Authorization File */
4661 status
= SYS$
OPEN (&uaf_fab
);
4665 vaxc$errno
= status
;
4668 status
= SYS$
CONNECT (&uaf_rab
);
4672 vaxc$errno
= status
;
4675 /* read the requested record - index is in uic */
4676 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4677 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4678 uaf_rab
.rab$b_ksz
= sizeof uic
;
4679 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4680 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4681 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4682 status
= SYS$
GET (&uaf_rab
);
4686 vaxc$errno
= status
;
4689 /* close the User Authorization File */
4690 status
= SYS$
DISCONNECT (&uaf_rab
);
4694 vaxc$errno
= status
;
4697 status
= SYS$
CLOSE (&uaf_fab
);
4701 vaxc$errno
= status
;
4707 static struct passwd retpw
;
4715 /* copy these out first because if the username is 32 chars, the next
4716 section will overwrite the first byte of the UIC */
4717 retpw
.pw_uid
= up
->uaf$w_mem
;
4718 retpw
.pw_gid
= up
->uaf$w_grp
;
4720 /* I suppose this is not the best style, to possibly overwrite one
4721 byte beyond the end of the field, but what the heck... */
4722 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4723 while (ptr
[-1] == ' ')
4726 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4728 /* the rest of these are counted ascii strings */
4729 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4730 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4731 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4732 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4733 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4734 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4735 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4736 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4740 #else /* not READ_SYSUAF */
4741 static struct passwd retpw
;
4742 #endif /* not READ_SYSUAF */
4753 unsigned char * full
;
4754 #endif /* READ_SYSUAF */
4759 if ('a' <= *ptr
&& *ptr
<= 'z')
4764 if (!(up
= get_uaf_name (name
)))
4766 return cnv_uaf_pw (up
);
4768 if (strcmp (name
, getenv ("USER")) == 0)
4770 retpw
.pw_uid
= getuid ();
4771 retpw
.pw_gid
= getgid ();
4772 strcpy (retpw
.pw_name
, name
);
4773 if (full
= egetenv ("FULLNAME"))
4774 strcpy (retpw
.pw_gecos
, full
);
4776 *retpw
.pw_gecos
= '\0';
4777 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4778 *retpw
.pw_shell
= '\0';
4783 #endif /* not READ_SYSUAF */
4793 if (!(up
= get_uaf_uic (uid
)))
4795 return cnv_uaf_pw (up
);
4797 if (uid
== sys_getuid ())
4798 return getpwnam (egetenv ("USER"));
4801 #endif /* not READ_SYSUAF */
4804 /* return total address space available to the current process. This is
4805 the sum of the current p0 size, p1 size and free page table entries
4811 unsigned long free_pages
;
4812 unsigned long frep0va
;
4813 unsigned long frep1va
;
4816 item_code
= JPI$_FREPTECNT
;
4817 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4820 vaxc$errno
= status
;
4825 item_code
= JPI$_FREP0VA
;
4826 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4829 vaxc$errno
= status
;
4832 item_code
= JPI$_FREP1VA
;
4833 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4836 vaxc$errno
= status
;
4840 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4844 define_logical_name (varname
, string
)
4848 struct dsc$descriptor_s strdsc
=
4849 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4850 struct dsc$descriptor_s envdsc
=
4851 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4852 struct dsc$descriptor_s lnmdsc
=
4853 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4855 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4859 delete_logical_name (varname
)
4862 struct dsc$descriptor_s envdsc
=
4863 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4864 struct dsc$descriptor_s lnmdsc
=
4865 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4867 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4885 error ("execvp system call not implemented");
4894 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4895 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4896 char from_esn
[NAM$C_MAXRSS
];
4897 char to_esn
[NAM$C_MAXRSS
];
4899 from_fab
.fab$l_fna
= from
;
4900 from_fab
.fab$b_fns
= strlen (from
);
4901 from_fab
.fab$l_nam
= &from_nam
;
4902 from_fab
.fab$l_fop
= FAB$M_NAM
;
4904 from_nam
.nam$l_esa
= from_esn
;
4905 from_nam
.nam$b_ess
= sizeof from_esn
;
4907 to_fab
.fab$l_fna
= to
;
4908 to_fab
.fab$b_fns
= strlen (to
);
4909 to_fab
.fab$l_nam
= &to_nam
;
4910 to_fab
.fab$l_fop
= FAB$M_NAM
;
4912 to_nam
.nam$l_esa
= to_esn
;
4913 to_nam
.nam$b_ess
= sizeof to_esn
;
4915 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4921 if (status
== RMS$_DEV
)
4925 vaxc$errno
= status
;
4930 /* This function renames a file like `rename', but it strips
4931 the version number from the "to" filename, such that the "to" file is
4932 will always be a new version. It also sets the file protection once it is
4933 finished. The protection that we will use is stored in fab_final_pro,
4934 and was set when we did a creat_copy_attrs to create the file that we
4937 We could use the chmod function, but Eunichs uses 3 bits per user category
4938 to describe the protection, and VMS uses 4 (write and delete are separate
4939 bits). To maintain portability, the VMS implementation of `chmod' wires
4940 the W and D bits together. */
4943 static struct fibdef fib
; /* We need this initialized to zero */
4944 char vms_file_written
[NAM$C_MAXRSS
];
4947 rename_sans_version (from
,to
)
4954 struct FAB to_fab
= cc$rms_fab
;
4955 struct NAM to_nam
= cc$rms_nam
;
4956 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4957 struct dsc$descriptor fib_attr
[2]
4958 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4959 char to_esn
[NAM$C_MAXRSS
];
4961 $
DESCRIPTOR (disk
,to_esn
);
4963 to_fab
.fab$l_fna
= to
;
4964 to_fab
.fab$b_fns
= strlen (to
);
4965 to_fab
.fab$l_nam
= &to_nam
;
4966 to_fab
.fab$l_fop
= FAB$M_NAM
;
4968 to_nam
.nam$l_esa
= to_esn
;
4969 to_nam
.nam$b_ess
= sizeof to_esn
;
4971 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4973 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4974 *(to_nam
.nam$l_ver
) = '\0';
4976 stat
= rename (from
, to_esn
);
4980 strcpy (vms_file_written
, to_esn
);
4982 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4983 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4985 /* Now set the file protection to the correct value */
4986 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4988 /* Copy these fields into the fib */
4989 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4990 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4991 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4993 SYS$
CLOSE (&to_fab
, 0, 0);
4995 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4998 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4999 0, 0, 0, &fib_attr
, 0);
5002 stat
= SYS$
DASSGN (chan
);
5005 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
5016 unsigned short fid
[3];
5017 char esa
[NAM$C_MAXRSS
];
5020 fab
.fab$l_fop
= FAB$M_OFP
;
5021 fab
.fab$l_fna
= file
;
5022 fab
.fab$b_fns
= strlen (file
);
5023 fab
.fab$l_nam
= &nam
;
5026 nam
.nam$l_esa
= esa
;
5027 nam
.nam$b_ess
= NAM$C_MAXRSS
;
5029 status
= SYS$
PARSE (&fab
);
5030 if ((status
& 1) == 0)
5033 vaxc$errno
= status
;
5036 status
= SYS$
SEARCH (&fab
);
5037 if ((status
& 1) == 0)
5040 vaxc$errno
= status
;
5044 fid
[0] = nam
.nam$w_fid
[0];
5045 fid
[1] = nam
.nam$w_fid
[1];
5046 fid
[2] = nam
.nam$w_fid
[2];
5048 fab
.fab$l_fna
= new;
5049 fab
.fab$b_fns
= strlen (new);
5051 status
= SYS$
PARSE (&fab
);
5052 if ((status
& 1) == 0)
5055 vaxc$errno
= status
;
5059 nam
.nam$w_fid
[0] = fid
[0];
5060 nam
.nam$w_fid
[1] = fid
[1];
5061 nam
.nam$w_fid
[2] = fid
[2];
5063 nam
.nam$l_esa
= nam
.nam$l_name
;
5064 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
5066 status
= SYS$
ENTER (&fab
);
5067 if ((status
& 1) == 0)
5070 vaxc$errno
= status
;
5081 printf ("%s not yet implemented\r\n", badfunc
);
5082 reset_all_sys_modes ();
5089 /* Arrange to return a range centered on zero. */
5090 return rand () - (1 << 30);
5102 /* Called from init_sys_modes. */
5104 hft_init (struct tty_output
*tty_out
)
5108 /* If we're not on an HFT we shouldn't do any of this. We determine
5109 if we are on an HFT by trying to get an HFT error code. If this
5110 call fails, we're not on an HFT. */
5112 if (ioctl (0, HFQERROR
, &junk
) < 0)
5114 #else /* not IBMR2AIX */
5115 if (ioctl (0, HFQEIO
, 0) < 0)
5117 #endif /* not IBMR2AIX */
5119 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5120 as the rubout key's ASCII code. Here this is changed. The bug is that
5121 there's no way to determine the old mapping, so in reset_sys_modes
5122 we need to assume that the normal map had been present. Of course, this
5123 code also doesn't help if on a terminal emulator which doesn't understand
5127 struct hfkeymap keymap
;
5129 buf
.hf_bufp
= (char *)&keymap
;
5130 buf
.hf_buflen
= sizeof (keymap
);
5131 keymap
.hf_nkeys
= 2;
5132 keymap
.hfkey
[0].hf_kpos
= 15;
5133 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5135 keymap
.hfkey
[0].hf_keyidh
= '<';
5136 #else /* not IBMR2AIX */
5137 keymap
.hfkey
[0].hf_page
= '<';
5138 #endif /* not IBMR2AIX */
5139 keymap
.hfkey
[0].hf_char
= 127;
5140 keymap
.hfkey
[1].hf_kpos
= 15;
5141 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5143 keymap
.hfkey
[1].hf_keyidh
= '<';
5144 #else /* not IBMR2AIX */
5145 keymap
.hfkey
[1].hf_page
= '<';
5146 #endif /* not IBMR2AIX */
5147 keymap
.hfkey
[1].hf_char
= 127;
5148 hftctl (0, HFSKBD
, &buf
);
5150 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
5152 TTY_LINE_INS_DEL_OK (tty_out
) = 0;
5153 TTY_CHAR_INS_DEL_OK (tty_out
) = 0;
5156 /* Reset the rubout key to backspace. */
5159 hft_reset (struct tty_output
*tty_out
)
5162 struct hfkeymap keymap
;
5166 if (ioctl (0, HFQERROR
, &junk
) < 0)
5168 #else /* not IBMR2AIX */
5169 if (ioctl (0, HFQEIO
, 0) < 0)
5171 #endif /* not IBMR2AIX */
5173 buf
.hf_bufp
= (char *)&keymap
;
5174 buf
.hf_buflen
= sizeof (keymap
);
5175 keymap
.hf_nkeys
= 2;
5176 keymap
.hfkey
[0].hf_kpos
= 15;
5177 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5179 keymap
.hfkey
[0].hf_keyidh
= '<';
5180 #else /* not IBMR2AIX */
5181 keymap
.hfkey
[0].hf_page
= '<';
5182 #endif /* not IBMR2AIX */
5183 keymap
.hfkey
[0].hf_char
= 8;
5184 keymap
.hfkey
[1].hf_kpos
= 15;
5185 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5187 keymap
.hfkey
[1].hf_keyidh
= '<';
5188 #else /* not IBMR2AIX */
5189 keymap
.hfkey
[1].hf_page
= '<';
5190 #endif /* not IBMR2AIX */
5191 keymap
.hfkey
[1].hf_char
= 8;
5192 hftctl (0, HFSKBD
, &buf
);
5199 /* These are included on Sunos 4.1 when we do not use shared libraries.
5200 X11 libraries may refer to these functions but (we hope) do not
5201 actually call them. */
5221 #endif /* USE_DL_STUBS */
5230 register int length
;
5234 long max_str
= 65535;
5236 while (length
> max_str
) {
5237 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5242 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5244 while (length
-- > 0)
5246 #endif /* not VMS */
5249 #endif /* no bzero */
5250 #endif /* BSTRING */
5252 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5255 /* Saying `void' requires a declaration, above, where bcopy is used
5256 and that declaration causes pain for systems where bcopy is a macro. */
5257 bcopy (b1
, b2
, length
)
5260 register int length
;
5263 long max_str
= 65535;
5265 while (length
> max_str
) {
5266 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
5272 (void) LIB$
MOVC3 (&length
, b1
, b2
);
5274 while (length
-- > 0)
5276 #endif /* not VMS */
5278 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5283 bcmp (b1
, b2
, length
) /* This could be a macro! */
5286 register int length
;
5289 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
5290 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
5292 return STR$
COMPARE (&src1
, &src2
);
5294 while (length
-- > 0)
5299 #endif /* not VMS */
5301 #endif /* no bcmp */
5302 #endif /* not BSTRING */
5304 #ifndef HAVE_STRSIGNAL
5311 if (0 <= code
&& code
< NSIG
)
5314 signame
= sys_errlist
[code
];
5316 /* Cast to suppress warning if the table has const char *. */
5317 signame
= (char *) sys_siglist
[code
];
5323 #endif /* HAVE_STRSIGNAL */
5325 /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
5326 (do not change this comment) */