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 "sysselect.h"
50 #include "blockinput.h"
54 /* It is essential to include stdlib.h so that this file picks up
55 the correct definitions of rand, srand, and RAND_MAX.
56 Otherwise random numbers will not work correctly. */
60 /* Nonzero means delete a process right away if it exits (process.c). */
61 static int delete_exited_processes
;
67 #define write sys_write
72 #endif /* not WINDOWSNT */
78 /* Does anyone other than VMS need this? */
80 #define sys_fwrite fwrite
86 #include <sys/types.h>
91 #if !defined (USG) || defined (BSD_PGRPS)
93 #define setpgrp setpgid
97 /* Get SI_SRPC_DOMAIN, if it is available. */
98 #ifdef HAVE_SYS_SYSTEMINFO_H
99 #include <sys/systeminfo.h>
102 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
106 #include <sys/param.h>
110 extern unsigned start
__asm__ ("start");
132 #include <sys/file.h>
140 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
144 #include <sys/file.h>
152 #include <sys/ioctl.h>
158 #ifdef BROKEN_TIOCGWINSZ
163 #if defined (USG) || defined (DGUX)
164 #include <sys/utsname.h>
165 #ifndef MEMORY_IN_STRING_H
168 #if defined (TIOCGWINSZ) || defined (ISC4_0)
170 #include <sys/sioctl.h>
173 #include <sys/stream.h>
174 #include <sys/ptem.h>
176 #endif /* TIOCGWINSZ or ISC4_0 */
177 #endif /* USG or DGUX */
179 extern int quit_char
;
181 #include "keyboard.h"
184 #include "termhooks.h"
185 #include "termchar.h"
186 #include "termopts.h"
187 #include "dispextern.h"
189 #include "cm.h" /* for reset_sys_modes */
193 /* In process.h which conflicts with the local copy. */
195 int _CRTAPI1
_spawnlp (int, const char *, const char *, ...);
196 int _CRTAPI1
_getpid (void);
199 #ifdef NONSYSTEM_DIR_LIBRARY
201 #endif /* NONSYSTEM_DIR_LIBRARY */
203 #include "syssignal.h"
210 #ifndef HAVE_STRUCT_UTIMBUF
211 /* We want to use utime rather than utimes, but we couldn't find the
212 structure declaration. We'll use the traditional one. */
220 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
226 #define LNOFLSH 0100000
229 static int baud_convert
[] =
234 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
235 1800, 2400, 4800, 9600, 19200, 38400
242 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
244 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
252 void croak
P_ ((char *));
255 void hft_init
P_ ((struct tty_display_info
*));
256 void hft_reset
P_ ((struct tty_display_info
*));
259 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
261 SIGMASKTYPE sigprocmask_set
;
264 /* Discard pending input on all input descriptors. */
270 struct emacs_tty buf
;
277 SYS$
QIOW (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
278 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
283 struct tty_display_info
*tty
;
284 for (tty
= tty_list
; tty
; tty
= tty
->next
)
287 ioctl (fileno (TTY_INPUT (tty
)), TIOCFLUSH
, &zero
);
290 #else /* not Apollo */
291 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
292 while (dos_keyread () != -1)
294 #else /* not MSDOS */
296 struct tty_display_info
*tty
;
297 for (tty
= tty_list
; tty
; tty
= tty
->next
)
299 EMACS_GET_TTY (fileno (TTY_INPUT (tty
)), &buf
);
300 EMACS_SET_TTY (fileno (TTY_INPUT (tty
)), &buf
, 0);
303 #endif /* not MSDOS */
304 #endif /* not Apollo */
306 #endif /* not WINDOWSNT */
312 /* Arrange for character C to be read as the next input from
314 XXX What if we have multiple ttys?
320 if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
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 (int fd
)
340 #ifdef INIT_BAUD_RATE
345 #else /* not DOS_NT */
349 SYS$
QIOW (0, fd
, IO$_SENSEMODE
, &sg
, 0, 0,
350 &sg
.class, 12, 0, 0, 0, 0 );
351 emacs_ospeed
= sg
.xmit_baud
;
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 */
372 ioctl (fd
, 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 (fd
, 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);
398 set_exclusive_use (fd
)
402 ioctl (fd
, FIOCLEX
, 0);
404 /* Ok to do nothing if this feature does not exist */
409 wait_without_blocking ()
412 wait3 (0, WNOHANG
| WUNTRACED
, 0);
414 croak ("wait_without_blocking");
416 synch_process_alive
= 0;
419 #endif /* not subprocesses */
421 int wait_debugging
; /* Set nonzero to make following function work under dbx
422 (at least for bsd). */
425 wait_for_termination_signal ()
428 /* Wait for subprocess with process id `pid' to terminate and
429 make sure it will get eliminated (not remain forever as a zombie) */
432 wait_for_termination (pid
)
441 status
= SYS$
FORCEX (&pid
, 0, 0);
444 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
445 /* Note that kill returns -1 even if the process is just a zombie now.
446 But inevitably a SIGCHLD interrupt should be generated
447 and child_sig will do wait3 and make the process go away. */
448 /* There is some indication that there is a bug involved with
449 termination of subprocesses, perhaps involving a kernel bug too,
450 but no idea what it is. Just as a hunch we signal SIGCHLD to see
451 if that causes the problem to go away or get worse. */
452 sigsetmask (sigmask (SIGCHLD
));
453 if (0 > kill (pid
, 0))
455 sigsetmask (SIGEMPTYMASK
);
456 kill (getpid (), SIGCHLD
);
462 sigpause (SIGEMPTYMASK
);
463 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
464 #if defined (UNIPLUS)
465 if (0 > kill (pid
, 0))
468 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
469 #ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */
470 sigblock (sigmask (SIGCHLD
));
472 if (kill (pid
, 0) == -1 && errno
== ESRCH
)
474 sigunblock (sigmask (SIGCHLD
));
478 sigsuspend (&empty_mask
);
479 #else /* not POSIX_SIGNALS */
480 #ifdef HAVE_SYSV_SIGPAUSE
482 if (0 > kill (pid
, 0))
488 #else /* not HAVE_SYSV_SIGPAUSE */
492 #else /* not WINDOWSNT */
493 if (0 > kill (pid
, 0))
495 /* Using sleep instead of pause avoids timing error.
496 If the inferior dies just before the sleep,
497 we lose just one second. */
499 #endif /* not WINDOWSNT */
500 #endif /* not HAVE_SYSV_SIGPAUSE */
501 #endif /* not POSIX_SIGNALS */
502 #endif /* not UNIPLUS */
503 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
505 #else /* not subprocesses */
508 #else /* not __DJGPP__ > 1 */
510 if (kill (pid
, 0) < 0)
516 if (status
== pid
|| status
== -1)
519 #endif /* not __DJGPP__ > 1*/
520 #endif /* not subprocesses */
527 * flush any pending output
528 * (may flush input as well; it does not matter the way we use it)
532 flush_pending_output (channel
)
536 /* If we try this, we get hit with SIGTTIN, because
537 the child's tty belongs to the child's pgrp. */
540 ioctl (channel
, TCFLSH
, 1);
544 /* 3rd arg should be ignored
545 but some 4.2 kernels actually want the address of an int
546 and nonzero means something different. */
547 ioctl (channel
, TIOCFLUSH
, &zero
);
554 /* Set up the terminal at the other end of a pseudo-terminal that
555 we will be controlling an inferior through.
556 It should not echo or do line-editing, since that is done
557 in Emacs. No padding needed for insertion into an Emacs buffer. */
560 child_setup_tty (out
)
566 EMACS_GET_TTY (out
, &s
);
568 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
569 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
570 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
572 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
573 /* No output delays */
575 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
576 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
577 #if 0 /* This causes bugs in (for instance) telnet to certain sites. */
578 s
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
579 #ifdef INLCR /* Just being cautious, since I can't check how
580 widespread INLCR is--rms. */
581 s
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
585 s
.main
.c_iflag
&= ~IUCLC
; /* Disable downcasing on input. */
588 s
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
591 s
.main
.c_oflag
&= ~OLCUC
; /* Disable upcasing on output. */
593 s
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
594 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CSIZE
) | CS8
; /* Don't strip 8th bit */
596 /* Said to be unnecessary: */
597 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
598 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
601 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
602 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
603 s
.main
.c_cc
[VERASE
] = CDISABLE
; /* disable erase processing */
604 s
.main
.c_cc
[VKILL
] = CDISABLE
; /* disable kill processing */
607 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
611 /* AIX enhanced edit loses NULs, so disable it */
614 s
.main
.c_iflag
&= ~ASCEDIT
;
616 /* Also, PTY overloads NUL and BREAK.
617 don't ignore break, but don't signal either, so it looks like NUL. */
618 s
.main
.c_iflag
&= ~IGNBRK
;
619 s
.main
.c_iflag
&= ~BRKINT
;
620 /* QUIT and INTR work better as signals, so disable character forms */
621 s
.main
.c_cc
[VINTR
] = 0377;
622 #ifdef SIGNALS_VIA_CHARACTERS
623 /* the QUIT and INTR character are used in process_send_signal
624 so set them here to something useful. */
625 if (s
.main
.c_cc
[VQUIT
] == 0377)
626 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
627 if (s
.main
.c_cc
[VINTR
] == 0377)
628 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
629 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
630 /* QUIT and INTR work better as signals, so disable character forms */
631 s
.main
.c_cc
[VQUIT
] = 0377;
632 s
.main
.c_cc
[VINTR
] = 0377;
633 s
.main
.c_lflag
&= ~ISIG
;
634 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
635 s
.main
.c_cc
[VEOL
] = 0377;
636 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
639 #else /* not HAVE_TERMIO */
641 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
643 s
.main
.sg_flags
|= LPASS8
;
644 s
.main
.sg_erase
= 0377;
645 s
.main
.sg_kill
= 0377;
646 s
.lmode
= LLITOUT
| s
.lmode
; /* Don't strip 8th bit */
648 #endif /* not HAVE_TERMIO */
650 EMACS_SET_TTY (out
, &s
, 0);
659 ioctl (out
, FIOASYNC
, &zero
);
662 #endif /* not DOS_NT */
666 #endif /* subprocesses */
668 /* Record a signal code and the handler for it. */
672 SIGTYPE (*handler
) P_ ((int));
675 static void save_signal_handlers
P_ ((struct save_signal
*));
676 static void restore_signal_handlers
P_ ((struct save_signal
*));
678 /* Suspend the Emacs process; give terminal to its superior. */
684 /* "Foster" parentage allows emacs to return to a subprocess that attached
685 to the current emacs as a cheaper than starting a whole new process. This
686 is set up by KEPTEDITOR.COM. */
687 unsigned long parent_id
, foster_parent_id
;
690 fpid_string
= getenv ("EMACS_PARENT_PID");
691 if (fpid_string
!= NULL
)
693 sscanf (fpid_string
, "%x", &foster_parent_id
);
694 if (foster_parent_id
!= 0)
695 parent_id
= foster_parent_id
;
697 parent_id
= getppid ();
700 parent_id
= getppid ();
702 xfree (fpid_string
); /* On VMS, this was malloc'd */
704 if (parent_id
&& parent_id
!= 0xffffffff)
706 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
707 int status
= LIB$
ATTACH (&parent_id
) & 1;
708 signal (SIGINT
, oldsig
);
717 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
718 d_prompt
.a
= "Emacs: "; /* Just a reminder */
719 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
724 #if defined (SIGTSTP) && !defined (MSDOS)
727 int pgrp
= EMACS_GETPGRP (0);
728 EMACS_KILLPG (pgrp
, SIGTSTP
);
731 #else /* No SIGTSTP */
732 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
733 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
734 kill (getpid (), SIGQUIT
);
736 #else /* No SIGTSTP or USG_JOBCTRL */
738 /* On a system where suspending is not implemented,
739 instead fork a subshell and let it talk directly to the terminal
743 #endif /* no USG_JOBCTRL */
744 #endif /* no SIGTSTP */
748 /* Fork a subshell. */
755 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
757 char oldwd
[MAXPATHLEN
+1]; /* Fixed length is safe on MSDOS. */
760 struct save_signal saved_handlers
[5];
762 unsigned char *str
= 0;
765 saved_handlers
[0].code
= SIGINT
;
766 saved_handlers
[1].code
= SIGQUIT
;
767 saved_handlers
[2].code
= SIGTERM
;
769 saved_handlers
[3].code
= SIGIO
;
770 saved_handlers
[4].code
= 0;
772 saved_handlers
[3].code
= 0;
775 /* Mentioning current_buffer->buffer would mean including buffer.h,
776 which somehow wedges the hp compiler. So instead... */
778 dir
= intern ("default-directory");
779 if (NILP (Fboundp (dir
)))
781 dir
= Fsymbol_value (dir
);
785 dir
= expand_and_dir_to_file (Funhandled_file_name_directory (dir
), Qnil
);
786 str
= (unsigned char *) alloca (SCHARS (dir
) + 2);
788 bcopy (SDATA (dir
), str
, len
);
789 if (str
[len
- 1] != '/') str
[len
++] = '/';
796 save_signal_handlers (saved_handlers
);
797 synch_process_alive
= 1;
798 #endif /* __DJGPP__ > 1 */
802 error ("Can't spawn subshell");
809 #ifdef DOS_NT /* MW, Aug 1993 */
812 sh
= (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
815 sh
= (char *) egetenv ("SHELL");
819 /* Use our buffer's default directory for the subshell. */
821 chdir ((char *) str
);
824 close_process_descs (); /* Close Emacs's pipes/ptys */
827 #ifdef SET_EMACS_PRIORITY
829 extern EMACS_INT emacs_priority
;
831 if (emacs_priority
< 0)
832 nice (-emacs_priority
);
836 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
838 char *epwd
= getenv ("PWD");
839 char old_pwd
[MAXPATHLEN
+1+4];
841 /* If PWD is set, pass it with corrected value. */
844 strcpy (old_pwd
, epwd
);
845 if (str
[len
- 1] == '/')
847 setenv ("PWD", str
, 1);
852 putenv (old_pwd
); /* restore previous value */
854 #if 0 /* This is also reported if last command executed in subshell failed, KFS */
856 report_file_error ("Can't execute subshell", Fcons (build_string (sh
), Qnil
));
858 #else /* not MSDOS */
860 /* Waits for process completion */
861 pid
= _spawnlp (_P_WAIT
, sh
, sh
, NULL
);
864 write (1, "Can't execute subshell", 22);
865 #else /* not WINDOWSNT */
867 write (1, "Can't execute subshell", 22);
869 #endif /* not WINDOWSNT */
870 #endif /* not MSDOS */
873 /* Do this now if we did not do it before. */
874 #if !defined (MSDOS) || __DJGPP__ == 1
875 save_signal_handlers (saved_handlers
);
876 synch_process_alive
= 1;
880 wait_for_termination (pid
);
882 restore_signal_handlers (saved_handlers
);
883 synch_process_alive
= 0;
886 #endif /* !MAC_OS8 */
889 save_signal_handlers (saved_handlers
)
890 struct save_signal
*saved_handlers
;
892 while (saved_handlers
->code
)
894 saved_handlers
->handler
895 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers
->code
, SIG_IGN
);
901 restore_signal_handlers (saved_handlers
)
902 struct save_signal
*saved_handlers
;
904 while (saved_handlers
->code
)
906 signal (saved_handlers
->code
, saved_handlers
->handler
);
912 /* If SIGIO is broken, don't do anything. */
929 unrequest_sigio (void)
936 int old_fcntl_flags
[MAXDESC
];
943 old_fcntl_flags
[fd
] = fcntl (fd
, F_GETFL
, 0) & ~FASYNC
;
944 fcntl (fd
, F_SETFL
, old_fcntl_flags
[fd
] | FASYNC
);
946 interrupts_deferred
= 0;
954 fcntl (fd
, F_SETFL
, old_fcntl_flags
[fd
]);
958 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
959 /* XXX Uhm, FASYNC is not used anymore here. */
964 /* XXX read_socket_hook is not global anymore. Is blocking SIGIO
967 if (read_socket_hook
)
972 sigunblock (sigmask (SIGWINCH
));
974 sigunblock (sigmask (SIGIO
));
976 interrupts_deferred
= 0;
980 unrequest_sigio (void)
982 /* XXX read_socket_hook is not global anymore. Is blocking SIGIO
985 if (read_socket_hook
)
990 sigblock (sigmask (SIGWINCH
));
992 sigblock (sigmask (SIGIO
));
993 interrupts_deferred
= 1;
996 #else /* no FASYNC */
997 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
1004 if (read_socket_hook
)
1007 /* XXX CURTTY() is bogus here. */
1008 ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC
, &on
);
1009 interrupts_deferred
= 0;
1017 if (read_socket_hook
)
1020 /* XXX CURTTY() is bogus here. */
1021 ioctl (fileno (TTY_INPUT (CURTTY ())), FIOASYNC
, &off
);
1022 interrupts_deferred
= 1;
1025 #else /* not FASYNC, not STRIDE */
1029 #include <termios.h>
1037 if (read_socket_hook
)
1041 sigaddset (&st
, SIGIO
);
1042 ioctl (0, FIOASYNC
, &on
); /* XXX This fails for multiple ttys. */
1043 interrupts_deferred
= 0;
1044 sigprocmask (SIG_UNBLOCK
, &st
, (sigset_t
*)0);
1052 if (read_socket_hook
)
1055 ioctl (0, FIOASYNC
, &off
); /* XXX This fails for multiple ttys. */
1056 interrupts_deferred
= 1;
1059 #else /* ! _CX_UX */
1065 if (read_socket_hook
)
1068 croak ("request_sigio");
1074 if (read_socket_hook
)
1077 croak ("unrequest_sigio");
1084 #endif /* F_SETFL */
1087 /* Saving and restoring the process group of Emacs's terminal. */
1091 /* The process group of which Emacs was a member when it initially
1094 If Emacs was in its own process group (i.e. inherited_pgroup ==
1095 getpid ()), then we know we're running under a shell with job
1096 control (Emacs would never be run as part of a pipeline).
1099 If Emacs was not in its own process group, then we know we're
1100 running under a shell (or a caller) that doesn't know how to
1101 separate itself from Emacs (like sh). Emacs must be in its own
1102 process group in order to receive SIGIO correctly. In this
1103 situation, we put ourselves in our own pgroup, forcibly set the
1104 tty's pgroup to our pgroup, and make sure to restore and reinstate
1105 the tty's pgroup just like any other terminal setting. If
1106 inherited_group was not the tty's pgroup, then we'll get a
1107 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1108 it goes foreground in the future, which is what should happen. */
1109 int inherited_pgroup
;
1111 /* Split off the foreground process group to Emacs alone.
1112 When we are in the foreground, but not started in our own process
1113 group, redirect the TTY to point to our own process group. We need
1114 to be in our own process group to receive SIGIO properly. */
1116 narrow_foreground_group (int fd
)
1120 if (! inherited_pgroup
)
1121 inherited_pgroup
= getpgid (0);
1122 /* XXX This only works on the controlling tty. */
1123 if (inherited_pgroup
!= me
)
1124 EMACS_SET_TTY_PGRP (fd
, &me
);
1128 /* Set the tty to our original foreground group. */
1130 widen_foreground_group (int fd
)
1132 if (inherited_pgroup
!= getpid ())
1133 EMACS_SET_TTY_PGRP (fd
, &inherited_pgroup
);
1134 setpgid (0, inherited_pgroup
);
1137 #endif /* BSD_PGRPS */
1139 /* Getting and setting emacs_tty structures. */
1141 /* Set *TC to the parameters associated with the terminal FD.
1142 Return zero if all's well, or -1 if we ran into an error we
1143 couldn't deal with. */
1145 emacs_get_tty (fd
, settings
)
1147 struct emacs_tty
*settings
;
1149 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1151 /* We have those nifty POSIX tcmumbleattr functions. */
1152 bzero (&settings
->main
, sizeof (settings
->main
));
1153 if (tcgetattr (fd
, &settings
->main
) < 0)
1158 /* The SYSV-style interface? */
1159 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
1164 /* Vehemently Monstrous System? :-) */
1165 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
1166 &settings
->main
.class, 12, 0, 0, 0, 0)
1172 /* I give up - I hope you have the BSD ioctls. */
1173 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
1175 #endif /* not DOS_NT */
1180 /* Suivant - Do we have to get struct ltchars data? */
1182 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
1186 /* How about a struct tchars and a wordful of lmode bits? */
1188 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
1189 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
1193 /* We have survived the tempest. */
1198 /* Set the parameters of the tty on FD according to the contents of
1199 *SETTINGS. If FLUSHP is non-zero, we discard input.
1200 Return 0 if all went well, and -1 if anything failed. */
1203 emacs_set_tty (fd
, settings
, flushp
)
1205 struct emacs_tty
*settings
;
1208 /* Set the primary parameters - baud rate, character size, etcetera. */
1211 /* We have those nifty POSIX tcmumbleattr functions.
1212 William J. Smith <wjs@wiis.wang.com> writes:
1213 "POSIX 1003.1 defines tcsetattr to return success if it was
1214 able to perform any of the requested actions, even if some
1215 of the requested actions could not be performed.
1216 We must read settings back to ensure tty setup properly.
1217 AIX requires this to keep tty from hanging occasionally." */
1218 /* This make sure that we don't loop indefinitely in here. */
1219 for (i
= 0 ; i
< 10 ; i
++)
1220 if (tcsetattr (fd
, flushp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
1231 bzero (&new, sizeof (new));
1232 /* Get the current settings, and see if they're what we asked for. */
1233 tcgetattr (fd
, &new);
1234 /* We cannot use memcmp on the whole structure here because under
1235 * aix386 the termios structure has some reserved field that may
1238 if ( new.c_iflag
== settings
->main
.c_iflag
1239 && new.c_oflag
== settings
->main
.c_oflag
1240 && new.c_cflag
== settings
->main
.c_cflag
1241 && new.c_lflag
== settings
->main
.c_lflag
1242 && memcmp (new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
1250 /* The SYSV-style interface? */
1251 if (ioctl (fd
, flushp
? TCSETAF
: TCSETAW
, &settings
->main
) < 0)
1256 /* Vehemently Monstrous System? :-) */
1257 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
1258 &settings
->main
.class, 12, 0, 0, 0, 0)
1264 /* I give up - I hope you have the BSD ioctls. */
1265 if (ioctl (fd
, (flushp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
1267 #endif /* not DOS_NT */
1273 /* Suivant - Do we have to get struct ltchars data? */
1275 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
1279 /* How about a struct tchars and a wordful of lmode bits? */
1281 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
1282 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
1286 /* We have survived the tempest. */
1293 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1298 #ifndef F_SETOWN_BUG
1300 int old_fcntl_owner
[MAXDESC
];
1301 #endif /* F_SETOWN */
1302 #endif /* F_SETOWN_BUG */
1304 /* This may also be defined in stdio,
1305 but if so, this does no harm,
1306 and using the same name avoids wasting the other one's space. */
1309 extern char *_sobuf
;
1311 #if defined (USG) || defined (DGUX)
1312 unsigned char _sobuf
[BUFSIZ
+8];
1314 char _sobuf
[BUFSIZ
];
1319 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
1322 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
1326 init_all_sys_modes (void)
1328 struct tty_display_info
*tty
;
1329 for (tty
= tty_list
; tty
; tty
= tty
->next
)
1330 init_sys_modes (tty
);
1334 init_sys_modes (tty_out
)
1335 struct tty_display_info
*tty_out
;
1337 struct emacs_tty tty
;
1340 /* cus-start.el complains if delete-exited-processes is not defined */
1341 #ifndef subprocesses
1342 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes
,
1343 doc
: /* *Non-nil means delete processes immediately when they exit.
1344 nil means don't delete them until `list-processes' is run. */);
1345 delete_exited_processes
= 0;
1347 #endif /* MAC_OS8 */
1351 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
1352 extern int (*interrupt_signal
) ();
1356 Vtty_erase_char
= Qnil
;
1363 input_ef
= get_kbd_event_flag ();
1364 /* LIB$GET_EF (&input_ef); */
1365 SYS$
CLREF (input_ef
);
1366 waiting_for_ast
= 0;
1368 timer_ef
= get_timer_event_flag ();
1369 /* LIB$GET_EF (&timer_ef); */
1370 SYS$
CLREF (timer_ef
);
1374 LIB$
GET_EF (&process_ef
);
1375 SYS$
CLREF (process_ef
);
1377 if (input_ef
/ 32 != process_ef
/ 32)
1378 croak ("Input and process event flags in different clusters.");
1380 if (input_ef
/ 32 != timer_ef
/ 32)
1381 croak ("Input and timer event flags in different clusters.");
1383 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1384 ((unsigned) 1 << (process_ef
% 32));
1386 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1387 ((unsigned) 1 << (timer_ef
% 32));
1389 sys_access_reinit ();
1395 /* read_socket_hook is not global anymore. I think doing this
1396 unconditionally will not cause any problems. */
1397 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1399 narrow_foreground_group (fileno (TTY_INPUT (tty_out
)));
1402 #ifdef HAVE_WINDOW_SYSTEM
1403 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1404 needs the initialization code below. */
1405 if (tty_out
->input
!= stdin
|| EQ (Vwindow_system
, Qnil
))
1408 if (! tty_out
->old_tty
)
1409 tty_out
->old_tty
= (struct emacs_tty
*) xmalloc (sizeof (struct emacs_tty
));
1411 EMACS_GET_TTY (fileno (TTY_INPUT (tty_out
)), tty_out
->old_tty
);
1413 tty
= *tty_out
->old_tty
;
1415 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1416 XSETINT (Vtty_erase_char
, tty
.main
.c_cc
[VERASE
]);
1419 /* This allows meta to be sent on 8th bit. */
1420 tty
.main
.c_iflag
&= ~INPCK
; /* don't check input for parity */
1422 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1423 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1424 #ifdef INLCR /* I'm just being cautious,
1425 since I can't check how widespread INLCR is--rms. */
1426 tty
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
1429 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1431 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1432 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1434 tty
.main
.c_lflag
&= ~IEXTEN
; /* Disable other editing characters. */
1436 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1437 if (tty_out
->flow_control
)
1439 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1441 tty
.main
.c_iflag
&= ~IXANY
;
1445 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1446 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1448 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1450 if (tty_out
->meta_key
)
1452 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1453 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1456 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1457 /* Set up C-g for both SIGQUIT and SIGINT.
1458 We don't know which we will get, but we handle both alike
1459 so which one it really gives us does not matter. */
1460 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1461 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1462 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1464 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1468 #if defined (mips) || defined (HAVE_TCATTR)
1470 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1473 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1474 #endif /* V_DSUSP */
1475 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1476 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1479 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1482 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1483 #endif /* VREPRINT */
1485 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1486 #endif /* VWERASE */
1488 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1489 #endif /* VDISCARD */
1491 if (tty_out
->flow_control
)
1494 tty
.main
.c_cc
[VSTART
] = '\021';
1497 tty
.main
.c_cc
[VSTOP
] = '\023';
1503 tty
.main
.c_cc
[VSTART
] = CDISABLE
;
1506 tty
.main
.c_cc
[VSTOP
] = CDISABLE
;
1509 #endif /* mips or HAVE_TCATTR */
1511 #ifdef SET_LINE_DISCIPLINE
1512 /* Need to explicitly request TERMIODISC line discipline or
1513 Ultrix's termios does not work correctly. */
1514 tty
.main
.c_line
= SET_LINE_DISCIPLINE
;
1518 /* AIX enhanced edit loses NULs, so disable it. */
1519 tty
.main
.c_line
= 0;
1520 tty
.main
.c_iflag
&= ~ASCEDIT
;
1522 tty
.main
.c_cc
[VSTRT
] = 255;
1523 tty
.main
.c_cc
[VSTOP
] = 255;
1524 tty
.main
.c_cc
[VSUSP
] = 255;
1525 tty
.main
.c_cc
[VDSUSP
] = 255;
1526 #endif /* IBMR2AIX */
1527 if (tty_out
->flow_control
)
1530 tty
.main
.c_cc
[VSTART
] = '\021';
1533 tty
.main
.c_cc
[VSTOP
] = '\023';
1536 /* Also, PTY overloads NUL and BREAK.
1537 don't ignore break, but don't signal either, so it looks like NUL.
1538 This really serves a purpose only if running in an XTERM window
1539 or via TELNET or the like, but does no harm elsewhere. */
1540 tty
.main
.c_iflag
&= ~IGNBRK
;
1541 tty
.main
.c_iflag
&= ~BRKINT
;
1543 #else /* if not HAVE_TERMIO */
1545 tty
.main
.tt_char
|= TT$M_NOECHO
;
1547 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1548 if (tty_out
->flow_control
)
1549 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1551 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1552 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1553 #else /* not VMS (BSD, that is) */
1555 XSETINT (Vtty_erase_char
, tty
.main
.sg_erase
);
1556 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1558 tty
.main
.sg_flags
|= ANYP
;
1559 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1560 #endif /* not DOS_NT */
1561 #endif /* not VMS (BSD, that is) */
1562 #endif /* not HAVE_TERMIO */
1564 /* If going to use CBREAK mode, we must request C-g to interrupt
1565 and turn off start and stop chars, etc. If not going to use
1566 CBREAK mode, do this anyway so as to turn off local flow
1567 control for user coming over network on 4.2; in this case,
1568 only t_stopc and t_startc really matter. */
1571 /* Note: if not using CBREAK mode, it makes no difference how we
1573 tty
.tchars
= new_tchars
;
1574 tty
.tchars
.t_intrc
= quit_char
;
1575 if (tty_out
->flow_control
)
1577 tty
.tchars
.t_startc
= '\021';
1578 tty
.tchars
.t_stopc
= '\023';
1581 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| tty_out
->old_tty
.lmode
;
1583 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1584 anything, and leaving it in breaks the meta key. Go figure. */
1585 tty
.lmode
&= ~LLITOUT
;
1592 #endif /* HAVE_TCHARS */
1593 #endif /* not HAVE_TERMIO */
1596 tty
.ltchars
= new_ltchars
;
1597 #endif /* HAVE_LTCHARS */
1598 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1599 if (!tty_out
->term_initted
)
1600 internal_terminal_init ();
1604 EMACS_SET_TTY (fileno (TTY_INPUT (tty_out
)), &tty
, 0);
1606 /* This code added to insure that, if flow-control is not to be used,
1607 we have an unlocked terminal at the start. */
1610 if (!tty_out
->flow_control
) ioctl (fileno (TTY_INPUT (tty_out
)), TCXONC
, 1);
1614 if (!tty_out
->flow_control
) ioctl (fileno (TTY_INPUT (tty_out
)), TIOCSTART
, 0);
1618 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1620 if (!tty_out
->flow_control
) tcflow (fileno (TTY_INPUT (tty_out
)), TCOON
);
1628 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1629 to be only LF. This is the way that is done. */
1632 if (ioctl (1, HFTGETID
, &tty
) != -1)
1633 write (1, "\033[20l", 5);
1639 /* Appears to do nothing when in PASTHRU mode.
1640 SYS$QIOW (0, fileno (TTY_INPUT (tty_out)), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1641 interrupt_signal, oob_chars, 0, 0, 0, 0);
1643 queue_kbd_input (0);
1648 #ifndef F_SETOWN_BUG
1649 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1651 && (tty_out
->input
!= stdin
|| EQ (Vwindow_system
, Qnil
)))
1653 old_fcntl_owner
[fileno (TTY_INPUT (tty_out
))] =
1654 fcntl (fileno (TTY_INPUT (tty_out
)), F_GETOWN
, 0);
1655 fcntl (fileno (TTY_INPUT (tty_out
)), F_SETOWN
, getpid ());
1656 init_sigio (fileno (TTY_INPUT (tty_out
)));
1658 #endif /* F_GETOWN */
1659 #endif /* F_SETOWN_BUG */
1660 #endif /* F_SETFL */
1663 if (interrupt_input
)
1664 init_sigio (fileno (TTY_INPUT (tty_out
)));
1667 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1671 /* This symbol is defined on recent USG systems.
1672 Someone says without this call USG won't really buffer the file
1673 even with a call to setbuf. */
1674 setvbuf (TTY_OUTPUT (tty_out
), (char *) _sobuf
, _IOFBF
, sizeof _sobuf
);
1676 setbuf (TTY_OUTPUT (tty_out
), (char *) _sobuf
);
1679 #if 0 /* We always need this with multi-tty support. */
1680 #ifdef HAVE_WINDOW_SYSTEM
1681 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1682 needs the initialization code below. */
1683 if (EQ (Vwindow_system
, Qnil
)
1685 /* When running in tty mode on NT/Win95, we have a read_socket
1686 hook, but still need the rest of the initialization code below. */
1687 && (! read_socket_hook
)
1692 tty_set_terminal_modes (tty_out
->display
);
1694 if (!tty_out
->term_initted
)
1696 Lisp_Object tail
, frame
;
1697 FOR_EACH_FRAME (tail
, frame
)
1699 /* XXX This needs to be revised. */
1700 if (FRAME_TERMCAP_P (XFRAME (frame
))
1701 && FRAME_TTY (XFRAME (frame
)) == tty_out
)
1702 init_frame_faces (XFRAME (frame
));
1706 if (tty_out
->term_initted
&& no_redraw_on_reenter
)
1708 if (display_completed
)
1709 direct_output_forward_char (0);
1713 Lisp_Object tail
, frame
;
1715 FOR_EACH_FRAME (tail
, frame
)
1717 if (FRAME_TERMCAP_P (XFRAME (frame
))
1718 && FRAME_TTY (XFRAME (frame
)) == tty_out
)
1719 FRAME_GARBAGED_P (XFRAME (frame
)) = 1;
1723 tty_out
->term_initted
= 1;
1726 /* Return nonzero if safe to use tabs in output.
1727 At the time this is called, init_sys_modes has not been done yet. */
1730 tabs_safe_p (int fd
)
1732 struct emacs_tty etty
;
1734 EMACS_GET_TTY (fd
, &etty
);
1735 return EMACS_TTY_TABS_OK (&etty
);
1738 /* Get terminal size from system.
1739 Store number of lines into *HEIGHTP and width into *WIDTHP.
1740 We store 0 if there's no valid information. */
1743 get_tty_size (int fd
, int *widthp
, int *heightp
)
1749 struct winsize size
;
1751 if (ioctl (fd
, TIOCGWINSZ
, &size
) == -1)
1752 *widthp
= *heightp
= 0;
1755 *widthp
= size
.ws_col
;
1756 *heightp
= size
.ws_row
;
1762 /* SunOS - style. */
1763 struct ttysize size
;
1765 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1766 *widthp
= *heightp
= 0;
1769 *widthp
= size
.ts_cols
;
1770 *heightp
= size
.ts_lines
;
1776 struct sensemode tty
;
1778 SYS$
QIOW (0, fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1779 &tty
.class, 12, 0, 0, 0, 0);
1780 *widthp
= tty
.scr_wid
;
1781 *heightp
= tty
.scr_len
;
1785 *widthp
= ScreenCols ();
1786 *heightp
= ScreenRows ();
1787 #else /* system doesn't know size */
1791 #endif /* not VMS */
1792 #endif /* not SunOS-style */
1793 #endif /* not BSD-style */
1796 /* Set the logical window size associated with descriptor FD
1797 to HEIGHT and WIDTH. This is used mainly with ptys. */
1800 set_window_size (fd
, height
, width
)
1801 int fd
, height
, width
;
1806 struct winsize size
;
1807 size
.ws_row
= height
;
1808 size
.ws_col
= width
;
1810 if (ioctl (fd
, TIOCSWINSZ
, &size
) == -1)
1811 return 0; /* error */
1818 /* SunOS - style. */
1819 struct ttysize size
;
1820 size
.ts_lines
= height
;
1821 size
.ts_cols
= width
;
1823 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1829 #endif /* not SunOS-style */
1830 #endif /* not BSD-style */
1835 reset_all_sys_modes (void)
1837 struct tty_display_info
*tty
;
1838 for (tty
= tty_list
; tty
; tty
= tty
->next
)
1839 reset_sys_modes (tty
);
1842 /* Prepare the terminal for closing it; move the cursor to the
1843 bottom of the frame, turn off interrupt-driven I/O, etc. */
1845 reset_sys_modes (tty_out
)
1846 struct tty_display_info
*tty_out
;
1853 if (!tty_out
->term_initted
)
1855 #if 0 /* We always need to do this with multi-tty support. */
1856 #ifdef HAVE_WINDOW_SYSTEM
1857 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1858 needs the clean-up code below. */
1859 if (tty_out
->input
!= stdin
1860 || (!EQ (Vwindow_system
, Qnil
)
1862 /* When running in tty mode on NT/Win95, we have a read_socket
1863 hook, but still need the rest of the clean-up code below. */
1871 cmgoto (tty_out
, FrameRows (tty_out
) - 1, 0);
1872 #if 0 /* XXX This doesn't work anymore, the signature has changed. */
1873 tty_clear_end_of_line (tty_out
, FrameCols (tty_out
));
1875 cmgoto (tty_out
, FrameRows (tty_out
) - 1, 0);
1876 fflush (tty_out
->output
);
1878 #if defined (IBMR2AIX) && defined (AIXHFT)
1880 /* HFT devices normally use ^J as a LF/CR. We forced it to
1881 do the LF only. Now, we need to reset it. */
1884 if (ioctl (1, HFTGETID
, &tty
) != -1)
1885 write (1, "\033[20h", 5);
1889 tty_reset_terminal_modes (tty_out
->display
);
1890 fflush (TTY_OUTPUT (tty_out
));
1893 /* Avoid possible loss of output when changing terminal modes. */
1894 fsync (fileno (TTY_OUTPUT (tty_out
)));
1899 #ifndef F_SETOWN_BUG
1900 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1901 if (interrupt_input
)
1903 reset_sigio (fileno (TTY_INPUT (tty_out
)));
1904 fcntl (fileno (TTY_INPUT (tty_out
)), F_SETOWN
,
1905 old_fcntl_owner
[fileno (TTY_INPUT (tty_out
))]);
1907 #endif /* F_SETOWN */
1908 #endif /* F_SETOWN_BUG */
1910 fcntl (fileno (TTY_INPUT (tty_out
)), F_SETFL
,
1911 fcntl (fileno (TTY_INPUT (tty_out
)), F_GETFL
, 0) & ~O_NDELAY
);
1913 #endif /* F_SETFL */
1915 if (interrupt_input
)
1916 reset_sigio (fileno (TTY_INPUT (tty_out
)));
1919 if (tty_out
->old_tty
)
1920 while (EMACS_SET_TTY (fileno (TTY_INPUT (tty_out
)),
1921 tty_out
->old_tty
, 0) < 0 && errno
== EINTR
)
1924 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1928 #ifdef SET_LINE_DISCIPLINE
1929 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1930 A different old line discipline is therefore not restored, yet.
1931 Restore the old line discipline by hand. */
1932 ioctl (0, TIOCSETD
, &tty_out
->old_tty
.main
.c_line
);
1940 widen_foreground_group (fileno (TTY_INPUT (tty_out
)));
1946 /* Set up the proper status flags for use of a pty. */
1952 /* I'm told that TOICREMOTE does not mean control chars
1953 "can't be sent" but rather that they don't have
1954 input-editing or signaling effects.
1955 That should be good, because we have other ways
1956 to do those things in Emacs.
1957 However, telnet mode seems not to work on 4.2.
1958 So TIOCREMOTE is turned off now. */
1960 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1961 will hang. In particular, the "timeout" feature (which
1962 causes a read to return if there is no data available)
1963 does this. Also it is known that telnet mode will hang
1964 in such a way that Emacs must be stopped (perhaps this
1965 is the same problem).
1967 If TIOCREMOTE is turned off, then there is a bug in
1968 hp-ux which sometimes loses data. Apparently the
1969 code which blocks the master process when the internal
1970 buffer fills up does not work. Other than this,
1971 though, everything else seems to work fine.
1973 Since the latter lossage is more benign, we may as well
1974 lose that way. -- cph */
1976 #if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
1979 ioctl (fd
, FIONBIO
, &on
);
1984 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1985 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1986 /* cause EMACS not to die when it should, i.e., when its own controlling */
1987 /* tty goes away. I've complained to the AIX developers, and they may */
1988 /* change this behavior, but I'm not going to hold my breath. */
1989 signal (SIGHUP
, SIG_IGN
);
1992 #endif /* HAVE_PTYS */
1996 /* Assigning an input channel is done at the start of Emacs execution.
1997 This is called each time Emacs is resumed, also, but does nothing
1998 because input_chain is no longer zero. */
2005 if (fileno (TTY_INPUT (CURTTY())) == 0)
2007 status
= SYS$
ASSIGN (&input_dsc
, &fileno (TTY_INPUT (CURTTY())), 0, 0);
2013 /* Deassigning the input channel is done before exiting. */
2018 return SYS$
DASSGN (fileno (TTY_INPUT (CURTTY())));
2023 /* Request reading one character into the keyboard buffer.
2024 This is done as soon as the buffer becomes empty. */
2030 extern kbd_input_ast ();
2032 waiting_for_ast
= 0;
2034 status
= SYS$
QIO (0, fileno (TTY_INPUT (CURTTY())), IO$_READVBLK
,
2035 &input_iosb
, kbd_input_ast
, 1,
2036 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
2041 /* Ast routine that is called when keyboard input comes in
2042 in accord with the SYS$QIO above. */
2047 register int c
= -1;
2048 int old_errno
= errno
;
2049 extern EMACS_TIME
*input_available_clear_time
;
2051 if (waiting_for_ast
)
2052 SYS$
SETEF (input_ef
);
2053 waiting_for_ast
= 0;
2056 if (input_count
== 25)
2058 printf ("Ast # %d,", input_count
);
2059 printf (" iosb = %x, %x, %x, %x",
2060 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
2063 if (input_iosb
.offset
)
2067 printf (", char = 0%o", c
);
2079 struct input_event e
;
2082 e
.kind
= ASCII_KEYSTROKE_EVENT
;
2083 XSETINT (e
.code
, c
);
2084 e
.frame_or_window
= selected_frame
;
2085 kbd_buffer_store_event (&e
);
2087 if (input_available_clear_time
)
2088 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
2092 /* Wait until there is something in kbd_buffer. */
2095 wait_for_kbd_input ()
2097 extern int have_process_input
, process_exited
;
2099 /* If already something, avoid doing system calls. */
2100 if (detect_input_pending ())
2104 /* Clear a flag, and tell ast routine above to set it. */
2105 SYS$
CLREF (input_ef
);
2106 waiting_for_ast
= 1;
2107 /* Check for timing error: ast happened while we were doing that. */
2108 if (!detect_input_pending ())
2110 /* No timing error: wait for flag to be set. */
2111 set_waiting_for_input (0);
2112 SYS$
WFLOR (input_ef
, input_eflist
);
2113 clear_waiting_for_input ();
2114 if (!detect_input_pending ())
2115 /* Check for subprocess input availability */
2117 int dsp
= have_process_input
|| process_exited
;
2119 SYS$
CLREF (process_ef
);
2120 if (have_process_input
)
2121 process_command_input ();
2126 update_mode_lines
++;
2127 prepare_menu_bars ();
2128 redisplay_preserve_echo_area (18);
2132 waiting_for_ast
= 0;
2135 /* Get rid of any pending QIO, when we are about to suspend
2136 or when we want to throw away pending input.
2137 We wait for a positive sign that the AST routine has run
2138 and therefore there is no I/O request queued when we return.
2139 SYS$SETAST is used to avoid a timing error. */
2145 printf ("At end_kbd_input.\n");
2149 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2151 SYS$
CANCEL (fileno (TTY_INPUT (CURTTY())));
2156 /* Clear a flag, and tell ast routine above to set it. */
2157 SYS$
CLREF (input_ef
);
2158 waiting_for_ast
= 1;
2160 SYS$
CANCEL (fileno (TTY_INPUT (CURTTY())));
2162 SYS$
WAITFR (input_ef
);
2163 waiting_for_ast
= 0;
2166 /* Wait for either input available or time interval expiry. */
2169 input_wait_timeout (timeval
)
2170 int timeval
; /* Time to wait, in seconds */
2173 static int zero
= 0;
2174 static int large
= -10000000;
2176 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2178 /* If already something, avoid doing system calls. */
2179 if (detect_input_pending ())
2183 /* Clear a flag, and tell ast routine above to set it. */
2184 SYS$
CLREF (input_ef
);
2185 waiting_for_ast
= 1;
2186 /* Check for timing error: ast happened while we were doing that. */
2187 if (!detect_input_pending ())
2189 /* No timing error: wait for flag to be set. */
2191 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2192 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
2194 waiting_for_ast
= 0;
2197 /* The standard `sleep' routine works some other way
2198 and it stops working if you have ever quit out of it.
2199 This one continues to work. */
2205 static int zero
= 0;
2206 static int large
= -10000000;
2208 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2211 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2212 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
2231 croak ("request sigio");
2237 croak ("unrequest sigio");
2242 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2247 #ifndef SYSTEM_MALLOC
2254 /* Some systems that cannot dump also cannot implement these. */
2257 * Return the address of the start of the text segment prior to
2258 * doing an unexec. After unexec the return value is undefined.
2259 * See crt0.c for further explanation and _start.
2263 #if !(defined (__NetBSD__) && defined (__ELF__))
2264 #ifndef HAVE_TEXT_START
2269 return ((char *) TEXT_START
);
2273 return ((char *) csrt
);
2274 #else /* not GOULD */
2275 extern int _start ();
2276 return ((char *) _start
);
2278 #endif /* TEXT_START */
2280 #endif /* not HAVE_TEXT_START */
2284 * Return the address of the start of the data segment prior to
2285 * doing an unexec. After unexec the return value is undefined.
2286 * See crt0.c for further information and definition of data_start.
2288 * Apparently, on BSD systems this is etext at startup. On
2289 * USG systems (swapping) this is highly mmu dependent and
2290 * is also dependent on whether or not the program is running
2291 * with shared text. Generally there is a (possibly large)
2292 * gap between end of text and start of data with shared text.
2294 * On Uniplus+ systems with shared text, data starts at a
2295 * fixed address. Each port (from a given oem) is generally
2296 * different, and the specific value of the start of data can
2297 * be obtained via the UniPlus+ specific "uvar" system call,
2298 * however the method outlined in crt0.c seems to be more portable.
2300 * Probably what will have to happen when a USG unexec is available,
2301 * at least on UniPlus, is temacs will have to be made unshared so
2302 * that text and data are contiguous. Then once loadup is complete,
2303 * unexec will produce a shared executable where the data can be
2304 * at the normal shared text boundary and the startofdata variable
2305 * will be patched by unexec to the correct value.
2309 #ifndef start_of_data
2314 return ((char *) DATA_START
);
2316 #ifdef ORDINARY_LINK
2318 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2319 * data_start isn't defined. We take the address of environ, which
2320 * is known to live at or near the start of the system crt0.c, and
2321 * we don't sweat the handful of bytes that might lose.
2323 extern char **environ
;
2325 return ((char *) &environ
);
2327 extern int data_start
;
2328 return ((char *) &data_start
);
2329 #endif /* ORDINARY_LINK */
2330 #endif /* DATA_START */
2332 #endif /* start_of_data */
2333 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2335 /* init_system_name sets up the string for the Lisp function
2336 system-name to return. */
2342 extern Lisp_Object Vsystem_name
;
2347 #include <sys/socket.h>
2349 #endif /* HAVE_SOCKETS */
2350 #endif /* not VMS */
2351 #endif /* not BSD4_1 */
2354 #ifndef HAVE_H_ERRNO
2357 #endif /* TRY_AGAIN */
2363 Vsystem_name
= build_string (sysname
);
2367 if ((sp
= egetenv ("SYS$NODE")) == 0)
2368 Vsystem_name
= build_string ("vax-vms");
2369 else if ((end
= index (sp
, ':')) == 0)
2370 Vsystem_name
= build_string (sp
);
2372 Vsystem_name
= make_string (sp
, end
- sp
);
2374 #ifndef HAVE_GETHOSTNAME
2377 Vsystem_name
= build_string (uts
.nodename
);
2378 #else /* HAVE_GETHOSTNAME */
2379 unsigned int hostname_size
= 256;
2380 char *hostname
= (char *) alloca (hostname_size
);
2382 /* Try to get the host name; if the buffer is too short, try
2383 again. Apparently, the only indication gethostname gives of
2384 whether the buffer was large enough is the presence or absence
2385 of a '\0' in the string. Eech. */
2388 gethostname (hostname
, hostname_size
- 1);
2389 hostname
[hostname_size
- 1] = '\0';
2391 /* Was the buffer large enough for the '\0'? */
2392 if (strlen (hostname
) < hostname_size
- 1)
2395 hostname_size
<<= 1;
2396 hostname
= (char *) alloca (hostname_size
);
2399 /* Turn the hostname into the official, fully-qualified hostname.
2400 Don't do this if we're going to dump; this can confuse system
2401 libraries on some machines and make the dumped emacs core dump. */
2404 #endif /* not CANNOT_DUMP */
2405 if (! index (hostname
, '.'))
2409 for (count
= 0;; count
++)
2414 hp
= gethostbyname (hostname
);
2416 if (! (hp
== 0 && h_errno
== TRY_AGAIN
))
2421 Fsleep_for (make_number (1), Qnil
);
2425 char *fqdn
= (char *) hp
->h_name
;
2430 if (!index (fqdn
, '.'))
2432 /* We still don't have a fully qualified domain name.
2433 Try to find one in the list of alternate names */
2434 char **alias
= hp
->h_aliases
;
2435 while (*alias
&& !index (*alias
, '.'))
2442 /* Convert the host name to lower case. */
2443 /* Using ctype.h here would introduce a possible locale
2444 dependence that is probably wrong for hostnames. */
2448 if (*p
>= 'A' && *p
<= 'Z')
2455 #endif /* HAVE_SOCKETS */
2456 /* We used to try using getdomainname here,
2457 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2458 getdomainname gets the NIS/YP domain which often is not the same
2459 as in Internet domain name. */
2460 #if 0 /* Turned off because sysinfo is not really likely to return the
2461 correct Internet domain. */
2462 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2463 if (! index (hostname
, '.'))
2465 /* The hostname is not fully qualified. Append the domain name. */
2467 int hostlen
= strlen (hostname
);
2468 int domain_size
= 256;
2472 char *domain
= (char *) alloca (domain_size
+ 1);
2473 char *fqdn
= (char *) alloca (hostlen
+ 1 + domain_size
+ 1);
2474 int sys_domain_size
= sysinfo (SI_SRPC_DOMAIN
, domain
, domain_size
);
2475 if (sys_domain_size
<= 0)
2477 if (domain_size
< sys_domain_size
)
2479 domain_size
= sys_domain_size
;
2482 strcpy (fqdn
, hostname
);
2483 if (domain
[0] == '.')
2484 strcpy (fqdn
+ hostlen
, domain
);
2485 else if (domain
[0] != 0)
2487 fqdn
[hostlen
] = '.';
2488 strcpy (fqdn
+ hostlen
+ 1, domain
);
2494 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2496 Vsystem_name
= build_string (hostname
);
2497 #endif /* HAVE_GETHOSTNAME */
2502 for (p
= SDATA (Vsystem_name
); *p
; p
++)
2503 if (*p
== ' ' || *p
== '\t')
2510 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2512 #include "sysselect.h"
2515 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2516 /* Cause explanatory error message at compile time,
2517 since the select emulation is not good enough for X. */
2518 int *x
= &x_windows_lose_if_no_select_system_call
;
2521 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2522 * Only checks read descriptors.
2524 /* How long to wait between checking fds in select */
2525 #define SELECT_PAUSE 1
2528 /* For longjmp'ing back to read_input_waiting. */
2530 jmp_buf read_alarm_throw
;
2532 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2533 The read_socket_hook function sets this to 1 while it is waiting. */
2535 int read_alarm_should_throw
;
2543 #else /* not BSD4_1 */
2544 signal (SIGALRM
, SIG_IGN
);
2545 #endif /* not BSD4_1 */
2546 if (read_alarm_should_throw
)
2547 longjmp (read_alarm_throw
, 1);
2551 /* Only rfds are checked. */
2553 sys_select (nfds
, rfds
, wfds
, efds
, timeout
)
2555 SELECT_TYPE
*rfds
, *wfds
, *efds
;
2556 EMACS_TIME
*timeout
;
2562 extern int proc_buffered_char
[];
2563 #ifndef subprocesses
2564 int process_tick
= 0, update_tick
= 0;
2566 extern int process_tick
, update_tick
;
2570 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2571 /* If we're using X, then the native select will work; we only need the
2572 emulation for non-X usage. */
2573 if (!NILP (Vwindow_system
))
2574 return select (nfds
, rfds
, wfds
, efds
, timeout
);
2576 timeoutval
= timeout
? EMACS_SECS (*timeout
) : 100000;
2577 local_timeout
= &timeoutval
;
2589 /* If we are looking only for the terminal, with no timeout,
2590 just read it and wait -- that's more efficient. */
2591 if (*local_timeout
== 100000 && process_tick
== update_tick
2592 && FD_ISSET (0, &orfds
))
2595 for (fd
= 1; fd
< nfds
; ++fd
)
2596 if (FD_ISSET (fd
, &orfds
))
2598 if (! detect_input_pending ())
2599 read_input_waiting ();
2605 /* Once a second, till the timer expires, check all the flagged read
2606 * descriptors to see if any input is available. If there is some then
2607 * set the corresponding bit in the return copy of rfds.
2611 register int to_check
, fd
;
2615 for (to_check
= nfds
, fd
= 0; --to_check
>= 0; fd
++)
2617 if (FD_ISSET (fd
, &orfds
))
2619 int avail
= 0, status
= 0;
2622 avail
= detect_input_pending (); /* Special keyboard handler */
2626 status
= ioctl (fd
, FIONREAD
, &avail
);
2627 #else /* no FIONREAD */
2628 /* Hoping it will return -1 if nothing available
2629 or 0 if all 0 chars requested are read. */
2630 if (proc_buffered_char
[fd
] >= 0)
2634 avail
= read (fd
, &buf
, 1);
2636 proc_buffered_char
[fd
] = buf
;
2638 #endif /* no FIONREAD */
2640 if (status
>= 0 && avail
> 0)
2648 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2651 turn_on_atimers (0);
2652 signal (SIGALRM
, select_alarm
);
2654 alarm (SELECT_PAUSE
);
2656 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2657 while (select_alarmed
== 0 && *local_timeout
!= 0
2658 && process_tick
== update_tick
)
2660 /* If we are interested in terminal input,
2661 wait by reading the terminal.
2662 That makes instant wakeup for terminal input at least. */
2663 if (FD_ISSET (0, &orfds
))
2665 read_input_waiting ();
2666 if (detect_input_pending ())
2672 (*local_timeout
) -= SELECT_PAUSE
;
2674 /* Reset the old alarm if there was one. */
2675 turn_on_atimers (1);
2677 if (*local_timeout
== 0) /* Stop on timer being cleared */
2682 #endif not WINDOWSNT
2684 /* Read keyboard input into the standard buffer,
2685 waiting for at least one character. */
2687 /* Make all keyboard buffers much bigger when using a window system. */
2688 #ifdef HAVE_WINDOW_SYSTEM
2689 #define BUFFER_SIZE_FACTOR 16
2691 #define BUFFER_SIZE_FACTOR 1
2695 read_input_waiting ()
2697 /* XXX This needs to be updated for multi-tty support. Does
2698 anybody need to emulate select these days? */
2700 extern int quit_char
;
2702 if (read_socket_hook
)
2704 struct input_event buf
[256];
2705 for (i
= 0; i
< 256; i
++)
2706 EVENT_INIT (buf
[i
]);
2708 read_alarm_should_throw
= 0;
2709 if (! setjmp (read_alarm_throw
))
2710 nread
= (*read_socket_hook
) (0, buf
, 256, 1);
2714 /* Scan the chars for C-g and store them in kbd_buffer. */
2715 for (i
= 0; i
< nread
; i
++)
2717 kbd_buffer_store_event (&buf
[i
]);
2718 /* Don't look at input that follows a C-g too closely.
2719 This reduces lossage due to autorepeat on C-g. */
2720 if (buf
[i
].kind
== ASCII_KEYSTROKE_EVENT
2721 && buf
[i
].code
== quit_char
)
2727 struct input_event e
;
2729 nread
= read (fileno (stdin
), buf
, 1);
2732 /* Scan the chars for C-g and store them in kbd_buffer. */
2733 e
.kind
= ASCII_KEYSTROKE_EVENT
;
2734 e
.frame_or_window
= selected_frame
;
2736 for (i
= 0; i
< nread
; i
++)
2738 /* Convert chars > 0177 to meta events if desired.
2739 We do this under the same conditions that read_avail_input does. */
2740 if (read_socket_hook
== 0)
2742 /* If the user says she has a meta key, then believe her. */
2743 if (meta_key
== 1 && (buf
[i
] & 0x80))
2744 e
.modifiers
= meta_modifier
;
2749 XSETINT (e
.code
, buf
[i
]);
2750 kbd_buffer_store_event (&e
);
2751 /* Don't look at input that follows a C-g too closely.
2752 This reduces lossage due to autorepeat on C-g. */
2753 if (buf
[i
] == quit_char
)
2759 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2760 #define select sys_select
2763 #endif /* not HAVE_SELECT */
2764 #endif /* not VMS */
2765 #endif /* not MSDOS */
2774 lmode
= LINTRUP
| lmode
;
2775 ioctl (fd
, TIOCLSET
, &lmode
);
2784 lmode
= ~LINTRUP
& lmode
;
2785 ioctl (fd
, TIOCLSET
, &lmode
);
2793 interrupts_deferred
= 0;
2801 interrupts_deferred
= 1;
2804 /* still inside #ifdef BSD4_1 */
2807 int sigheld
; /* Mask of held signals */
2813 sigheld
|= sigbit (signum
);
2821 sigheld
|= sigbit (signum
);
2828 sigheld
&= ~sigbit (signum
);
2833 sigfree () /* Free all held signals */
2836 for (i
= 0; i
< NSIG
; i
++)
2837 if (sigheld
& sigbit (i
))
2845 return 1 << (i
- 1);
2847 #endif /* subprocesses */
2850 /* POSIX signals support - DJB */
2851 /* Anyone with POSIX signals should have ANSI C declarations */
2853 #ifdef POSIX_SIGNALS
2855 sigset_t empty_mask
, full_mask
;
2858 sys_signal (int signal_number
, signal_handler_t action
)
2860 struct sigaction new_action
, old_action
;
2861 sigemptyset (&new_action
.sa_mask
);
2862 new_action
.sa_handler
= action
;
2863 #if defined (SA_RESTART) && ! defined (BROKEN_SA_RESTART)
2864 /* Emacs mostly works better with restartable system services. If this
2865 flag exists, we probably want to turn it on here.
2866 However, on some systems this resets the timeout of `select'
2867 which means that `select' never finishes if it keeps getting signals.
2868 BROKEN_SA_RESTART is defined on those systems. */
2869 new_action
.sa_flags
= SA_RESTART
;
2871 new_action
.sa_flags
= 0;
2873 sigaction (signal_number
, &new_action
, &old_action
);
2874 return (old_action
.sa_handler
);
2878 /* If we're compiling with GCC, we don't need this function, since it
2879 can be written as a macro. */
2881 sys_sigmask (int sig
)
2884 sigemptyset (&mask
);
2885 sigaddset (&mask
, sig
);
2890 /* I'd like to have these guys return pointers to the mask storage in here,
2891 but there'd be trouble if the code was saving multiple masks. I'll be
2892 safe and pass the structure. It normally won't be more than 2 bytes
2896 sys_sigblock (sigset_t new_mask
)
2899 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2904 sys_sigunblock (sigset_t new_mask
)
2907 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2912 sys_sigsetmask (sigset_t new_mask
)
2915 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2919 #endif /* POSIX_SIGNALS */
2921 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2922 static char *my_sys_siglist
[NSIG
];
2926 # define sys_siglist my_sys_siglist
2932 #ifdef POSIX_SIGNALS
2933 sigemptyset (&empty_mask
);
2934 sigfillset (&full_mask
);
2937 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2941 sys_siglist
[SIGABRT
] = "Aborted";
2944 sys_siglist
[SIGAIO
] = "LAN I/O interrupt";
2947 sys_siglist
[SIGALRM
] = "Alarm clock";
2950 sys_siglist
[SIGBUS
] = "Bus error";
2953 sys_siglist
[SIGCLD
] = "Child status changed";
2956 sys_siglist
[SIGCHLD
] = "Child status changed";
2959 sys_siglist
[SIGCONT
] = "Continued";
2962 sys_siglist
[SIGDANGER
] = "Swap space dangerously low";
2965 sys_siglist
[SIGDGNOTIFY
] = "Notification message in queue";
2968 sys_siglist
[SIGEMT
] = "Emulation trap";
2971 sys_siglist
[SIGFPE
] = "Arithmetic exception";
2974 sys_siglist
[SIGFREEZE
] = "SIGFREEZE";
2977 sys_siglist
[SIGGRANT
] = "Monitor mode granted";
2980 sys_siglist
[SIGHUP
] = "Hangup";
2983 sys_siglist
[SIGILL
] = "Illegal instruction";
2986 sys_siglist
[SIGINT
] = "Interrupt";
2989 sys_siglist
[SIGIO
] = "I/O possible";
2992 sys_siglist
[SIGIOINT
] = "I/O intervention required";
2995 sys_siglist
[SIGIOT
] = "IOT trap";
2998 sys_siglist
[SIGKILL
] = "Killed";
3001 sys_siglist
[SIGLOST
] = "Resource lost";
3004 sys_siglist
[SIGLWP
] = "SIGLWP";
3007 sys_siglist
[SIGMSG
] = "Monitor mode data available";
3010 sys_siglist
[SIGWIND
] = "SIGPHONE";
3013 sys_siglist
[SIGPIPE
] = "Broken pipe";
3016 sys_siglist
[SIGPOLL
] = "Pollable event occurred";
3019 sys_siglist
[SIGPROF
] = "Profiling timer expired";
3022 sys_siglist
[SIGPTY
] = "PTY I/O interrupt";
3025 sys_siglist
[SIGPWR
] = "Power-fail restart";
3028 sys_siglist
[SIGQUIT
] = "Quit";
3031 sys_siglist
[SIGRETRACT
] = "Need to relinguish monitor mode";
3034 sys_siglist
[SIGSAK
] = "Secure attention";
3037 sys_siglist
[SIGSEGV
] = "Segmentation violation";
3040 sys_siglist
[SIGSOUND
] = "Sound completed";
3043 sys_siglist
[SIGSTOP
] = "Stopped (signal)";
3046 sys_siglist
[SIGSTP
] = "Stopped (user)";
3049 sys_siglist
[SIGSYS
] = "Bad argument to system call";
3052 sys_siglist
[SIGTERM
] = "Terminated";
3055 sys_siglist
[SIGTHAW
] = "SIGTHAW";
3058 sys_siglist
[SIGTRAP
] = "Trace/breakpoint trap";
3061 sys_siglist
[SIGTSTP
] = "Stopped (user)";
3064 sys_siglist
[SIGTTIN
] = "Stopped (tty input)";
3067 sys_siglist
[SIGTTOU
] = "Stopped (tty output)";
3070 sys_siglist
[SIGURG
] = "Urgent I/O condition";
3073 sys_siglist
[SIGUSR1
] = "User defined signal 1";
3076 sys_siglist
[SIGUSR2
] = "User defined signal 2";
3079 sys_siglist
[SIGVTALRM
] = "Virtual timer expired";
3082 sys_siglist
[SIGWAITING
] = "Process's LWPs are blocked";
3085 sys_siglist
[SIGWINCH
] = "Window size changed";
3088 sys_siglist
[SIGWIND
] = "SIGWIND";
3091 sys_siglist
[SIGXCPU
] = "CPU time limit exceeded";
3094 sys_siglist
[SIGXFSZ
] = "File size limit exceeded";
3097 #endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
3106 /* Figure out how many bits the system's random number generator uses.
3107 `random' and `lrand48' are assumed to return 31 usable bits.
3108 BSD `rand' returns a 31 bit value but the low order bits are unusable;
3109 so we'll shift it and treat it like the 15-bit USG `rand'. */
3113 # define RAND_BITS 31
3114 # else /* !HAVE_RANDOM */
3115 # ifdef HAVE_LRAND48
3116 # define RAND_BITS 31
3117 # define random lrand48
3118 # else /* !HAVE_LRAND48 */
3119 # define RAND_BITS 15
3120 # if RAND_MAX == 32767
3121 # define random rand
3122 # else /* RAND_MAX != 32767 */
3123 # if RAND_MAX == 2147483647
3124 # define random() (rand () >> 16)
3125 # else /* RAND_MAX != 2147483647 */
3127 # define random rand
3129 # define random() (rand () >> 16)
3131 # endif /* RAND_MAX != 2147483647 */
3132 # endif /* RAND_MAX != 32767 */
3133 # endif /* !HAVE_LRAND48 */
3134 # endif /* !HAVE_RANDOM */
3135 #endif /* !RAND_BITS */
3142 srandom ((unsigned int)arg
);
3144 # ifdef HAVE_LRAND48
3147 srand ((unsigned int)arg
);
3153 * Build a full Emacs-sized word out of whatever we've got.
3154 * This suffices even for a 64-bit architecture with a 15-bit rand.
3159 long val
= random ();
3160 #if VALBITS > RAND_BITS
3161 val
= (val
<< RAND_BITS
) ^ random ();
3162 #if VALBITS > 2*RAND_BITS
3163 val
= (val
<< RAND_BITS
) ^ random ();
3164 #if VALBITS > 3*RAND_BITS
3165 val
= (val
<< RAND_BITS
) ^ random ();
3166 #if VALBITS > 4*RAND_BITS
3167 val
= (val
<< RAND_BITS
) ^ random ();
3168 #endif /* need at least 5 */
3169 #endif /* need at least 4 */
3170 #endif /* need at least 3 */
3171 #endif /* need at least 2 */
3172 return val
& ((1L << VALBITS
) - 1);
3175 #ifdef WRONG_NAME_INSQUE
3188 /* If any place else asks for the TERM variable,
3189 allow it to be overridden with the EMACS_TERM variable
3190 before attempting to translate the logical name TERM. As a last
3191 resort, ask for VAX C's special idea of the TERM variable. */
3198 static char buf
[256];
3199 static struct dsc$descriptor_s equiv
3200 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
3201 static struct dsc$descriptor_s d_name
3202 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
3205 if (!strcmp (name
, "TERM"))
3207 val
= (char *) getenv ("EMACS_TERM");
3212 d_name
.dsc$w_length
= strlen (name
);
3213 d_name
.dsc$a_pointer
= name
;
3214 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
3216 char *str
= (char *) xmalloc (eqlen
+ 1);
3217 bcopy (buf
, str
, eqlen
);
3219 /* This is a storage leak, but a pain to fix. With luck,
3220 no one will ever notice. */
3223 return (char *) getenv (name
);
3228 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
3229 to force a call on the debugger from within the image. */
3233 reset_all_sys_modes ();
3234 LIB$
SIGNAL (SS$_DEBUG
);
3240 #ifdef LINK_CRTL_SHARE
3241 #ifdef SHARABLE_LIB_BUG
3242 /* Variables declared noshare and initialized in sharable libraries
3243 cannot be shared. The VMS linker incorrectly forces you to use a private
3244 version which is uninitialized... If not for this "feature", we
3245 could use the C library definition of sys_nerr and sys_errlist. */
3247 char *sys_errlist
[] =
3251 "no such file or directory",
3253 "interrupted system call",
3255 "no such device or address",
3256 "argument list too long",
3257 "exec format error",
3260 "no more processes",
3261 "not enough memory",
3262 "permission denied",
3264 "block device required",
3265 "mount devices busy",
3267 "cross-device link",
3272 "file table overflow",
3273 "too many open files",
3277 "no space left on device",
3279 "read-only file system",
3285 "vax/vms specific error code nontranslatable error"
3287 #endif /* SHARABLE_LIB_BUG */
3288 #endif /* LINK_CRTL_SHARE */
3291 #ifndef HAVE_STRERROR
3297 extern char *sys_errlist
[];
3298 extern int sys_nerr
;
3300 if (errnum
>= 0 && errnum
< sys_nerr
)
3301 return sys_errlist
[errnum
];
3302 return (char *) "Unknown error";
3304 #endif /* not WINDOWSNT */
3305 #endif /* ! HAVE_STRERROR */
3308 emacs_open (path
, oflag
, mode
)
3312 register int rtnval
;
3315 if (oflag
& O_CREAT
)
3316 return creat (path
, mode
);
3319 while ((rtnval
= open (path
, oflag
, mode
)) == -1
3320 && (errno
== EINTR
));
3329 register int rtnval
;
3331 while ((rtnval
= close (fd
)) == -1
3332 && (errno
== EINTR
))
3335 /* If close is interrupted SunOS 4.1 may or may not have closed the
3336 file descriptor. If it did the second close will fail with
3337 errno = EBADF. That means we have succeeded. */
3338 if (rtnval
== -1 && did_retry
&& errno
== EBADF
)
3345 emacs_read (fildes
, buf
, nbyte
)
3350 register int rtnval
;
3352 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
3353 && (errno
== EINTR
));
3358 emacs_write (fildes
, buf
, nbyte
)
3363 register int rtnval
, bytes_written
;
3369 rtnval
= write (fildes
, buf
, nbyte
);
3376 return (bytes_written
? bytes_written
: -1);
3381 bytes_written
+= rtnval
;
3383 return (bytes_written
);
3388 * All of the following are for USG.
3390 * On USG systems the system calls are INTERRUPTIBLE by signals
3391 * that the user program has elected to catch. Thus the system call
3392 * must be retried in these cases. To handle this without massive
3393 * changes in the source code, we remap the standard system call names
3394 * to names for our own functions in sysdep.c that do the system call
3395 * with retries. Actually, for portability reasons, it is good
3396 * programming practice, as this example shows, to limit all actual
3397 * system calls to a single occurrence in the source. Sure, this
3398 * adds an extra level of function call overhead but it is almost
3399 * always negligible. Fred Fish, Unisoft Systems Inc.
3403 * Warning, this function may not duplicate 4.2 action properly
3404 * under error conditions.
3408 /* In 4.1, param.h fails to define this. */
3409 #define MAXPATHLEN 1024
3418 char *npath
, *spath
;
3419 extern char *getcwd ();
3421 BLOCK_INPUT
; /* getcwd uses malloc */
3422 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
3428 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3429 up to first slash. Should be harmless on other systems. */
3430 while (*npath
&& *npath
!= '/')
3432 strcpy (pathname
, npath
);
3433 free (spath
); /* getcwd uses malloc */
3438 #endif /* HAVE_GETWD */
3441 * Emulate rename using unlink/link. Note that this is
3442 * only partially correct. Also, doesn't enforce restriction
3443 * that files be of same type (regular->regular, dir->dir, etc).
3452 if (access (from
, 0) == 0)
3455 if (link (from
, to
) == 0)
3456 if (unlink (from
) == 0)
3468 /* HPUX curses library references perror, but as far as we know
3469 it won't be called. Anyway this definition will do for now. */
3475 #endif /* not HAVE_PERROR */
3481 * Emulate BSD dup2. First close newd if it already exists.
3482 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3483 * until we are, then close the unsuccessful ones.
3490 register int fd
, ret
;
3495 return fcntl (oldd
, F_DUPFD
, newd
);
3502 ret
= dup2 (old
,new);
3508 #endif /* not HAVE_DUP2 */
3511 * Gettimeofday. Simulate as much as possible. Only accurate
3512 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3513 * Only needed when subprocesses are defined.
3518 #ifndef HAVE_GETTIMEOFDAY
3523 gettimeofday (tp
, tzp
)
3525 struct timezone
*tzp
;
3527 extern long time ();
3529 tp
->tv_sec
= time ((long *)0);
3532 tzp
->tz_minuteswest
= -1;
3539 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3542 * This function will go away as soon as all the stubs fixed. (fnf)
3549 printf ("%s not yet implemented\r\n", badfunc
);
3550 reset_all_sys_modes ();
3556 /* Directory routines for systems that don't have them. */
3558 #ifdef SYSV_SYSTEM_DIR
3562 #if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
3566 register DIR *dirp
; /* stream from opendir */
3570 rtnval
= emacs_close (dirp
->dd_fd
);
3572 /* Some systems (like Solaris) allocate the buffer and the DIR all
3573 in one block. Why in the world are we freeing this ourselves
3575 #if ! (defined (sun) && defined (USG5_4))
3576 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
3578 xfree ((char *) dirp
);
3582 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3583 #endif /* SYSV_SYSTEM_DIR */
3585 #ifdef NONSYSTEM_DIR_LIBRARY
3589 char *filename
; /* name of directory */
3591 register DIR *dirp
; /* -> malloc'ed storage */
3592 register int fd
; /* file descriptor for read */
3593 struct stat sbuf
; /* result of fstat */
3595 fd
= emacs_open (filename
, O_RDONLY
, 0);
3600 if (fstat (fd
, &sbuf
) < 0
3601 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
3602 || (dirp
= (DIR *) xmalloc (sizeof (DIR))) == 0)
3606 return 0; /* bad luck today */
3611 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
3618 register DIR *dirp
; /* stream from opendir */
3620 emacs_close (dirp
->dd_fd
);
3621 xfree ((char *) dirp
);
3629 ino_t od_ino
; /* inode */
3630 char od_name
[DIRSIZ
]; /* filename */
3632 #endif /* not VMS */
3634 struct direct dir_static
; /* simulated directory contents */
3639 register DIR *dirp
; /* stream from opendir */
3642 register struct olddir
*dp
; /* -> directory data */
3644 register struct dir$_name
*dp
; /* -> directory data */
3645 register struct dir$_version
*dv
; /* -> version data */
3650 if (dirp
->dd_loc
>= dirp
->dd_size
)
3651 dirp
->dd_loc
= dirp
->dd_size
= 0;
3653 if (dirp
->dd_size
== 0 /* refill buffer */
3654 && (dirp
->dd_size
= emacs_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3658 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3659 dirp
->dd_loc
+= sizeof (struct olddir
);
3661 if (dp
->od_ino
!= 0) /* not deleted entry */
3663 dir_static
.d_ino
= dp
->od_ino
;
3664 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3665 dir_static
.d_name
[DIRSIZ
] = '\0';
3666 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3667 dir_static
.d_reclen
= sizeof (struct direct
)
3669 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3670 return &dir_static
; /* -> simulated structure */
3673 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3674 if (dirp
->dd_loc
== 0)
3675 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3676 : dp
->dir$b_namecount
;
3677 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3678 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3679 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3680 dir_static
.d_reclen
= sizeof (struct direct
)
3682 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3683 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3684 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3685 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3692 /* readdirver is just like readdir except it returns all versions of a file
3693 as separate entries. */
3698 register DIR *dirp
; /* stream from opendir */
3700 register struct dir$_name
*dp
; /* -> directory data */
3701 register struct dir$_version
*dv
; /* -> version data */
3703 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3704 dirp
->dd_loc
= dirp
->dd_size
= 0;
3706 if (dirp
->dd_size
== 0 /* refill buffer */
3707 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3710 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3711 if (dirp
->dd_loc
== 0)
3712 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3713 : dp
->dir$b_namecount
;
3714 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3715 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3716 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3717 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3718 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3719 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3720 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3721 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3727 #endif /* NONSYSTEM_DIR_LIBRARY */
3731 set_file_times (filename
, atime
, mtime
)
3732 const char *filename
;
3733 EMACS_TIME atime
, mtime
;
3736 struct timeval tv
[2];
3739 return utimes (filename
, tv
);
3740 #else /* not HAVE_UTIMES */
3742 utb
.actime
= EMACS_SECS (atime
);
3743 utb
.modtime
= EMACS_SECS (mtime
);
3744 return utime (filename
, &utb
);
3745 #endif /* not HAVE_UTIMES */
3748 /* mkdir and rmdir functions, for systems which don't have them. */
3752 * Written by Robert Rother, Mariah Corporation, August 1985.
3754 * If you want it, it's yours. All I ask in return is that if you
3755 * figure out how to do this in a Bourne Shell script you send me
3757 * sdcsvax!rmr or rmr@uscd
3759 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3760 * subroutine. 11Mar86; hoptoad!gnu
3762 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3763 * subroutine didn't return EEXIST. It does now.
3769 #ifdef MKDIR_PROTOTYPE
3773 mkdir (dpath
, dmode
)
3778 int cpid
, status
, fd
;
3779 struct stat statbuf
;
3781 if (stat (dpath
, &statbuf
) == 0)
3783 errno
= EEXIST
; /* Stat worked, so it already exists */
3787 /* If stat fails for a reason other than non-existence, return error */
3788 if (errno
!= ENOENT
)
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 */
3800 * Cheap hack to set mode of new directory. Since this
3801 * child process is going away anyway, we zap its umask.
3802 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3803 * directory. Does anybody care?
3805 status
= umask (0); /* Get current umask */
3806 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3807 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3814 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3815 _exit (-1); /* Can't exec /bin/mkdir */
3817 default: /* Parent process */
3818 wait_for_termination (cpid
);
3821 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3823 errno
= EIO
; /* We don't know why, but */
3824 return -1; /* /bin/mkdir failed */
3829 #endif /* not HAVE_MKDIR */
3836 int cpid
, status
, fd
;
3837 struct stat statbuf
;
3839 if (stat (dpath
, &statbuf
) != 0)
3841 /* Stat just set errno. We don't have to */
3845 synch_process_alive
= 1;
3846 switch (cpid
= fork ())
3849 case -1: /* Error in fork */
3850 return (-1); /* Errno is set already */
3852 case 0: /* Child process */
3853 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3860 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
3861 _exit (-1); /* Can't exec /bin/rmdir */
3863 default: /* Parent process */
3864 wait_for_termination (cpid
);
3867 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3869 errno
= EIO
; /* We don't know why, but */
3870 return -1; /* /bin/rmdir failed */
3875 #endif /* !HAVE_RMDIR */
3879 /* Functions for VMS */
3881 #include "vms-pwd.h"
3886 /* Return as a string the VMS error string pertaining to STATUS.
3887 Reuses the same static buffer each time it is called. */
3891 int status
; /* VMS status code */
3895 static char buf
[257];
3897 bufadr
[0] = sizeof buf
- 1;
3898 bufadr
[1] = (int) buf
;
3899 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3900 return "untranslatable VMS error status";
3908 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3909 * not work correctly. (It also doesn't work well in version 2.3.)
3914 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3915 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3919 unsigned short s_buflen
;
3920 unsigned short s_code
;
3922 unsigned short *s_retlenadr
;
3926 #define buflen s.s_buflen
3927 #define code s.s_code
3928 #define bufadr s.s_bufadr
3929 #define retlenadr s.s_retlenadr
3931 #define R_OK 4 /* test for read permission */
3932 #define W_OK 2 /* test for write permission */
3933 #define X_OK 1 /* test for execute (search) permission */
3934 #define F_OK 0 /* test for presence of file */
3937 sys_access (path
, mode
)
3941 static char *user
= NULL
;
3944 /* translate possible directory spec into .DIR file name, so brain-dead
3945 * access can treat the directory like a file. */
3946 if (directory_file_name (path
, dir_fn
))
3950 return access (path
, mode
);
3951 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3957 unsigned short int dummy
;
3959 static int constant
= ACL$C_FILE
;
3960 DESCRIPTOR (path_desc
, path
);
3961 DESCRIPTOR (user_desc
, user
);
3965 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3968 acces
|= CHP$M_READ
;
3970 acces
|= CHP$M_WRITE
;
3971 itemlst
[0].buflen
= sizeof (int);
3972 itemlst
[0].code
= CHP$_FLAGS
;
3973 itemlst
[0].bufadr
= (char *) &flags
;
3974 itemlst
[0].retlenadr
= &dummy
;
3975 itemlst
[1].buflen
= sizeof (int);
3976 itemlst
[1].code
= CHP$_ACCESS
;
3977 itemlst
[1].bufadr
= (char *) &acces
;
3978 itemlst
[1].retlenadr
= &dummy
;
3979 itemlst
[2].end
= CHP$_END
;
3980 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3981 return stat
== SS$_NORMAL
? 0 : -1;
3985 #else /* not VMS4_4 */
3988 #define ACE$M_WRITE 2
3989 #define ACE$C_KEYID 1
3991 static unsigned short memid
, grpid
;
3992 static unsigned int uic
;
3994 /* Called from init_sys_modes, so it happens not very often
3995 but at least each time Emacs is loaded. */
3997 sys_access_reinit ()
4003 sys_access (filename
, type
)
4009 int status
, size
, i
, typecode
, acl_controlled
;
4010 unsigned int *aclptr
, *aclend
, aclbuf
[60];
4011 union prvdef prvmask
;
4013 /* Get UIC and GRP values for protection checking. */
4016 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
4019 memid
= uic
& 0xFFFF;
4023 if (type
!= 2) /* not checking write access */
4024 return access (filename
, type
);
4026 /* Check write protection. */
4028 #define CHECKPRIV(bit) (prvmask.bit)
4029 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
4031 /* Find privilege bits */
4032 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
4034 error ("Unable to find privileges: %s", vmserrstr (status
));
4035 if (CHECKPRIV (PRV$V_BYPASS
))
4036 return 0; /* BYPASS enabled */
4038 fab
.fab$b_fac
= FAB$M_GET
;
4039 fab
.fab$l_fna
= filename
;
4040 fab
.fab$b_fns
= strlen (filename
);
4041 fab
.fab$l_xab
= &xab
;
4042 xab
= cc$rms_xabpro
;
4043 xab
.xab$l_aclbuf
= aclbuf
;
4044 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
4045 status
= SYS$
OPEN (&fab
, 0, 0);
4048 SYS$
CLOSE (&fab
, 0, 0);
4049 /* Check system access */
4050 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITABLE (XAB$V_SYS
))
4052 /* Check ACL entries, if any */
4054 if (xab
.xab$w_acllen
> 0)
4057 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
4058 while (*aclptr
&& aclptr
< aclend
)
4060 size
= (*aclptr
& 0xff) / 4;
4061 typecode
= (*aclptr
>> 8) & 0xff;
4062 if (typecode
== ACE$C_KEYID
)
4063 for (i
= size
- 1; i
> 1; i
--)
4064 if (aclptr
[i
] == uic
)
4067 if (aclptr
[1] & ACE$M_WRITE
)
4068 return 0; /* Write access through ACL */
4070 aclptr
= &aclptr
[size
];
4072 if (acl_controlled
) /* ACL specified, prohibits write access */
4075 /* No ACL entries specified, check normal protection */
4076 if (WRITABLE (XAB$V_WLD
)) /* World writable */
4078 if (WRITABLE (XAB$V_GRP
) &&
4079 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
4080 return 0; /* Group writable */
4081 if (WRITABLE (XAB$V_OWN
) &&
4082 (xab
.xab$l_uic
& 0xFFFF) == memid
)
4083 return 0; /* Owner writable */
4085 return -1; /* Not writable */
4087 #endif /* not VMS4_4 */
4090 static char vtbuf
[NAM$C_MAXRSS
+1];
4092 /* translate a vms file spec to a unix path */
4094 sys_translate_vms (vfile
)
4105 /* leading device or logical name is a root directory */
4106 if (p
= strchr (vfile
, ':'))
4115 if (*p
== '[' || *p
== '<')
4117 while (*++vfile
!= *p
+ 2)
4121 if (vfile
[-1] == *p
)
4144 static char utbuf
[NAM$C_MAXRSS
+1];
4146 /* translate a unix path to a VMS file spec */
4148 sys_translate_unix (ufile
)
4171 if (index (&ufile
[1], '/'))
4178 if (index (&ufile
[1], '/'))
4185 if (strncmp (ufile
, "./", 2) == 0)
4192 ufile
++; /* skip the dot */
4193 if (index (&ufile
[1], '/'))
4198 else if (strncmp (ufile
, "../", 3) == 0)
4206 ufile
+= 2; /* skip the dots */
4207 if (index (&ufile
[1], '/'))
4232 extern char *getcwd ();
4234 #define MAXPATHLEN 1024
4236 ptr
= xmalloc (MAXPATHLEN
);
4237 val
= getcwd (ptr
, MAXPATHLEN
);
4243 strcpy (pathname
, ptr
);
4252 long item_code
= JPI$_OWNER
;
4253 unsigned long parent_id
;
4256 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
4259 vaxc$errno
= status
;
4269 return (getgid () << 16) | getuid ();
4274 sys_read (fildes
, buf
, nbyte
)
4279 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
4284 sys_write (fildes
, buf
, nbyte
)
4289 register int nwrote
, rtnval
= 0;
4291 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
4297 return rtnval
? rtnval
: -1;
4298 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
4299 return rtnval
? rtnval
: -1;
4300 return (rtnval
+ nwrote
);
4305 * VAX/VMS VAX C RTL really loses. It insists that records
4306 * end with a newline (carriage return) character, and if they
4307 * don't it adds one (nice of it isn't it!)
4309 * Thus we do this stupidity below.
4314 sys_write (fildes
, buf
, nbytes
)
4317 unsigned int nbytes
;
4324 fstat (fildes
, &st
);
4330 /* Handle fixed-length files with carriage control. */
4331 if (st
.st_fab_rfm
== FAB$C_FIX
4332 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
4334 len
= st
.st_fab_mrs
;
4335 retval
= write (fildes
, p
, min (len
, nbytes
));
4338 retval
++; /* This skips the implied carriage control */
4342 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4343 while (*e
!= '\n' && e
> p
) e
--;
4344 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
4345 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4347 retval
= write (fildes
, p
, len
);
4358 /* Create file NEW copying its attributes from file OLD. If
4359 OLD is 0 or does not exist, create based on the value of
4362 /* Protection value the file should ultimately have.
4363 Set by create_copy_attrs, and use by rename_sansversions. */
4364 static unsigned short int fab_final_pro
;
4367 creat_copy_attrs (old
, new)
4370 struct FAB fab
= cc$rms_fab
;
4371 struct XABPRO xabpro
;
4372 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
4373 extern int vms_stmlf_recfm
;
4377 fab
.fab$b_fac
= FAB$M_GET
;
4378 fab
.fab$l_fna
= old
;
4379 fab
.fab$b_fns
= strlen (old
);
4380 fab
.fab$l_xab
= (char *) &xabpro
;
4381 xabpro
= cc$rms_xabpro
;
4382 xabpro
.xab$l_aclbuf
= aclbuf
;
4383 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
4384 /* Call $OPEN to fill in the fab & xabpro fields. */
4385 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4387 SYS$
CLOSE (&fab
, 0, 0);
4388 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
4389 if (xabpro
.xab$w_acllen
> 0)
4391 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
4392 /* If the acl buffer was too short, redo open with longer one.
4393 Wouldn't need to do this if there were some system imposed
4394 limit on the size of an ACL, but I can't find any such. */
4396 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
4397 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
4398 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4399 SYS$
CLOSE (&fab
, 0, 0);
4405 xabpro
.xab$l_aclbuf
= 0;
4410 fab
.fab$l_fna
= new;
4411 fab
.fab$b_fns
= strlen (new);
4415 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
4416 fab
.fab$b_rat
= FAB$M_CR
;
4419 /* Set the file protections such that we will be able to manipulate
4420 this file. Once we are done writing and renaming it, we will set
4421 the protections back. */
4423 fab_final_pro
= xabpro
.xab$w_pro
;
4425 SYS$
SETDFPROT (0, &fab_final_pro
);
4426 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
4428 /* Create the new file with either default attrs or attrs copied
4430 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
4432 SYS$
CLOSE (&fab
, 0, 0);
4433 /* As this is a "replacement" for creat, return a file descriptor
4434 opened for writing. */
4435 return open (new, O_WRONLY
);
4440 #include <varargs.h>
4443 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4448 sys_creat (va_alist
)
4451 va_list list_incrementer
;
4454 int rfd
; /* related file descriptor */
4455 int fd
; /* Our new file descriptor */
4462 extern int vms_stmlf_recfm
;
4465 va_start (list_incrementer
);
4466 name
= va_arg (list_incrementer
, char *);
4467 mode
= va_arg (list_incrementer
, int);
4469 rfd
= va_arg (list_incrementer
, int);
4470 va_end (list_incrementer
);
4473 /* Use information from the related file descriptor to set record
4474 format of the newly created file. */
4475 fstat (rfd
, &st_buf
);
4476 switch (st_buf
.st_fab_rfm
)
4479 strcpy (rfm
, "rfm = fix");
4480 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
4481 strcpy (rat
, "rat = ");
4482 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4484 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4485 strcat (rat
, "ftn");
4486 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4487 strcat (rat
, "prn");
4488 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4489 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4490 strcat (rat
, ", blk");
4492 strcat (rat
, "blk");
4493 return creat (name
, 0, rfm
, rat
, mrs
);
4496 strcpy (rfm
, "rfm = vfc");
4497 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
4498 strcpy (rat
, "rat = ");
4499 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4501 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4502 strcat (rat
, "ftn");
4503 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4504 strcat (rat
, "prn");
4505 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4506 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4507 strcat (rat
, ", blk");
4509 strcat (rat
, "blk");
4510 return creat (name
, 0, rfm
, rat
, fsz
);
4513 strcpy (rfm
, "rfm = stm");
4517 strcpy (rfm
, "rfm = stmcr");
4521 strcpy (rfm
, "rfm = stmlf");
4525 strcpy (rfm
, "rfm = udf");
4529 strcpy (rfm
, "rfm = var");
4532 strcpy (rat
, "rat = ");
4533 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4535 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4536 strcat (rat
, "ftn");
4537 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4538 strcat (rat
, "prn");
4539 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4540 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4541 strcat (rat
, ", blk");
4543 strcat (rat
, "blk");
4547 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
4548 strcpy (rat
, "rat=cr");
4550 /* Until the VAX C RTL fixes the many bugs with modes, always use
4551 mode 0 to get the user's default protection. */
4552 fd
= creat (name
, 0, rfm
, rat
);
4553 if (fd
< 0 && errno
== EEXIST
)
4555 if (unlink (name
) < 0)
4556 report_file_error ("delete", build_string (name
));
4557 fd
= creat (name
, 0, rfm
, rat
);
4563 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4565 sys_fwrite (ptr
, size
, num
, fp
)
4566 register char * ptr
;
4569 register int tot
= num
* size
;
4577 * The VMS C library routine creat actually creates a new version of an
4578 * existing file rather than truncating the old version. There are times
4579 * when this is not the desired behavior, for instance, when writing an
4580 * auto save file (you only want one version), or when you don't have
4581 * write permission in the directory containing the file (but the file
4582 * itself is writable). Hence this routine, which is equivalent to
4583 * "close (creat (fn, 0));" on Unix if fn already exists.
4589 struct FAB xfab
= cc$rms_fab
;
4590 struct RAB xrab
= cc$rms_rab
;
4593 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
4594 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
4595 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
4596 xfab
.fab$l_fna
= fn
;
4597 xfab
.fab$b_fns
= strlen (fn
);
4598 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
4600 xrab
.rab$l_fab
= &xfab
;
4602 /* This gibberish opens the file, positions to the first record, and
4603 deletes all records from there until the end of file. */
4604 if ((SYS$
OPEN (&xfab
) & 01) == 01)
4606 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
4607 (SYS$
FIND (&xrab
) & 01) == 01 &&
4608 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
4619 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4620 SYSPRV or a readable SYSUAF.DAT. */
4626 * Routine to read the VMS User Authorization File and return
4627 * a specific user's record.
4630 static struct UAF retuaf
;
4633 get_uaf_name (uname
)
4640 uaf_fab
= cc$rms_fab
;
4641 uaf_rab
= cc$rms_rab
;
4642 /* initialize fab fields */
4643 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4644 uaf_fab
.fab$b_fns
= 21;
4645 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4646 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4647 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4648 /* initialize rab fields */
4649 uaf_rab
.rab$l_fab
= &uaf_fab
;
4650 /* open the User Authorization File */
4651 status
= SYS$
OPEN (&uaf_fab
);
4655 vaxc$errno
= status
;
4658 status
= SYS$
CONNECT (&uaf_rab
);
4662 vaxc$errno
= status
;
4665 /* read the requested record - index is in uname */
4666 uaf_rab
.rab$l_kbf
= uname
;
4667 uaf_rab
.rab$b_ksz
= strlen (uname
);
4668 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4669 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4670 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4671 status
= SYS$
GET (&uaf_rab
);
4675 vaxc$errno
= status
;
4678 /* close the User Authorization File */
4679 status
= SYS$
DISCONNECT (&uaf_rab
);
4683 vaxc$errno
= status
;
4686 status
= SYS$
CLOSE (&uaf_fab
);
4690 vaxc$errno
= status
;
4704 uaf_fab
= cc$rms_fab
;
4705 uaf_rab
= cc$rms_rab
;
4706 /* initialize fab fields */
4707 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4708 uaf_fab
.fab$b_fns
= 21;
4709 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4710 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4711 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4712 /* initialize rab fields */
4713 uaf_rab
.rab$l_fab
= &uaf_fab
;
4714 /* open the User Authorization File */
4715 status
= SYS$
OPEN (&uaf_fab
);
4719 vaxc$errno
= status
;
4722 status
= SYS$
CONNECT (&uaf_rab
);
4726 vaxc$errno
= status
;
4729 /* read the requested record - index is in uic */
4730 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4731 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4732 uaf_rab
.rab$b_ksz
= sizeof uic
;
4733 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4734 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4735 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4736 status
= SYS$
GET (&uaf_rab
);
4740 vaxc$errno
= status
;
4743 /* close the User Authorization File */
4744 status
= SYS$
DISCONNECT (&uaf_rab
);
4748 vaxc$errno
= status
;
4751 status
= SYS$
CLOSE (&uaf_fab
);
4755 vaxc$errno
= status
;
4761 static struct passwd retpw
;
4769 /* copy these out first because if the username is 32 chars, the next
4770 section will overwrite the first byte of the UIC */
4771 retpw
.pw_uid
= up
->uaf$w_mem
;
4772 retpw
.pw_gid
= up
->uaf$w_grp
;
4774 /* I suppose this is not the best style, to possibly overwrite one
4775 byte beyond the end of the field, but what the heck... */
4776 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4777 while (ptr
[-1] == ' ')
4780 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4782 /* the rest of these are counted ascii strings */
4783 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4784 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4785 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4786 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4787 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4788 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4789 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4790 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4794 #else /* not READ_SYSUAF */
4795 static struct passwd retpw
;
4796 #endif /* not READ_SYSUAF */
4807 unsigned char * full
;
4808 #endif /* READ_SYSUAF */
4813 if ('a' <= *ptr
&& *ptr
<= 'z')
4818 if (!(up
= get_uaf_name (name
)))
4820 return cnv_uaf_pw (up
);
4822 if (strcmp (name
, getenv ("USER")) == 0)
4824 retpw
.pw_uid
= getuid ();
4825 retpw
.pw_gid
= getgid ();
4826 strcpy (retpw
.pw_name
, name
);
4827 if (full
= egetenv ("FULLNAME"))
4828 strcpy (retpw
.pw_gecos
, full
);
4830 *retpw
.pw_gecos
= '\0';
4831 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4832 *retpw
.pw_shell
= '\0';
4837 #endif /* not READ_SYSUAF */
4847 if (!(up
= get_uaf_uic (uid
)))
4849 return cnv_uaf_pw (up
);
4851 if (uid
== sys_getuid ())
4852 return getpwnam (egetenv ("USER"));
4855 #endif /* not READ_SYSUAF */
4858 /* return total address space available to the current process. This is
4859 the sum of the current p0 size, p1 size and free page table entries
4865 unsigned long free_pages
;
4866 unsigned long frep0va
;
4867 unsigned long frep1va
;
4870 item_code
= JPI$_FREPTECNT
;
4871 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4874 vaxc$errno
= status
;
4879 item_code
= JPI$_FREP0VA
;
4880 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4883 vaxc$errno
= status
;
4886 item_code
= JPI$_FREP1VA
;
4887 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4890 vaxc$errno
= status
;
4894 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4898 define_logical_name (varname
, string
)
4902 struct dsc$descriptor_s strdsc
=
4903 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4904 struct dsc$descriptor_s envdsc
=
4905 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4906 struct dsc$descriptor_s lnmdsc
=
4907 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4909 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4913 delete_logical_name (varname
)
4916 struct dsc$descriptor_s envdsc
=
4917 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4918 struct dsc$descriptor_s lnmdsc
=
4919 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4921 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4939 error ("execvp system call not implemented");
4948 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4949 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4950 char from_esn
[NAM$C_MAXRSS
];
4951 char to_esn
[NAM$C_MAXRSS
];
4953 from_fab
.fab$l_fna
= from
;
4954 from_fab
.fab$b_fns
= strlen (from
);
4955 from_fab
.fab$l_nam
= &from_nam
;
4956 from_fab
.fab$l_fop
= FAB$M_NAM
;
4958 from_nam
.nam$l_esa
= from_esn
;
4959 from_nam
.nam$b_ess
= sizeof from_esn
;
4961 to_fab
.fab$l_fna
= to
;
4962 to_fab
.fab$b_fns
= strlen (to
);
4963 to_fab
.fab$l_nam
= &to_nam
;
4964 to_fab
.fab$l_fop
= FAB$M_NAM
;
4966 to_nam
.nam$l_esa
= to_esn
;
4967 to_nam
.nam$b_ess
= sizeof to_esn
;
4969 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4975 if (status
== RMS$_DEV
)
4979 vaxc$errno
= status
;
4984 /* This function renames a file like `rename', but it strips
4985 the version number from the "to" filename, such that the "to" file is
4986 will always be a new version. It also sets the file protection once it is
4987 finished. The protection that we will use is stored in fab_final_pro,
4988 and was set when we did a creat_copy_attrs to create the file that we
4991 We could use the chmod function, but Eunichs uses 3 bits per user category
4992 to describe the protection, and VMS uses 4 (write and delete are separate
4993 bits). To maintain portability, the VMS implementation of `chmod' wires
4994 the W and D bits together. */
4997 static struct fibdef fib
; /* We need this initialized to zero */
4998 char vms_file_written
[NAM$C_MAXRSS
];
5001 rename_sans_version (from
,to
)
5008 struct FAB to_fab
= cc$rms_fab
;
5009 struct NAM to_nam
= cc$rms_nam
;
5010 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
5011 struct dsc$descriptor fib_attr
[2]
5012 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
5013 char to_esn
[NAM$C_MAXRSS
];
5015 $
DESCRIPTOR (disk
,to_esn
);
5017 to_fab
.fab$l_fna
= to
;
5018 to_fab
.fab$b_fns
= strlen (to
);
5019 to_fab
.fab$l_nam
= &to_nam
;
5020 to_fab
.fab$l_fop
= FAB$M_NAM
;
5022 to_nam
.nam$l_esa
= to_esn
;
5023 to_nam
.nam$b_ess
= sizeof to_esn
;
5025 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
5027 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
5028 *(to_nam
.nam$l_ver
) = '\0';
5030 stat
= rename (from
, to_esn
);
5034 strcpy (vms_file_written
, to_esn
);
5036 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
5037 to_fab
.fab$b_fns
= strlen (vms_file_written
);
5039 /* Now set the file protection to the correct value */
5040 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
5042 /* Copy these fields into the fib */
5043 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
5044 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
5045 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
5047 SYS$
CLOSE (&to_fab
, 0, 0);
5049 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
5052 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
5053 0, 0, 0, &fib_attr
, 0);
5056 stat
= SYS$
DASSGN (chan
);
5059 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
5070 unsigned short fid
[3];
5071 char esa
[NAM$C_MAXRSS
];
5074 fab
.fab$l_fop
= FAB$M_OFP
;
5075 fab
.fab$l_fna
= file
;
5076 fab
.fab$b_fns
= strlen (file
);
5077 fab
.fab$l_nam
= &nam
;
5080 nam
.nam$l_esa
= esa
;
5081 nam
.nam$b_ess
= NAM$C_MAXRSS
;
5083 status
= SYS$
PARSE (&fab
);
5084 if ((status
& 1) == 0)
5087 vaxc$errno
= status
;
5090 status
= SYS$
SEARCH (&fab
);
5091 if ((status
& 1) == 0)
5094 vaxc$errno
= status
;
5098 fid
[0] = nam
.nam$w_fid
[0];
5099 fid
[1] = nam
.nam$w_fid
[1];
5100 fid
[2] = nam
.nam$w_fid
[2];
5102 fab
.fab$l_fna
= new;
5103 fab
.fab$b_fns
= strlen (new);
5105 status
= SYS$
PARSE (&fab
);
5106 if ((status
& 1) == 0)
5109 vaxc$errno
= status
;
5113 nam
.nam$w_fid
[0] = fid
[0];
5114 nam
.nam$w_fid
[1] = fid
[1];
5115 nam
.nam$w_fid
[2] = fid
[2];
5117 nam
.nam$l_esa
= nam
.nam$l_name
;
5118 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
5120 status
= SYS$
ENTER (&fab
);
5121 if ((status
& 1) == 0)
5124 vaxc$errno
= status
;
5135 printf ("%s not yet implemented\r\n", badfunc
);
5136 reset_all_sys_modes ();
5143 /* Arrange to return a range centered on zero. */
5144 return rand () - (1 << 30);
5156 /* Called from init_sys_modes. */
5158 hft_init (struct tty_display_info
*tty_out
)
5162 /* If we're not on an HFT we shouldn't do any of this. We determine
5163 if we are on an HFT by trying to get an HFT error code. If this
5164 call fails, we're not on an HFT. */
5166 if (ioctl (0, HFQERROR
, &junk
) < 0)
5168 #else /* not IBMR2AIX */
5169 if (ioctl (0, HFQEIO
, 0) < 0)
5171 #endif /* not IBMR2AIX */
5173 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5174 as the rubout key's ASCII code. Here this is changed. The bug is that
5175 there's no way to determine the old mapping, so in reset_sys_modes
5176 we need to assume that the normal map had been present. Of course, this
5177 code also doesn't help if on a terminal emulator which doesn't understand
5181 struct hfkeymap keymap
;
5183 buf
.hf_bufp
= (char *)&keymap
;
5184 buf
.hf_buflen
= sizeof (keymap
);
5185 keymap
.hf_nkeys
= 2;
5186 keymap
.hfkey
[0].hf_kpos
= 15;
5187 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5189 keymap
.hfkey
[0].hf_keyidh
= '<';
5190 #else /* not IBMR2AIX */
5191 keymap
.hfkey
[0].hf_page
= '<';
5192 #endif /* not IBMR2AIX */
5193 keymap
.hfkey
[0].hf_char
= 127;
5194 keymap
.hfkey
[1].hf_kpos
= 15;
5195 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5197 keymap
.hfkey
[1].hf_keyidh
= '<';
5198 #else /* not IBMR2AIX */
5199 keymap
.hfkey
[1].hf_page
= '<';
5200 #endif /* not IBMR2AIX */
5201 keymap
.hfkey
[1].hf_char
= 127;
5202 hftctl (0, HFSKBD
, &buf
);
5206 /* Reset the rubout key to backspace. */
5209 hft_reset (struct tty_display_info
*tty_out
)
5212 struct hfkeymap keymap
;
5216 if (ioctl (0, HFQERROR
, &junk
) < 0)
5218 #else /* not IBMR2AIX */
5219 if (ioctl (0, HFQEIO
, 0) < 0)
5221 #endif /* not IBMR2AIX */
5223 buf
.hf_bufp
= (char *)&keymap
;
5224 buf
.hf_buflen
= sizeof (keymap
);
5225 keymap
.hf_nkeys
= 2;
5226 keymap
.hfkey
[0].hf_kpos
= 15;
5227 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5229 keymap
.hfkey
[0].hf_keyidh
= '<';
5230 #else /* not IBMR2AIX */
5231 keymap
.hfkey
[0].hf_page
= '<';
5232 #endif /* not IBMR2AIX */
5233 keymap
.hfkey
[0].hf_char
= 8;
5234 keymap
.hfkey
[1].hf_kpos
= 15;
5235 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5237 keymap
.hfkey
[1].hf_keyidh
= '<';
5238 #else /* not IBMR2AIX */
5239 keymap
.hfkey
[1].hf_page
= '<';
5240 #endif /* not IBMR2AIX */
5241 keymap
.hfkey
[1].hf_char
= 8;
5242 hftctl (0, HFSKBD
, &buf
);
5249 /* These are included on Sunos 4.1 when we do not use shared libraries.
5250 X11 libraries may refer to these functions but (we hope) do not
5251 actually call them. */
5271 #endif /* USE_DL_STUBS */
5280 register int length
;
5284 long max_str
= 65535;
5286 while (length
> max_str
) {
5287 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5292 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5294 while (length
-- > 0)
5296 #endif /* not VMS */
5299 #endif /* no bzero */
5300 #endif /* BSTRING */
5302 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5305 /* Saying `void' requires a declaration, above, where bcopy is used
5306 and that declaration causes pain for systems where bcopy is a macro. */
5307 bcopy (b1
, b2
, length
)
5310 register int length
;
5313 long max_str
= 65535;
5315 while (length
> max_str
) {
5316 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
5322 (void) LIB$
MOVC3 (&length
, b1
, b2
);
5324 while (length
-- > 0)
5326 #endif /* not VMS */
5328 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5333 bcmp (b1
, b2
, length
) /* This could be a macro! */
5336 register int length
;
5339 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
5340 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
5342 return STR$
COMPARE (&src1
, &src2
);
5344 while (length
-- > 0)
5349 #endif /* not VMS */
5351 #endif /* no bcmp */
5352 #endif /* not BSTRING */
5354 #ifndef HAVE_STRSIGNAL
5361 if (0 <= code
&& code
< NSIG
)
5364 signame
= sys_errlist
[code
];
5366 /* Cast to suppress warning if the table has const char *. */
5367 signame
= (char *) sys_siglist
[code
];
5373 #endif /* HAVE_STRSIGNAL */
5375 /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
5376 (do not change this comment) */