1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 86,87,88,93,94,95, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
32 /* Including stdlib.h isn't necessarily enough to get srandom
33 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
35 #if 0 /* It turns out that defining _OSF_SOURCE in osf5-0.h gets
36 random prototyped as returning `int'. It looks to me as
37 though the best way to DTRT is to prefer the rand48 functions
38 (per libc.info). -- fx */
39 extern long int random
P_ ((void));
41 #if 0 /* Don't prototype srandom; it takes an unsigned argument on
42 some systems, and an unsigned long on others, like FreeBSD
44 extern void srandom
P_ ((unsigned int));
48 #include "blockinput.h"
52 /* It is essential to include stdlib.h so that this file picks up
53 the correct definitions of rand, srand, and RAND_MAX.
54 Otherwise random numbers will not work correctly. */
58 /* Nonzero means delete a process right away if it exits (process.c). */
59 static int delete_exited_processes
;
61 #endif /* macintosh */
65 #define write sys_write
70 #endif /* not WINDOWSNT */
72 /* Does anyone other than VMS need this? */
74 #define sys_fwrite fwrite
80 #include <sys/types.h>
84 /* Get _POSIX_VDISABLE, if it is available. */
94 #if !defined (USG) || defined (BSD_PGRPS)
96 #define setpgrp setpgid
100 /* Get SI_SRPC_DOMAIN, if it is available. */
101 #ifdef HAVE_SYS_SYSTEMINFO_H
102 #include <sys/systeminfo.h>
105 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
109 #include <sys/param.h>
113 extern unsigned start
__asm__ ("start");
135 #include <sys/file.h>
143 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
147 #ifdef BSD_SYSTEM /* avoid writing defined (BSD_SYSTEM) || defined (USG)
148 because the vms compiler doesn't grok `defined' */
156 #endif /* not 4.1 bsd */
159 #include <sys/ioctl.h>
165 #ifdef BROKEN_TIOCGWINSZ
170 #if defined (USG) || defined (DGUX)
171 #include <sys/utsname.h>
172 #ifndef MEMORY_IN_STRING_H
175 #if defined (TIOCGWINSZ) || defined (ISC4_0)
177 #include <sys/sioctl.h>
180 #include <sys/stream.h>
181 #include <sys/ptem.h>
183 #endif /* TIOCGWINSZ or ISC4_0 */
184 #endif /* USG or DGUX */
186 extern int quit_char
;
188 #include "keyboard.h"
191 #include "termhooks.h"
192 #include "termchar.h"
193 #include "termopts.h"
194 #include "dispextern.h"
199 /* In process.h which conflicts with the local copy. */
201 int _CRTAPI1
_spawnlp (int, const char *, const char *, ...);
202 int _CRTAPI1
_getpid (void);
205 #ifdef NONSYSTEM_DIR_LIBRARY
207 #endif /* NONSYSTEM_DIR_LIBRARY */
209 #include "syssignal.h"
216 #ifndef HAVE_STRUCT_UTIMBUF
217 /* We want to use utime rather than utimes, but we couldn't find the
218 structure declaration. We'll use the traditional one. */
226 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
232 #define LNOFLSH 0100000
235 static int baud_convert
[] =
240 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
241 1800, 2400, 4800, 9600, 19200, 38400
248 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
250 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
258 /* The file descriptor for Emacs's input terminal.
259 Under Unix, this is normally zero except when using X;
260 under VMS, we place the input channel number here. */
263 void croak
P_ ((char *));
270 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
272 SIGMASKTYPE sigprocmask_set
;
275 /* Specify a different file descriptor for further input operations. */
284 /* Discard pending input on descriptor input_fd. */
290 struct emacs_tty buf
;
295 /* Discarding input is not safe when the input could contain
296 replies from the X server. So don't do it. */
297 if (read_socket_hook
)
302 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
303 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
309 ioctl (input_fd
, TIOCFLUSH
, &zero
);
311 #else /* not Apollo */
312 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
313 while (dos_keyread () != -1)
315 #else /* not MSDOS */
316 EMACS_GET_TTY (input_fd
, &buf
);
317 EMACS_SET_TTY (input_fd
, &buf
, 0);
318 #endif /* not MSDOS */
319 #endif /* not Apollo */
321 #endif /* not WINDOWSNT */
326 /* Arrange for character C to be read as the next input from
333 if (read_socket_hook
)
336 /* Should perhaps error if in batch mode */
338 ioctl (input_fd
, TIOCSTI
, &c
);
339 #else /* no TIOCSTI */
340 error ("Cannot stuff terminal input characters in this version of Unix");
341 #endif /* no TIOCSTI */
353 #ifdef INIT_BAUD_RATE
358 #else /* not DOS_NT */
362 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
363 &sg
.class, 12, 0, 0, 0, 0 );
364 emacs_ospeed
= sg
.xmit_baud
;
370 tcgetattr (input_fd
, &sg
);
371 emacs_ospeed
= cfgetospeed (&sg
);
372 #if defined (USE_GETOBAUD) && defined (getobaud)
373 /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
374 if (emacs_ospeed
== 0)
375 emacs_ospeed
= getobaud (sg
.c_cflag
);
377 #else /* neither VMS nor TERMIOS */
383 tcgetattr (input_fd
, &sg
);
385 ioctl (input_fd
, TCGETA
, &sg
);
387 emacs_ospeed
= sg
.c_cflag
& CBAUD
;
388 #else /* neither VMS nor TERMIOS nor TERMIO */
391 sg
.sg_ospeed
= B9600
;
392 if (ioctl (input_fd
, TIOCGETP
, &sg
) < 0)
394 emacs_ospeed
= sg
.sg_ospeed
;
395 #endif /* not HAVE_TERMIO */
396 #endif /* not HAVE_TERMIOS */
398 #endif /* not DOS_NT */
399 #endif /* not INIT_BAUD_RATE */
402 baud_rate
= (emacs_ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
403 ? baud_convert
[emacs_ospeed
] : 9600);
410 set_exclusive_use (fd
)
414 ioctl (fd
, FIOCLEX
, 0);
416 /* Ok to do nothing if this feature does not exist */
421 wait_without_blocking ()
424 wait3 (0, WNOHANG
| WUNTRACED
, 0);
426 croak ("wait_without_blocking");
428 synch_process_alive
= 0;
431 #endif /* not subprocesses */
433 int wait_debugging
; /* Set nonzero to make following function work under dbx
434 (at least for bsd). */
437 wait_for_termination_signal ()
440 /* Wait for subprocess with process id `pid' to terminate and
441 make sure it will get eliminated (not remain forever as a zombie) */
444 wait_for_termination (pid
)
453 status
= SYS$
FORCEX (&pid
, 0, 0);
456 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
457 /* Note that kill returns -1 even if the process is just a zombie now.
458 But inevitably a SIGCHLD interrupt should be generated
459 and child_sig will do wait3 and make the process go away. */
460 /* There is some indication that there is a bug involved with
461 termination of subprocesses, perhaps involving a kernel bug too,
462 but no idea what it is. Just as a hunch we signal SIGCHLD to see
463 if that causes the problem to go away or get worse. */
464 sigsetmask (sigmask (SIGCHLD
));
465 if (0 > kill (pid
, 0))
467 sigsetmask (SIGEMPTYMASK
);
468 kill (getpid (), SIGCHLD
);
474 sigpause (SIGEMPTYMASK
);
475 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
476 #if defined (UNIPLUS)
477 if (0 > kill (pid
, 0))
480 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
481 #ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */
482 sigblock (sigmask (SIGCHLD
));
484 if (kill (pid
, 0) == -1 && errno
== ESRCH
)
486 sigunblock (sigmask (SIGCHLD
));
490 /* FIXME: Since sigpause is not POSIX and its use is deprecated,
491 this should probably be `sigsuspend (&empty_mask)', which is
492 POSIX. I'm not making that change right away because the
493 release is nearing. 2001-09-20 gerd. */
494 sigpause (SIGEMPTYMASK
);
495 #else /* not POSIX_SIGNALS */
496 #ifdef HAVE_SYSV_SIGPAUSE
498 if (0 > kill (pid
, 0))
504 #else /* not HAVE_SYSV_SIGPAUSE */
508 #else /* not WINDOWSNT */
509 if (0 > kill (pid
, 0))
511 /* Using sleep instead of pause avoids timing error.
512 If the inferior dies just before the sleep,
513 we lose just one second. */
515 #endif /* not WINDOWSNT */
516 #endif /* not HAVE_SYSV_SIGPAUSE */
517 #endif /* not POSIX_SIGNALS */
518 #endif /* not UNIPLUS */
519 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
521 #else /* not subprocesses */
524 #else /* not __DJGPP__ > 1 */
526 if (kill (pid
, 0) < 0)
532 if (status
== pid
|| status
== -1)
535 #endif /* not __DJGPP__ > 1*/
536 #endif /* not subprocesses */
543 * flush any pending output
544 * (may flush input as well; it does not matter the way we use it)
548 flush_pending_output (channel
)
552 /* If we try this, we get hit with SIGTTIN, because
553 the child's tty belongs to the child's pgrp. */
556 ioctl (channel
, TCFLSH
, 1);
560 /* 3rd arg should be ignored
561 but some 4.2 kernels actually want the address of an int
562 and nonzero means something different. */
563 ioctl (channel
, TIOCFLUSH
, &zero
);
570 /* Set up the terminal at the other end of a pseudo-terminal that
571 we will be controlling an inferior through.
572 It should not echo or do line-editing, since that is done
573 in Emacs. No padding needed for insertion into an Emacs buffer. */
576 child_setup_tty (out
)
582 EMACS_GET_TTY (out
, &s
);
584 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
585 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
586 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
588 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
589 /* No output delays */
591 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
592 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
593 #if 0 /* This causes bugs in (for instance) telnet to certain sites. */
594 s
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
595 #ifdef INLCR /* Just being cautious, since I can't check how
596 widespread INLCR is--rms. */
597 s
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
601 s
.main
.c_iflag
&= ~IUCLC
; /* Disable downcasing on input. */
604 s
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
607 s
.main
.c_oflag
&= ~OLCUC
; /* Disable upcasing on output. */
609 s
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
610 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CSIZE
) | CS8
; /* Don't strip 8th bit */
612 /* Said to be unnecessary: */
613 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
614 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
617 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
618 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
619 s
.main
.c_cc
[VERASE
] = CDISABLE
; /* disable erase processing */
620 s
.main
.c_cc
[VKILL
] = CDISABLE
; /* disable kill processing */
623 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
627 /* AIX enhanced edit loses NULs, so disable it */
630 s
.main
.c_iflag
&= ~ASCEDIT
;
632 /* Also, PTY overloads NUL and BREAK.
633 don't ignore break, but don't signal either, so it looks like NUL. */
634 s
.main
.c_iflag
&= ~IGNBRK
;
635 s
.main
.c_iflag
&= ~BRKINT
;
636 /* QUIT and INTR work better as signals, so disable character forms */
637 s
.main
.c_cc
[VINTR
] = 0377;
638 #ifdef SIGNALS_VIA_CHARACTERS
639 /* the QUIT and INTR character are used in process_send_signal
640 so set them here to something useful. */
641 if (s
.main
.c_cc
[VQUIT
] == 0377)
642 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
643 if (s
.main
.c_cc
[VINTR
] == 0377)
644 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
645 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
646 /* QUIT and INTR work better as signals, so disable character forms */
647 s
.main
.c_cc
[VQUIT
] = 0377;
648 s
.main
.c_cc
[VINTR
] = 0377;
649 s
.main
.c_lflag
&= ~ISIG
;
650 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
651 s
.main
.c_cc
[VEOL
] = 0377;
652 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
655 #else /* not HAVE_TERMIO */
657 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
659 s
.main
.sg_flags
|= LPASS8
;
660 s
.main
.sg_erase
= 0377;
661 s
.main
.sg_kill
= 0377;
662 s
.lmode
= LLITOUT
| s
.lmode
; /* Don't strip 8th bit */
664 #endif /* not HAVE_TERMIO */
666 EMACS_SET_TTY (out
, &s
, 0);
675 ioctl (out
, FIOASYNC
, &zero
);
678 #endif /* not DOS_NT */
682 #endif /* subprocesses */
684 /* Record a signal code and the handler for it. */
688 SIGTYPE (*handler
) P_ ((int));
691 static void save_signal_handlers
P_ ((struct save_signal
*));
692 static void restore_signal_handlers
P_ ((struct save_signal
*));
694 /* Suspend the Emacs process; give terminal to its superior. */
700 /* "Foster" parentage allows emacs to return to a subprocess that attached
701 to the current emacs as a cheaper than starting a whole new process. This
702 is set up by KEPTEDITOR.COM. */
703 unsigned long parent_id
, foster_parent_id
;
706 fpid_string
= getenv ("EMACS_PARENT_PID");
707 if (fpid_string
!= NULL
)
709 sscanf (fpid_string
, "%x", &foster_parent_id
);
710 if (foster_parent_id
!= 0)
711 parent_id
= foster_parent_id
;
713 parent_id
= getppid ();
716 parent_id
= getppid ();
718 xfree (fpid_string
); /* On VMS, this was malloc'd */
720 if (parent_id
&& parent_id
!= 0xffffffff)
722 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
723 int status
= LIB$
ATTACH (&parent_id
) & 1;
724 signal (SIGINT
, oldsig
);
733 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
734 d_prompt
.a
= "Emacs: "; /* Just a reminder */
735 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
740 #if defined (SIGTSTP) && !defined (MSDOS)
743 int pgrp
= EMACS_GETPGRP (0);
744 EMACS_KILLPG (pgrp
, SIGTSTP
);
747 #else /* No SIGTSTP */
748 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
749 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
750 kill (getpid (), SIGQUIT
);
752 #else /* No SIGTSTP or USG_JOBCTRL */
754 /* On a system where suspending is not implemented,
755 instead fork a subshell and let it talk directly to the terminal
759 #endif /* no USG_JOBCTRL */
760 #endif /* no SIGTSTP */
764 /* Fork a subshell. */
771 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
773 char oldwd
[MAXPATHLEN
+1]; /* Fixed length is safe on MSDOS. */
776 struct save_signal saved_handlers
[5];
778 unsigned char *str
= 0;
781 saved_handlers
[0].code
= SIGINT
;
782 saved_handlers
[1].code
= SIGQUIT
;
783 saved_handlers
[2].code
= SIGTERM
;
785 saved_handlers
[3].code
= SIGIO
;
786 saved_handlers
[4].code
= 0;
788 saved_handlers
[3].code
= 0;
791 /* Mentioning current_buffer->buffer would mean including buffer.h,
792 which somehow wedges the hp compiler. So instead... */
794 dir
= intern ("default-directory");
795 if (NILP (Fboundp (dir
)))
797 dir
= Fsymbol_value (dir
);
801 dir
= expand_and_dir_to_file (Funhandled_file_name_directory (dir
), Qnil
);
802 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
803 len
= XSTRING (dir
)->size
;
804 bcopy (XSTRING (dir
)->data
, str
, len
);
805 if (str
[len
- 1] != '/') str
[len
++] = '/';
812 save_signal_handlers (saved_handlers
);
813 synch_process_alive
= 1;
814 #endif /* __DJGPP__ > 1 */
818 error ("Can't spawn subshell");
825 #ifdef DOS_NT /* MW, Aug 1993 */
828 sh
= (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
831 sh
= (char *) egetenv ("SHELL");
835 /* Use our buffer's default directory for the subshell. */
837 chdir ((char *) str
);
840 close_process_descs (); /* Close Emacs's pipes/ptys */
843 #ifdef SET_EMACS_PRIORITY
845 extern EMACS_INT emacs_priority
;
847 if (emacs_priority
< 0)
848 nice (-emacs_priority
);
852 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
854 char *epwd
= getenv ("PWD");
855 char old_pwd
[MAXPATHLEN
+1+4];
857 /* If PWD is set, pass it with corrected value. */
860 strcpy (old_pwd
, epwd
);
861 if (str
[len
- 1] == '/')
863 setenv ("PWD", str
, 1);
868 putenv (old_pwd
); /* restore previous value */
870 #if 0 /* This is also reported if last command executed in subshell failed, KFS */
872 report_file_error ("Can't execute subshell", Fcons (build_string (sh
), Qnil
));
874 #else /* not MSDOS */
876 /* Waits for process completion */
877 pid
= _spawnlp (_P_WAIT
, sh
, sh
, NULL
);
880 write (1, "Can't execute subshell", 22);
881 #else /* not WINDOWSNT */
883 write (1, "Can't execute subshell", 22);
885 #endif /* not WINDOWSNT */
886 #endif /* not MSDOS */
889 /* Do this now if we did not do it before. */
890 #if !defined (MSDOS) || __DJGPP__ == 1
891 save_signal_handlers (saved_handlers
);
892 synch_process_alive
= 1;
896 wait_for_termination (pid
);
898 restore_signal_handlers (saved_handlers
);
899 synch_process_alive
= 0;
902 #endif /* !macintosh */
905 save_signal_handlers (saved_handlers
)
906 struct save_signal
*saved_handlers
;
908 while (saved_handlers
->code
)
910 saved_handlers
->handler
911 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers
->code
, SIG_IGN
);
917 restore_signal_handlers (saved_handlers
)
918 struct save_signal
*saved_handlers
;
920 while (saved_handlers
->code
)
922 signal (saved_handlers
->code
, saved_handlers
->handler
);
936 old_fcntl_flags
= fcntl (fd
, F_GETFL
, 0) & ~FASYNC
;
937 fcntl (fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
939 interrupts_deferred
= 0;
948 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
953 if (read_socket_hook
)
957 sigunblock (sigmask (SIGWINCH
));
959 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
961 interrupts_deferred
= 0;
967 if (read_socket_hook
)
971 sigblock (sigmask (SIGWINCH
));
973 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
);
974 interrupts_deferred
= 1;
977 #else /* no FASYNC */
978 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
985 if (read_socket_hook
)
988 ioctl (input_fd
, FIOASYNC
, &on
);
989 interrupts_deferred
= 0;
997 if (read_socket_hook
)
1000 ioctl (input_fd
, FIOASYNC
, &off
);
1001 interrupts_deferred
= 1;
1004 #else /* not FASYNC, not STRIDE */
1008 #include <termios.h>
1016 if (read_socket_hook
)
1020 sigaddset (&st
, SIGIO
);
1021 ioctl (input_fd
, FIOASYNC
, &on
);
1022 interrupts_deferred
= 0;
1023 sigprocmask (SIG_UNBLOCK
, &st
, (sigset_t
*)0);
1031 if (read_socket_hook
)
1034 ioctl (input_fd
, FIOASYNC
, &off
);
1035 interrupts_deferred
= 1;
1038 #else /* ! _CX_UX */
1043 if (read_socket_hook
)
1046 croak ("request_sigio");
1052 if (read_socket_hook
)
1055 croak ("unrequest_sigio");
1061 #endif /* F_SETFL */
1063 /* Saving and restoring the process group of Emacs's terminal. */
1067 /* The process group of which Emacs was a member when it initially
1070 If Emacs was in its own process group (i.e. inherited_pgroup ==
1071 getpid ()), then we know we're running under a shell with job
1072 control (Emacs would never be run as part of a pipeline).
1075 If Emacs was not in its own process group, then we know we're
1076 running under a shell (or a caller) that doesn't know how to
1077 separate itself from Emacs (like sh). Emacs must be in its own
1078 process group in order to receive SIGIO correctly. In this
1079 situation, we put ourselves in our own pgroup, forcibly set the
1080 tty's pgroup to our pgroup, and make sure to restore and reinstate
1081 the tty's pgroup just like any other terminal setting. If
1082 inherited_group was not the tty's pgroup, then we'll get a
1083 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1084 it goes foreground in the future, which is what should happen. */
1085 int inherited_pgroup
;
1087 /* Split off the foreground process group to Emacs alone.
1088 When we are in the foreground, but not started in our own process
1089 group, redirect the TTY to point to our own process group. We need
1090 to be in our own process group to receive SIGIO properly. */
1092 narrow_foreground_group ()
1096 setpgrp (0, inherited_pgroup
);
1097 if (inherited_pgroup
!= me
)
1098 EMACS_SET_TTY_PGRP (input_fd
, &me
);
1102 /* Set the tty to our original foreground group. */
1104 widen_foreground_group ()
1106 if (inherited_pgroup
!= getpid ())
1107 EMACS_SET_TTY_PGRP (input_fd
, &inherited_pgroup
);
1108 setpgrp (0, inherited_pgroup
);
1111 #endif /* BSD_PGRPS */
1113 /* Getting and setting emacs_tty structures. */
1115 /* Set *TC to the parameters associated with the terminal FD.
1116 Return zero if all's well, or -1 if we ran into an error we
1117 couldn't deal with. */
1119 emacs_get_tty (fd
, settings
)
1121 struct emacs_tty
*settings
;
1123 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1125 /* We have those nifty POSIX tcmumbleattr functions. */
1126 bzero (&settings
->main
, sizeof (settings
->main
));
1127 if (tcgetattr (fd
, &settings
->main
) < 0)
1132 /* The SYSV-style interface? */
1133 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
1138 /* Vehemently Monstrous System? :-) */
1139 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
1140 &settings
->main
.class, 12, 0, 0, 0, 0)
1146 /* I give up - I hope you have the BSD ioctls. */
1147 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
1149 #endif /* not DOS_NT */
1154 /* Suivant - Do we have to get struct ltchars data? */
1156 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
1160 /* How about a struct tchars and a wordful of lmode bits? */
1162 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
1163 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
1167 /* We have survived the tempest. */
1172 /* Set the parameters of the tty on FD according to the contents of
1173 *SETTINGS. If FLUSHP is non-zero, we discard input.
1174 Return 0 if all went well, and -1 if anything failed. */
1177 emacs_set_tty (fd
, settings
, flushp
)
1179 struct emacs_tty
*settings
;
1182 /* Set the primary parameters - baud rate, character size, etcetera. */
1185 /* We have those nifty POSIX tcmumbleattr functions.
1186 William J. Smith <wjs@wiis.wang.com> writes:
1187 "POSIX 1003.1 defines tcsetattr to return success if it was
1188 able to perform any of the requested actions, even if some
1189 of the requested actions could not be performed.
1190 We must read settings back to ensure tty setup properly.
1191 AIX requires this to keep tty from hanging occasionally." */
1192 /* This make sure that we don't loop indefinitely in here. */
1193 for (i
= 0 ; i
< 10 ; i
++)
1194 if (tcsetattr (fd
, flushp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
1205 bzero (&new, sizeof (new));
1206 /* Get the current settings, and see if they're what we asked for. */
1207 tcgetattr (fd
, &new);
1208 /* We cannot use memcmp on the whole structure here because under
1209 * aix386 the termios structure has some reserved field that may
1212 if ( new.c_iflag
== settings
->main
.c_iflag
1213 && new.c_oflag
== settings
->main
.c_oflag
1214 && new.c_cflag
== settings
->main
.c_cflag
1215 && new.c_lflag
== settings
->main
.c_lflag
1216 && memcmp (new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
1224 /* The SYSV-style interface? */
1225 if (ioctl (fd
, flushp
? TCSETAF
: TCSETAW
, &settings
->main
) < 0)
1230 /* Vehemently Monstrous System? :-) */
1231 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
1232 &settings
->main
.class, 12, 0, 0, 0, 0)
1238 /* I give up - I hope you have the BSD ioctls. */
1239 if (ioctl (fd
, (flushp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
1241 #endif /* not DOS_NT */
1247 /* Suivant - Do we have to get struct ltchars data? */
1249 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
1253 /* How about a struct tchars and a wordful of lmode bits? */
1255 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
1256 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
1260 /* We have survived the tempest. */
1265 /* The initial tty mode bits */
1266 struct emacs_tty old_tty
;
1268 /* 1 if we have been through init_sys_modes. */
1271 /* 1 if outer tty status has been recorded. */
1275 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1280 #ifndef F_SETOWN_BUG
1282 int old_fcntl_owner
;
1283 #endif /* F_SETOWN */
1284 #endif /* F_SETOWN_BUG */
1286 /* This may also be defined in stdio,
1287 but if so, this does no harm,
1288 and using the same name avoids wasting the other one's space. */
1291 extern char *_sobuf
;
1293 #if defined (USG) || defined (DGUX)
1294 unsigned char _sobuf
[BUFSIZ
+8];
1296 char _sobuf
[BUFSIZ
];
1301 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
1304 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
1310 struct emacs_tty tty
;
1313 /* cus-start.el complains if delete-exited-processes is not defined */
1314 #ifndef subprocesses
1315 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes
,
1316 doc
: /* *Non-nil means delete processes immediately when they exit.
1317 nil means don't delete them until `list-processes' is run. */);
1318 delete_exited_processes
= 0;
1320 #endif /* not macintosh */
1324 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
1325 extern int (*interrupt_signal
) ();
1329 Vtty_erase_char
= Qnil
;
1336 input_ef
= get_kbd_event_flag ();
1337 /* LIB$GET_EF (&input_ef); */
1338 SYS$
CLREF (input_ef
);
1339 waiting_for_ast
= 0;
1341 timer_ef
= get_timer_event_flag ();
1342 /* LIB$GET_EF (&timer_ef); */
1343 SYS$
CLREF (timer_ef
);
1347 LIB$
GET_EF (&process_ef
);
1348 SYS$
CLREF (process_ef
);
1350 if (input_ef
/ 32 != process_ef
/ 32)
1351 croak ("Input and process event flags in different clusters.");
1353 if (input_ef
/ 32 != timer_ef
/ 32)
1354 croak ("Input and timer event flags in different clusters.");
1356 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1357 ((unsigned) 1 << (process_ef
% 32));
1359 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1360 ((unsigned) 1 << (timer_ef
% 32));
1362 sys_access_reinit ();
1364 #endif /* not VMS */
1367 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1368 narrow_foreground_group ();
1371 #ifdef HAVE_WINDOW_SYSTEM
1372 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1373 needs the initialization code below. */
1374 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1377 EMACS_GET_TTY (input_fd
, &old_tty
);
1383 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1384 XSETINT (Vtty_erase_char
, old_tty
.main
.c_cc
[VERASE
]);
1387 /* This allows meta to be sent on 8th bit. */
1388 tty
.main
.c_iflag
&= ~INPCK
; /* don't check input for parity */
1390 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1391 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1392 #ifdef INLCR /* I'm just being cautious,
1393 since I can't check how widespread INLCR is--rms. */
1394 tty
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
1397 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1399 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1400 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1402 tty
.main
.c_lflag
&= ~IEXTEN
; /* Disable other editing characters. */
1404 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1407 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1409 tty
.main
.c_iflag
&= ~IXANY
;
1413 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1414 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1416 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1420 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1421 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1424 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1425 /* Set up C-g for both SIGQUIT and SIGINT.
1426 We don't know which we will get, but we handle both alike
1427 so which one it really gives us does not matter. */
1428 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1429 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1430 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1432 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1436 #if defined (mips) || defined (HAVE_TCATTR)
1438 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1441 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1442 #endif /* V_DSUSP */
1443 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1444 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1447 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1450 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1451 #endif /* VREPRINT */
1453 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1454 #endif /* VWERASE */
1456 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1457 #endif /* VDISCARD */
1462 tty
.main
.c_cc
[VSTART
] = '\021';
1465 tty
.main
.c_cc
[VSTOP
] = '\023';
1471 tty
.main
.c_cc
[VSTART
] = CDISABLE
;
1474 tty
.main
.c_cc
[VSTOP
] = CDISABLE
;
1477 #endif /* mips or HAVE_TCATTR */
1479 #ifdef SET_LINE_DISCIPLINE
1480 /* Need to explicitly request TERMIODISC line discipline or
1481 Ultrix's termios does not work correctly. */
1482 tty
.main
.c_line
= SET_LINE_DISCIPLINE
;
1486 /* AIX enhanced edit loses NULs, so disable it. */
1487 tty
.main
.c_line
= 0;
1488 tty
.main
.c_iflag
&= ~ASCEDIT
;
1490 tty
.main
.c_cc
[VSTRT
] = 255;
1491 tty
.main
.c_cc
[VSTOP
] = 255;
1492 tty
.main
.c_cc
[VSUSP
] = 255;
1493 tty
.main
.c_cc
[VDSUSP
] = 255;
1494 #endif /* IBMR2AIX */
1498 tty
.main
.c_cc
[VSTART
] = '\021';
1501 tty
.main
.c_cc
[VSTOP
] = '\023';
1504 /* Also, PTY overloads NUL and BREAK.
1505 don't ignore break, but don't signal either, so it looks like NUL.
1506 This really serves a purpose only if running in an XTERM window
1507 or via TELNET or the like, but does no harm elsewhere. */
1508 tty
.main
.c_iflag
&= ~IGNBRK
;
1509 tty
.main
.c_iflag
&= ~BRKINT
;
1511 #else /* if not HAVE_TERMIO */
1513 tty
.main
.tt_char
|= TT$M_NOECHO
;
1515 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1517 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1519 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1520 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1521 #else /* not VMS (BSD, that is) */
1523 XSETINT (Vtty_erase_char
, tty
.main
.sg_erase
);
1524 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1526 tty
.main
.sg_flags
|= ANYP
;
1527 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1528 #endif /* not DOS_NT */
1529 #endif /* not VMS (BSD, that is) */
1530 #endif /* not HAVE_TERMIO */
1532 /* If going to use CBREAK mode, we must request C-g to interrupt
1533 and turn off start and stop chars, etc. If not going to use
1534 CBREAK mode, do this anyway so as to turn off local flow
1535 control for user coming over network on 4.2; in this case,
1536 only t_stopc and t_startc really matter. */
1539 /* Note: if not using CBREAK mode, it makes no difference how we
1541 tty
.tchars
= new_tchars
;
1542 tty
.tchars
.t_intrc
= quit_char
;
1545 tty
.tchars
.t_startc
= '\021';
1546 tty
.tchars
.t_stopc
= '\023';
1549 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1551 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1552 anything, and leaving it in breaks the meta key. Go figure. */
1553 tty
.lmode
&= ~LLITOUT
;
1560 #endif /* HAVE_TCHARS */
1561 #endif /* not HAVE_TERMIO */
1564 tty
.ltchars
= new_ltchars
;
1565 #endif /* HAVE_LTCHARS */
1566 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1568 internal_terminal_init ();
1572 EMACS_SET_TTY (input_fd
, &tty
, 0);
1574 /* This code added to insure that, if flow-control is not to be used,
1575 we have an unlocked terminal at the start. */
1578 if (!flow_control
) ioctl (input_fd
, TCXONC
, 1);
1582 if (!flow_control
) ioctl (input_fd
, TIOCSTART
, 0);
1586 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1588 if (!flow_control
) tcflow (input_fd
, TCOON
);
1596 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1597 to be only LF. This is the way that is done. */
1600 if (ioctl (1, HFTGETID
, &tty
) != -1)
1601 write (1, "\033[20l", 5);
1607 /* Appears to do nothing when in PASTHRU mode.
1608 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1609 interrupt_signal, oob_chars, 0, 0, 0, 0);
1611 queue_kbd_input (0);
1616 #ifndef F_SETOWN_BUG
1617 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1619 && ! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1621 old_fcntl_owner
= fcntl (input_fd
, F_GETOWN
, 0);
1622 fcntl (input_fd
, F_SETOWN
, getpid ());
1623 init_sigio (input_fd
);
1625 #endif /* F_GETOWN */
1626 #endif /* F_SETOWN_BUG */
1627 #endif /* F_SETFL */
1630 if (interrupt_input
)
1631 init_sigio (input_fd
);
1634 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1638 /* This symbol is defined on recent USG systems.
1639 Someone says without this call USG won't really buffer the file
1640 even with a call to setbuf. */
1641 setvbuf (stdout
, (char *) _sobuf
, _IOFBF
, sizeof _sobuf
);
1643 setbuf (stdout
, (char *) _sobuf
);
1645 #ifdef HAVE_WINDOW_SYSTEM
1646 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1647 needs the initialization code below. */
1648 if (EQ (Vwindow_system
, Qnil
)
1650 /* When running in tty mode on NT/Win95, we have a read_socket
1651 hook, but still need the rest of the initialization code below. */
1652 && (! read_socket_hook
)
1656 set_terminal_modes ();
1659 && FRAMEP (Vterminal_frame
)
1660 && FRAME_TERMCAP_P (XFRAME (Vterminal_frame
)))
1661 init_frame_faces (XFRAME (Vterminal_frame
));
1663 if (term_initted
&& no_redraw_on_reenter
)
1665 if (display_completed
)
1666 direct_output_forward_char (0);
1671 if (FRAMEP (Vterminal_frame
))
1672 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1678 /* Return nonzero if safe to use tabs in output.
1679 At the time this is called, init_sys_modes has not been done yet. */
1684 struct emacs_tty tty
;
1686 EMACS_GET_TTY (input_fd
, &tty
);
1687 return EMACS_TTY_TABS_OK (&tty
);
1690 /* Get terminal size from system.
1691 Store number of lines into *HEIGHTP and width into *WIDTHP.
1692 We store 0 if there's no valid information. */
1695 get_frame_size (widthp
, heightp
)
1696 int *widthp
, *heightp
;
1702 struct winsize size
;
1704 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1705 *widthp
= *heightp
= 0;
1708 *widthp
= size
.ws_col
;
1709 *heightp
= size
.ws_row
;
1715 /* SunOS - style. */
1716 struct ttysize size
;
1718 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1719 *widthp
= *heightp
= 0;
1722 *widthp
= size
.ts_cols
;
1723 *heightp
= size
.ts_lines
;
1729 struct sensemode tty
;
1731 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1732 &tty
.class, 12, 0, 0, 0, 0);
1733 *widthp
= tty
.scr_wid
;
1734 *heightp
= tty
.scr_len
;
1738 *widthp
= ScreenCols ();
1739 *heightp
= ScreenRows ();
1740 #else /* system doesn't know size */
1745 #endif /* not VMS */
1746 #endif /* not SunOS-style */
1747 #endif /* not BSD-style */
1750 /* Set the logical window size associated with descriptor FD
1751 to HEIGHT and WIDTH. This is used mainly with ptys. */
1754 set_window_size (fd
, height
, width
)
1755 int fd
, height
, width
;
1760 struct winsize size
;
1761 size
.ws_row
= height
;
1762 size
.ws_col
= width
;
1764 if (ioctl (fd
, TIOCSWINSZ
, &size
) == -1)
1765 return 0; /* error */
1772 /* SunOS - style. */
1773 struct ttysize size
;
1774 size
.ts_lines
= height
;
1775 size
.ts_cols
= width
;
1777 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1783 #endif /* not SunOS-style */
1784 #endif /* not BSD-style */
1788 /* Prepare the terminal for exiting Emacs; move the cursor to the
1789 bottom of the frame, turn off interrupt-driven I/O, etc. */
1802 #ifdef HAVE_WINDOW_SYSTEM
1803 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1804 needs the clean-up code below. */
1805 if (!EQ (Vwindow_system
, Qnil
)
1807 /* When running in tty mode on NT/Win95, we have a read_socket
1808 hook, but still need the rest of the clean-up code below. */
1814 sf
= SELECTED_FRAME ();
1815 cursor_to (FRAME_HEIGHT (sf
) - 1, 0);
1816 clear_end_of_line (FRAME_WIDTH (sf
));
1817 /* clear_end_of_line may move the cursor */
1818 cursor_to (FRAME_HEIGHT (sf
) - 1, 0);
1819 #if defined (IBMR2AIX) && defined (AIXHFT)
1821 /* HFT devices normally use ^J as a LF/CR. We forced it to
1822 do the LF only. Now, we need to reset it. */
1825 if (ioctl (1, HFTGETID
, &tty
) != -1)
1826 write (1, "\033[20h", 5);
1830 reset_terminal_modes ();
1834 /* Avoid possible loss of output when changing terminal modes. */
1835 fsync (fileno (stdout
));
1840 #ifndef F_SETOWN_BUG
1841 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1842 if (interrupt_input
)
1845 fcntl (input_fd
, F_SETOWN
, old_fcntl_owner
);
1847 #endif /* F_SETOWN */
1848 #endif /* F_SETOWN_BUG */
1850 fcntl (input_fd
, F_SETFL
, fcntl (input_fd
, F_GETFL
, 0) & ~O_NDELAY
);
1852 #endif /* F_SETFL */
1854 if (interrupt_input
)
1859 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1862 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1866 #ifdef SET_LINE_DISCIPLINE
1867 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1868 A different old line discipline is therefore not restored, yet.
1869 Restore the old line discipline by hand. */
1870 ioctl (0, TIOCSETD
, &old_tty
.main
.c_line
);
1878 widen_foreground_group ();
1884 /* Set up the proper status flags for use of a pty. */
1890 /* I'm told that TOICREMOTE does not mean control chars
1891 "can't be sent" but rather that they don't have
1892 input-editing or signaling effects.
1893 That should be good, because we have other ways
1894 to do those things in Emacs.
1895 However, telnet mode seems not to work on 4.2.
1896 So TIOCREMOTE is turned off now. */
1898 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1899 will hang. In particular, the "timeout" feature (which
1900 causes a read to return if there is no data available)
1901 does this. Also it is known that telnet mode will hang
1902 in such a way that Emacs must be stopped (perhaps this
1903 is the same problem).
1905 If TIOCREMOTE is turned off, then there is a bug in
1906 hp-ux which sometimes loses data. Apparently the
1907 code which blocks the master process when the internal
1908 buffer fills up does not work. Other than this,
1909 though, everything else seems to work fine.
1911 Since the latter lossage is more benign, we may as well
1912 lose that way. -- cph */
1914 #if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
1917 ioctl (fd
, FIONBIO
, &on
);
1922 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1923 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1924 /* cause EMACS not to die when it should, i.e., when its own controlling */
1925 /* tty goes away. I've complained to the AIX developers, and they may */
1926 /* change this behavior, but I'm not going to hold my breath. */
1927 signal (SIGHUP
, SIG_IGN
);
1930 #endif /* HAVE_PTYS */
1934 /* Assigning an input channel is done at the start of Emacs execution.
1935 This is called each time Emacs is resumed, also, but does nothing
1936 because input_chain is no longer zero. */
1945 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1951 /* Deassigning the input channel is done before exiting. */
1956 return SYS$
DASSGN (input_fd
);
1961 /* Request reading one character into the keyboard buffer.
1962 This is done as soon as the buffer becomes empty. */
1968 extern kbd_input_ast ();
1970 waiting_for_ast
= 0;
1972 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1973 &input_iosb
, kbd_input_ast
, 1,
1974 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1979 /* Ast routine that is called when keyboard input comes in
1980 in accord with the SYS$QIO above. */
1985 register int c
= -1;
1986 int old_errno
= errno
;
1987 extern EMACS_TIME
*input_available_clear_time
;
1989 if (waiting_for_ast
)
1990 SYS$
SETEF (input_ef
);
1991 waiting_for_ast
= 0;
1994 if (input_count
== 25)
1996 printf ("Ast # %d,", input_count
);
1997 printf (" iosb = %x, %x, %x, %x",
1998 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
2001 if (input_iosb
.offset
)
2005 printf (", char = 0%o", c
);
2017 struct input_event e
;
2018 e
.kind
= ascii_keystroke
;
2019 XSETINT (e
.code
, c
);
2020 e
.frame_or_window
= selected_frame
;
2021 kbd_buffer_store_event (&e
);
2023 if (input_available_clear_time
)
2024 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
2028 /* Wait until there is something in kbd_buffer. */
2031 wait_for_kbd_input ()
2033 extern int have_process_input
, process_exited
;
2035 /* If already something, avoid doing system calls. */
2036 if (detect_input_pending ())
2040 /* Clear a flag, and tell ast routine above to set it. */
2041 SYS$
CLREF (input_ef
);
2042 waiting_for_ast
= 1;
2043 /* Check for timing error: ast happened while we were doing that. */
2044 if (!detect_input_pending ())
2046 /* No timing error: wait for flag to be set. */
2047 set_waiting_for_input (0);
2048 SYS$
WFLOR (input_ef
, input_eflist
);
2049 clear_waiting_for_input ();
2050 if (!detect_input_pending ())
2051 /* Check for subprocess input availability */
2053 int dsp
= have_process_input
|| process_exited
;
2055 SYS$
CLREF (process_ef
);
2056 if (have_process_input
)
2057 process_command_input ();
2062 update_mode_lines
++;
2063 prepare_menu_bars ();
2064 redisplay_preserve_echo_area (18);
2068 waiting_for_ast
= 0;
2071 /* Get rid of any pending QIO, when we are about to suspend
2072 or when we want to throw away pending input.
2073 We wait for a positive sign that the AST routine has run
2074 and therefore there is no I/O request queued when we return.
2075 SYS$SETAST is used to avoid a timing error. */
2081 printf ("At end_kbd_input.\n");
2085 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2087 SYS$
CANCEL (input_fd
);
2092 /* Clear a flag, and tell ast routine above to set it. */
2093 SYS$
CLREF (input_ef
);
2094 waiting_for_ast
= 1;
2096 SYS$
CANCEL (input_fd
);
2098 SYS$
WAITFR (input_ef
);
2099 waiting_for_ast
= 0;
2102 /* Wait for either input available or time interval expiry. */
2105 input_wait_timeout (timeval
)
2106 int timeval
; /* Time to wait, in seconds */
2109 static int zero
= 0;
2110 static int large
= -10000000;
2112 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2114 /* If already something, avoid doing system calls. */
2115 if (detect_input_pending ())
2119 /* Clear a flag, and tell ast routine above to set it. */
2120 SYS$
CLREF (input_ef
);
2121 waiting_for_ast
= 1;
2122 /* Check for timing error: ast happened while we were doing that. */
2123 if (!detect_input_pending ())
2125 /* No timing error: wait for flag to be set. */
2127 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2128 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
2130 waiting_for_ast
= 0;
2133 /* The standard `sleep' routine works some other way
2134 and it stops working if you have ever quit out of it.
2135 This one continues to work. */
2141 static int zero
= 0;
2142 static int large
= -10000000;
2144 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2147 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2148 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
2166 croak ("request sigio");
2172 croak ("unrequest sigio");
2177 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2182 #ifndef SYSTEM_MALLOC
2189 /* Some systems that cannot dump also cannot implement these. */
2192 * Return the address of the start of the text segment prior to
2193 * doing an unexec. After unexec the return value is undefined.
2194 * See crt0.c for further explanation and _start.
2198 #if !(defined (__NetBSD__) && defined (__ELF__))
2199 #ifndef HAVE_TEXT_START
2204 return ((char *) TEXT_START
);
2208 return ((char *) csrt
);
2209 #else /* not GOULD */
2210 extern int _start ();
2211 return ((char *) _start
);
2213 #endif /* TEXT_START */
2215 #endif /* not HAVE_TEXT_START */
2219 * Return the address of the start of the data segment prior to
2220 * doing an unexec. After unexec the return value is undefined.
2221 * See crt0.c for further information and definition of data_start.
2223 * Apparently, on BSD systems this is etext at startup. On
2224 * USG systems (swapping) this is highly mmu dependent and
2225 * is also dependent on whether or not the program is running
2226 * with shared text. Generally there is a (possibly large)
2227 * gap between end of text and start of data with shared text.
2229 * On Uniplus+ systems with shared text, data starts at a
2230 * fixed address. Each port (from a given oem) is generally
2231 * different, and the specific value of the start of data can
2232 * be obtained via the UniPlus+ specific "uvar" system call,
2233 * however the method outlined in crt0.c seems to be more portable.
2235 * Probably what will have to happen when a USG unexec is available,
2236 * at least on UniPlus, is temacs will have to be made unshared so
2237 * that text and data are contiguous. Then once loadup is complete,
2238 * unexec will produce a shared executable where the data can be
2239 * at the normal shared text boundary and the startofdata variable
2240 * will be patched by unexec to the correct value.
2248 return ((char *) DATA_START
);
2250 #ifdef ORDINARY_LINK
2252 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2253 * data_start isn't defined. We take the address of environ, which
2254 * is known to live at or near the start of the system crt0.c, and
2255 * we don't sweat the handful of bytes that might lose.
2257 extern char **environ
;
2259 return ((char *) &environ
);
2261 extern int data_start
;
2262 return ((char *) &data_start
);
2263 #endif /* ORDINARY_LINK */
2264 #endif /* DATA_START */
2266 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2269 /* Some systems that cannot dump also cannot implement these. */
2272 * Return the address of the end of the text segment prior to
2273 * doing an unexec. After unexec the return value is undefined.
2280 return ((char *) TEXT_END
);
2283 return ((char *) &etext
);
2288 * Return the address of the end of the data segment prior to
2289 * doing an unexec. After unexec the return value is undefined.
2296 return ((char *) DATA_END
);
2299 return ((char *) &edata
);
2303 #endif /* not CANNOT_DUMP */
2305 /* init_system_name sets up the string for the Lisp function
2306 system-name to return. */
2312 extern Lisp_Object Vsystem_name
;
2317 #include <sys/socket.h>
2319 #endif /* HAVE_SOCKETS */
2320 #endif /* not VMS */
2321 #endif /* not BSD4_1 */
2324 #ifndef HAVE_H_ERRNO
2327 #endif /* TRY_AGAIN */
2333 Vsystem_name
= build_string (sysname
);
2337 if ((sp
= egetenv ("SYS$NODE")) == 0)
2338 Vsystem_name
= build_string ("vax-vms");
2339 else if ((end
= index (sp
, ':')) == 0)
2340 Vsystem_name
= build_string (sp
);
2342 Vsystem_name
= make_string (sp
, end
- sp
);
2344 #ifndef HAVE_GETHOSTNAME
2347 Vsystem_name
= build_string (uts
.nodename
);
2348 #else /* HAVE_GETHOSTNAME */
2349 unsigned int hostname_size
= 256;
2350 char *hostname
= (char *) alloca (hostname_size
);
2352 /* Try to get the host name; if the buffer is too short, try
2353 again. Apparently, the only indication gethostname gives of
2354 whether the buffer was large enough is the presence or absence
2355 of a '\0' in the string. Eech. */
2358 gethostname (hostname
, hostname_size
- 1);
2359 hostname
[hostname_size
- 1] = '\0';
2361 /* Was the buffer large enough for the '\0'? */
2362 if (strlen (hostname
) < hostname_size
- 1)
2365 hostname_size
<<= 1;
2366 hostname
= (char *) alloca (hostname_size
);
2369 /* Turn the hostname into the official, fully-qualified hostname.
2370 Don't do this if we're going to dump; this can confuse system
2371 libraries on some machines and make the dumped emacs core dump. */
2374 #endif /* not CANNOT_DUMP */
2375 if (! index (hostname
, '.'))
2379 for (count
= 0;; count
++)
2384 hp
= gethostbyname (hostname
);
2386 if (! (hp
== 0 && h_errno
== TRY_AGAIN
))
2391 Fsleep_for (make_number (1), Qnil
);
2395 char *fqdn
= (char *) hp
->h_name
;
2400 if (!index (fqdn
, '.'))
2402 /* We still don't have a fully qualified domain name.
2403 Try to find one in the list of alternate names */
2404 char **alias
= hp
->h_aliases
;
2405 while (*alias
&& !index (*alias
, '.'))
2412 /* Convert the host name to lower case. */
2413 /* Using ctype.h here would introduce a possible locale
2414 dependence that is probably wrong for hostnames. */
2418 if (*p
>= 'A' && *p
<= 'Z')
2425 #endif /* HAVE_SOCKETS */
2426 /* We used to try using getdomainname here,
2427 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2428 getdomainname gets the NIS/YP domain which often is not the same
2429 as in Internet domain name. */
2430 #if 0 /* Turned off because sysinfo is not really likely to return the
2431 correct Internet domain. */
2432 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2433 if (! index (hostname
, '.'))
2435 /* The hostname is not fully qualified. Append the domain name. */
2437 int hostlen
= strlen (hostname
);
2438 int domain_size
= 256;
2442 char *domain
= (char *) alloca (domain_size
+ 1);
2443 char *fqdn
= (char *) alloca (hostlen
+ 1 + domain_size
+ 1);
2444 int sys_domain_size
= sysinfo (SI_SRPC_DOMAIN
, domain
, domain_size
);
2445 if (sys_domain_size
<= 0)
2447 if (domain_size
< sys_domain_size
)
2449 domain_size
= sys_domain_size
;
2452 strcpy (fqdn
, hostname
);
2453 if (domain
[0] == '.')
2454 strcpy (fqdn
+ hostlen
, domain
);
2455 else if (domain
[0] != 0)
2457 fqdn
[hostlen
] = '.';
2458 strcpy (fqdn
+ hostlen
+ 1, domain
);
2464 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2466 Vsystem_name
= build_string (hostname
);
2467 #endif /* HAVE_GETHOSTNAME */
2472 for (p
= XSTRING (Vsystem_name
)->data
; *p
; p
++)
2473 if (*p
== ' ' || *p
== '\t')
2480 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2482 #include "sysselect.h"
2485 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2486 /* Cause explanatory error message at compile time,
2487 since the select emulation is not good enough for X. */
2488 int *x
= &x_windows_lose_if_no_select_system_call
;
2491 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2492 * Only checks read descriptors.
2494 /* How long to wait between checking fds in select */
2495 #define SELECT_PAUSE 1
2498 /* For longjmp'ing back to read_input_waiting. */
2500 jmp_buf read_alarm_throw
;
2502 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2503 The read_socket_hook function sets this to 1 while it is waiting. */
2505 int read_alarm_should_throw
;
2513 #else /* not BSD4_1 */
2514 signal (SIGALRM
, SIG_IGN
);
2515 #endif /* not BSD4_1 */
2516 if (read_alarm_should_throw
)
2517 longjmp (read_alarm_throw
, 1);
2521 /* Only rfds are checked. */
2523 sys_select (nfds
, rfds
, wfds
, efds
, timeout
)
2525 SELECT_TYPE
*rfds
, *wfds
, *efds
;
2526 EMACS_TIME
*timeout
;
2532 extern int proc_buffered_char
[];
2533 #ifndef subprocesses
2534 int process_tick
= 0, update_tick
= 0;
2536 extern int process_tick
, update_tick
;
2540 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2541 /* If we're using X, then the native select will work; we only need the
2542 emulation for non-X usage. */
2543 if (!NILP (Vwindow_system
))
2544 return select (nfds
, rfds
, wfds
, efds
, timeout
);
2546 timeoutval
= timeout
? EMACS_SECS (*timeout
) : 100000;
2547 local_timeout
= &timeoutval
;
2559 /* If we are looking only for the terminal, with no timeout,
2560 just read it and wait -- that's more efficient. */
2561 if (*local_timeout
== 100000 && process_tick
== update_tick
2562 && FD_ISSET (0, &orfds
))
2565 for (fd
= 1; fd
< nfds
; ++fd
)
2566 if (FD_ISSET (fd
, &orfds
))
2568 if (! detect_input_pending ())
2569 read_input_waiting ();
2575 /* Once a second, till the timer expires, check all the flagged read
2576 * descriptors to see if any input is available. If there is some then
2577 * set the corresponding bit in the return copy of rfds.
2581 register int to_check
, fd
;
2585 for (to_check
= nfds
, fd
= 0; --to_check
>= 0; fd
++)
2587 if (FD_ISSET (fd
, &orfds
))
2589 int avail
= 0, status
= 0;
2592 avail
= detect_input_pending (); /* Special keyboard handler */
2596 status
= ioctl (fd
, FIONREAD
, &avail
);
2597 #else /* no FIONREAD */
2598 /* Hoping it will return -1 if nothing available
2599 or 0 if all 0 chars requested are read. */
2600 if (proc_buffered_char
[fd
] >= 0)
2604 avail
= read (fd
, &buf
, 1);
2606 proc_buffered_char
[fd
] = buf
;
2608 #endif /* no FIONREAD */
2610 if (status
>= 0 && avail
> 0)
2618 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2621 turn_on_atimers (0);
2622 signal (SIGALRM
, select_alarm
);
2624 alarm (SELECT_PAUSE
);
2626 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2627 while (select_alarmed
== 0 && *local_timeout
!= 0
2628 && process_tick
== update_tick
)
2630 /* If we are interested in terminal input,
2631 wait by reading the terminal.
2632 That makes instant wakeup for terminal input at least. */
2633 if (FD_ISSET (0, &orfds
))
2635 read_input_waiting ();
2636 if (detect_input_pending ())
2642 (*local_timeout
) -= SELECT_PAUSE
;
2644 /* Reset the old alarm if there was one. */
2645 turn_on_atimers (1);
2647 if (*local_timeout
== 0) /* Stop on timer being cleared */
2652 #endif /* not WINDOWSNT */
2654 /* Read keyboard input into the standard buffer,
2655 waiting for at least one character. */
2657 /* Make all keyboard buffers much bigger when using a window system. */
2658 #ifdef HAVE_WINDOW_SYSTEM
2659 #define BUFFER_SIZE_FACTOR 16
2661 #define BUFFER_SIZE_FACTOR 1
2665 read_input_waiting ()
2667 struct input_event e
;
2669 extern int quit_char
;
2671 if (read_socket_hook
)
2673 struct input_event buf
[256];
2675 read_alarm_should_throw
= 0;
2676 if (! setjmp (read_alarm_throw
))
2677 nread
= (*read_socket_hook
) (0, buf
, 256, 1);
2681 /* Scan the chars for C-g and store them in kbd_buffer. */
2682 for (i
= 0; i
< nread
; i
++)
2684 kbd_buffer_store_event (&buf
[i
]);
2685 /* Don't look at input that follows a C-g too closely.
2686 This reduces lossage due to autorepeat on C-g. */
2687 if (buf
[i
].kind
== ascii_keystroke
2688 && buf
[i
].code
== quit_char
)
2695 nread
= read (fileno (stdin
), buf
, 1);
2697 /* Scan the chars for C-g and store them in kbd_buffer. */
2698 e
.kind
= ascii_keystroke
;
2699 e
.frame_or_window
= selected_frame
;
2701 for (i
= 0; i
< nread
; i
++)
2703 /* Convert chars > 0177 to meta events if desired.
2704 We do this under the same conditions that read_avail_input does. */
2705 if (read_socket_hook
== 0)
2707 /* If the user says she has a meta key, then believe her. */
2708 if (meta_key
== 1 && (buf
[i
] & 0x80))
2709 e
.modifiers
= meta_modifier
;
2714 XSETINT (e
.code
, buf
[i
]);
2715 kbd_buffer_store_event (&e
);
2716 /* Don't look at input that follows a C-g too closely.
2717 This reduces lossage due to autorepeat on C-g. */
2718 if (buf
[i
] == quit_char
)
2724 #endif /* not HAVE_SELECT */
2725 #endif /* not VMS */
2726 #endif /* not MSDOS */
2735 lmode
= LINTRUP
| lmode
;
2736 ioctl (fd
, TIOCLSET
, &lmode
);
2744 lmode
= ~LINTRUP
& lmode
;
2745 ioctl (0, TIOCLSET
, &lmode
);
2753 interrupts_deferred
= 0;
2761 interrupts_deferred
= 1;
2764 /* still inside #ifdef BSD4_1 */
2767 int sigheld
; /* Mask of held signals */
2773 sigheld
|= sigbit (signum
);
2781 sigheld
|= sigbit (signum
);
2788 sigheld
&= ~sigbit (signum
);
2793 sigfree () /* Free all held signals */
2796 for (i
= 0; i
< NSIG
; i
++)
2797 if (sigheld
& sigbit (i
))
2805 return 1 << (i
- 1);
2807 #endif /* subprocesses */
2810 /* POSIX signals support - DJB */
2811 /* Anyone with POSIX signals should have ANSI C declarations */
2813 #ifdef POSIX_SIGNALS
2815 sigset_t empty_mask
, full_mask
;
2818 sys_signal (int signal_number
, signal_handler_t action
)
2820 struct sigaction new_action
, old_action
;
2821 sigemptyset (&new_action
.sa_mask
);
2822 new_action
.sa_handler
= action
;
2824 /* Emacs mostly works better with restartable system services. If this
2825 * flag exists, we probably want to turn it on here.
2827 new_action
.sa_flags
= SA_RESTART
;
2829 new_action
.sa_flags
= 0;
2831 sigaction (signal_number
, &new_action
, &old_action
);
2832 return (old_action
.sa_handler
);
2836 /* If we're compiling with GCC, we don't need this function, since it
2837 can be written as a macro. */
2839 sys_sigmask (int sig
)
2842 sigemptyset (&mask
);
2843 sigaddset (&mask
, sig
);
2848 /* I'd like to have these guys return pointers to the mask storage in here,
2849 but there'd be trouble if the code was saving multiple masks. I'll be
2850 safe and pass the structure. It normally won't be more than 2 bytes
2854 sys_sigblock (sigset_t new_mask
)
2857 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2862 sys_sigunblock (sigset_t new_mask
)
2865 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2870 sys_sigsetmask (sigset_t new_mask
)
2873 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2877 #endif /* POSIX_SIGNALS */
2879 #if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
2880 static char *my_sys_siglist
[NSIG
];
2884 # define sys_siglist my_sys_siglist
2890 #ifdef POSIX_SIGNALS
2891 sigemptyset (&empty_mask
);
2892 sigfillset (&full_mask
);
2895 #if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
2899 sys_siglist
[SIGABRT
] = "Aborted";
2902 sys_siglist
[SIGAIO
] = "LAN I/O interrupt";
2905 sys_siglist
[SIGALRM
] = "Alarm clock";
2908 sys_siglist
[SIGBUS
] = "Bus error";
2911 sys_siglist
[SIGCLD
] = "Child status changed";
2914 sys_siglist
[SIGCHLD
] = "Child status changed";
2917 sys_siglist
[SIGCONT
] = "Continued";
2920 sys_siglist
[SIGDANGER
] = "Swap space dangerously low";
2923 sys_siglist
[SIGDGNOTIFY
] = "Notification message in queue";
2926 sys_siglist
[SIGEMT
] = "Emulation trap";
2929 sys_siglist
[SIGFPE
] = "Arithmetic exception";
2932 sys_siglist
[SIGFREEZE
] = "SIGFREEZE";
2935 sys_siglist
[SIGGRANT
] = "Monitor mode granted";
2938 sys_siglist
[SIGHUP
] = "Hangup";
2941 sys_siglist
[SIGILL
] = "Illegal instruction";
2944 sys_siglist
[SIGINT
] = "Interrupt";
2947 sys_siglist
[SIGIO
] = "I/O possible";
2950 sys_siglist
[SIGIOINT
] = "I/O intervention required";
2953 sys_siglist
[SIGIOT
] = "IOT trap";
2956 sys_siglist
[SIGKILL
] = "Killed";
2959 sys_siglist
[SIGLOST
] = "Resource lost";
2962 sys_siglist
[SIGLWP
] = "SIGLWP";
2965 sys_siglist
[SIGMSG
] = "Monitor mode data available";
2968 sys_siglist
[SIGWIND
] = "SIGPHONE";
2971 sys_siglist
[SIGPIPE
] = "Broken pipe";
2974 sys_siglist
[SIGPOLL
] = "Pollable event occurred";
2977 sys_siglist
[SIGPROF
] = "Profiling timer expired";
2980 sys_siglist
[SIGPTY
] = "PTY I/O interrupt";
2983 sys_siglist
[SIGPWR
] = "Power-fail restart";
2986 sys_siglist
[SIGQUIT
] = "Quit";
2989 sys_siglist
[SIGRETRACT
] = "Need to relinguish monitor mode";
2992 sys_siglist
[SIGSAK
] = "Secure attention";
2995 sys_siglist
[SIGSEGV
] = "Segmentation violation";
2998 sys_siglist
[SIGSOUND
] = "Sound completed";
3001 sys_siglist
[SIGSTOP
] = "Stopped (signal)";
3004 sys_siglist
[SIGSTP
] = "Stopped (user)";
3007 sys_siglist
[SIGSYS
] = "Bad argument to system call";
3010 sys_siglist
[SIGTERM
] = "Terminated";
3013 sys_siglist
[SIGTHAW
] = "SIGTHAW";
3016 sys_siglist
[SIGTRAP
] = "Trace/breakpoint trap";
3019 sys_siglist
[SIGTSTP
] = "Stopped (user)";
3022 sys_siglist
[SIGTTIN
] = "Stopped (tty input)";
3025 sys_siglist
[SIGTTOU
] = "Stopped (tty output)";
3028 sys_siglist
[SIGURG
] = "Urgent I/O condition";
3031 sys_siglist
[SIGUSR1
] = "User defined signal 1";
3034 sys_siglist
[SIGUSR2
] = "User defined signal 2";
3037 sys_siglist
[SIGVTALRM
] = "Virtual timer expired";
3040 sys_siglist
[SIGWAITING
] = "Process's LWPs are blocked";
3043 sys_siglist
[SIGWINCH
] = "Window size changed";
3046 sys_siglist
[SIGWIND
] = "SIGWIND";
3049 sys_siglist
[SIGXCPU
] = "CPU time limit exceeded";
3052 sys_siglist
[SIGXFSZ
] = "File size limit exceeded";
3055 #endif /* !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED */
3064 /* Figure out how many bits the system's random number generator uses.
3065 `random' and `lrand48' are assumed to return 31 usable bits.
3066 BSD `rand' returns a 31 bit value but the low order bits are unusable;
3067 so we'll shift it and treat it like the 15-bit USG `rand'. */
3071 # define RAND_BITS 31
3072 # else /* !HAVE_RANDOM */
3073 # ifdef HAVE_LRAND48
3074 # define RAND_BITS 31
3075 # define random lrand48
3076 # else /* !HAVE_LRAND48 */
3077 # define RAND_BITS 15
3078 # if RAND_MAX == 32767
3079 # define random rand
3080 # else /* RAND_MAX != 32767 */
3081 # if RAND_MAX == 2147483647
3082 # define random() (rand () >> 16)
3083 # else /* RAND_MAX != 2147483647 */
3085 # define random rand
3087 # define random() (rand () >> 16)
3089 # endif /* RAND_MAX != 2147483647 */
3090 # endif /* RAND_MAX != 32767 */
3091 # endif /* !HAVE_LRAND48 */
3092 # endif /* !HAVE_RANDOM */
3093 #endif /* !RAND_BITS */
3100 srandom ((unsigned int)arg
);
3102 # ifdef HAVE_LRAND48
3105 srand ((unsigned int)arg
);
3111 * Build a full Emacs-sized word out of whatever we've got.
3112 * This suffices even for a 64-bit architecture with a 15-bit rand.
3117 long val
= random ();
3118 #if VALBITS > RAND_BITS
3119 val
= (val
<< RAND_BITS
) ^ random ();
3120 #if VALBITS > 2*RAND_BITS
3121 val
= (val
<< RAND_BITS
) ^ random ();
3122 #if VALBITS > 3*RAND_BITS
3123 val
= (val
<< RAND_BITS
) ^ random ();
3124 #if VALBITS > 4*RAND_BITS
3125 val
= (val
<< RAND_BITS
) ^ random ();
3126 #endif /* need at least 5 */
3127 #endif /* need at least 4 */
3128 #endif /* need at least 3 */
3129 #endif /* need at least 2 */
3130 return val
& ((1L << VALBITS
) - 1);
3133 #ifdef WRONG_NAME_INSQUE
3146 /* If any place else asks for the TERM variable,
3147 allow it to be overridden with the EMACS_TERM variable
3148 before attempting to translate the logical name TERM. As a last
3149 resort, ask for VAX C's special idea of the TERM variable. */
3156 static char buf
[256];
3157 static struct dsc$descriptor_s equiv
3158 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
3159 static struct dsc$descriptor_s d_name
3160 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
3163 if (!strcmp (name
, "TERM"))
3165 val
= (char *) getenv ("EMACS_TERM");
3170 d_name
.dsc$w_length
= strlen (name
);
3171 d_name
.dsc$a_pointer
= name
;
3172 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
3174 char *str
= (char *) xmalloc (eqlen
+ 1);
3175 bcopy (buf
, str
, eqlen
);
3177 /* This is a storage leak, but a pain to fix. With luck,
3178 no one will ever notice. */
3181 return (char *) getenv (name
);
3186 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
3187 to force a call on the debugger from within the image. */
3192 LIB$
SIGNAL (SS$_DEBUG
);
3198 #ifdef LINK_CRTL_SHARE
3199 #ifdef SHARABLE_LIB_BUG
3200 /* Variables declared noshare and initialized in sharable libraries
3201 cannot be shared. The VMS linker incorrectly forces you to use a private
3202 version which is uninitialized... If not for this "feature", we
3203 could use the C library definition of sys_nerr and sys_errlist. */
3205 char *sys_errlist
[] =
3209 "no such file or directory",
3211 "interrupted system call",
3213 "no such device or address",
3214 "argument list too long",
3215 "exec format error",
3218 "no more processes",
3219 "not enough memory",
3220 "permission denied",
3222 "block device required",
3223 "mount devices busy",
3225 "cross-device link",
3230 "file table overflow",
3231 "too many open files",
3235 "no space left on device",
3237 "read-only file system",
3243 "vax/vms specific error code nontranslatable error"
3245 #endif /* SHARABLE_LIB_BUG */
3246 #endif /* LINK_CRTL_SHARE */
3249 #ifndef HAVE_STRERROR
3255 extern char *sys_errlist
[];
3256 extern int sys_nerr
;
3258 if (errnum
>= 0 && errnum
< sys_nerr
)
3259 return sys_errlist
[errnum
];
3260 return (char *) "Unknown error";
3262 #endif /* not WINDOWSNT */
3263 #endif /* ! HAVE_STRERROR */
3266 emacs_open (path
, oflag
, mode
)
3270 register int rtnval
;
3273 if (oflag
& O_CREAT
)
3274 return creat (path
, mode
);
3277 while ((rtnval
= open (path
, oflag
, mode
)) == -1
3278 && (errno
== EINTR
));
3287 register int rtnval
;
3289 while ((rtnval
= close (fd
)) == -1
3290 && (errno
== EINTR
))
3293 /* If close is interrupted SunOS 4.1 may or may not have closed the
3294 file descriptor. If it did the second close will fail with
3295 errno = EBADF. That means we have succeeded. */
3296 if (rtnval
== -1 && did_retry
&& errno
== EBADF
)
3303 emacs_read (fildes
, buf
, nbyte
)
3308 register int rtnval
;
3310 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
3311 && (errno
== EINTR
));
3316 emacs_write (fildes
, buf
, nbyte
)
3321 register int rtnval
, bytes_written
;
3327 rtnval
= write (fildes
, buf
, nbyte
);
3334 return (bytes_written
? bytes_written
: -1);
3339 bytes_written
+= rtnval
;
3341 return (bytes_written
);
3346 * All of the following are for USG.
3348 * On USG systems the system calls are INTERRUPTIBLE by signals
3349 * that the user program has elected to catch. Thus the system call
3350 * must be retried in these cases. To handle this without massive
3351 * changes in the source code, we remap the standard system call names
3352 * to names for our own functions in sysdep.c that do the system call
3353 * with retries. Actually, for portability reasons, it is good
3354 * programming practice, as this example shows, to limit all actual
3355 * system calls to a single occurrence in the source. Sure, this
3356 * adds an extra level of function call overhead but it is almost
3357 * always negligible. Fred Fish, Unisoft Systems Inc.
3361 * Warning, this function may not duplicate 4.2 action properly
3362 * under error conditions.
3366 /* In 4.1, param.h fails to define this. */
3367 #define MAXPATHLEN 1024
3376 char *npath
, *spath
;
3377 extern char *getcwd ();
3379 BLOCK_INPUT
; /* getcwd uses malloc */
3380 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
3386 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3387 up to first slash. Should be harmless on other systems. */
3388 while (*npath
&& *npath
!= '/')
3390 strcpy (pathname
, npath
);
3391 free (spath
); /* getcwd uses malloc */
3396 #endif /* HAVE_GETWD */
3399 * Emulate rename using unlink/link. Note that this is
3400 * only partially correct. Also, doesn't enforce restriction
3401 * that files be of same type (regular->regular, dir->dir, etc).
3410 if (access (from
, 0) == 0)
3413 if (link (from
, to
) == 0)
3414 if (unlink (from
) == 0)
3426 /* HPUX curses library references perror, but as far as we know
3427 it won't be called. Anyway this definition will do for now. */
3433 #endif /* not HAVE_PERROR */
3439 * Emulate BSD dup2. First close newd if it already exists.
3440 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3441 * until we are, then close the unsuccessful ones.
3448 register int fd
, ret
;
3453 return fcntl (oldd
, F_DUPFD
, newd
);
3460 ret
= dup2 (old
,new);
3466 #endif /* not HAVE_DUP2 */
3469 * Gettimeofday. Simulate as much as possible. Only accurate
3470 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3471 * Only needed when subprocesses are defined.
3476 #ifndef HAVE_GETTIMEOFDAY
3481 gettimeofday (tp
, tzp
)
3483 struct timezone
*tzp
;
3485 extern long time ();
3487 tp
->tv_sec
= time ((long *)0);
3490 tzp
->tz_minuteswest
= -1;
3497 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3500 * This function will go away as soon as all the stubs fixed. (fnf)
3507 printf ("%s not yet implemented\r\n", badfunc
);
3514 /* Directory routines for systems that don't have them. */
3516 #ifdef SYSV_SYSTEM_DIR
3520 #if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
3524 register DIR *dirp
; /* stream from opendir */
3528 rtnval
= emacs_close (dirp
->dd_fd
);
3530 /* Some systems (like Solaris) allocate the buffer and the DIR all
3531 in one block. Why in the world are we freeing this ourselves
3533 #if ! (defined (sun) && defined (USG5_4))
3534 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
3536 xfree ((char *) dirp
);
3540 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3541 #endif /* SYSV_SYSTEM_DIR */
3543 #ifdef NONSYSTEM_DIR_LIBRARY
3547 char *filename
; /* name of directory */
3549 register DIR *dirp
; /* -> malloc'ed storage */
3550 register int fd
; /* file descriptor for read */
3551 struct stat sbuf
; /* result of fstat */
3553 fd
= emacs_open (filename
, O_RDONLY
, 0);
3558 if (fstat (fd
, &sbuf
) < 0
3559 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
3560 || (dirp
= (DIR *) xmalloc (sizeof (DIR))) == 0)
3564 return 0; /* bad luck today */
3569 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
3576 register DIR *dirp
; /* stream from opendir */
3578 emacs_close (dirp
->dd_fd
);
3579 xfree ((char *) dirp
);
3587 ino_t od_ino
; /* inode */
3588 char od_name
[DIRSIZ
]; /* filename */
3590 #endif /* not VMS */
3592 struct direct dir_static
; /* simulated directory contents */
3597 register DIR *dirp
; /* stream from opendir */
3600 register struct olddir
*dp
; /* -> directory data */
3602 register struct dir$_name
*dp
; /* -> directory data */
3603 register struct dir$_version
*dv
; /* -> version data */
3608 if (dirp
->dd_loc
>= dirp
->dd_size
)
3609 dirp
->dd_loc
= dirp
->dd_size
= 0;
3611 if (dirp
->dd_size
== 0 /* refill buffer */
3612 && (dirp
->dd_size
= emacs_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3616 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3617 dirp
->dd_loc
+= sizeof (struct olddir
);
3619 if (dp
->od_ino
!= 0) /* not deleted entry */
3621 dir_static
.d_ino
= dp
->od_ino
;
3622 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3623 dir_static
.d_name
[DIRSIZ
] = '\0';
3624 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3625 dir_static
.d_reclen
= sizeof (struct direct
)
3627 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3628 return &dir_static
; /* -> simulated structure */
3631 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3632 if (dirp
->dd_loc
== 0)
3633 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3634 : dp
->dir$b_namecount
;
3635 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3636 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3637 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3638 dir_static
.d_reclen
= sizeof (struct direct
)
3640 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3641 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3642 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3643 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3650 /* readdirver is just like readdir except it returns all versions of a file
3651 as separate entries. */
3656 register DIR *dirp
; /* stream from opendir */
3658 register struct dir$_name
*dp
; /* -> directory data */
3659 register struct dir$_version
*dv
; /* -> version data */
3661 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3662 dirp
->dd_loc
= dirp
->dd_size
= 0;
3664 if (dirp
->dd_size
== 0 /* refill buffer */
3665 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3668 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3669 if (dirp
->dd_loc
== 0)
3670 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3671 : dp
->dir$b_namecount
;
3672 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3673 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3674 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3675 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3676 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3677 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3678 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3679 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3685 #endif /* NONSYSTEM_DIR_LIBRARY */
3689 set_file_times (filename
, atime
, mtime
)
3691 EMACS_TIME atime
, mtime
;
3694 struct timeval tv
[2];
3697 return utimes (filename
, tv
);
3698 #else /* not HAVE_UTIMES */
3700 utb
.actime
= EMACS_SECS (atime
);
3701 utb
.modtime
= EMACS_SECS (mtime
);
3702 return utime (filename
, &utb
);
3703 #endif /* not HAVE_UTIMES */
3706 /* mkdir and rmdir functions, for systems which don't have them. */
3710 * Written by Robert Rother, Mariah Corporation, August 1985.
3712 * If you want it, it's yours. All I ask in return is that if you
3713 * figure out how to do this in a Bourne Shell script you send me
3715 * sdcsvax!rmr or rmr@uscd
3717 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3718 * subroutine. 11Mar86; hoptoad!gnu
3720 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3721 * subroutine didn't return EEXIST. It does now.
3727 #ifdef MKDIR_PROTOTYPE
3731 mkdir (dpath
, dmode
)
3736 int cpid
, status
, fd
;
3737 struct stat statbuf
;
3739 if (stat (dpath
, &statbuf
) == 0)
3741 errno
= EEXIST
; /* Stat worked, so it already exists */
3745 /* If stat fails for a reason other than non-existence, return error */
3746 if (errno
!= ENOENT
)
3749 synch_process_alive
= 1;
3750 switch (cpid
= fork ())
3753 case -1: /* Error in fork */
3754 return (-1); /* Errno is set already */
3756 case 0: /* Child process */
3758 * Cheap hack to set mode of new directory. Since this
3759 * child process is going away anyway, we zap its umask.
3760 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3761 * directory. Does anybody care?
3763 status
= umask (0); /* Get current umask */
3764 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3765 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3772 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3773 _exit (-1); /* Can't exec /bin/mkdir */
3775 default: /* Parent process */
3776 wait_for_termination (cpid
);
3779 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3781 errno
= EIO
; /* We don't know why, but */
3782 return -1; /* /bin/mkdir failed */
3787 #endif /* not HAVE_MKDIR */
3794 int cpid
, status
, fd
;
3795 struct stat statbuf
;
3797 if (stat (dpath
, &statbuf
) != 0)
3799 /* Stat just set errno. We don't have to */
3803 synch_process_alive
= 1;
3804 switch (cpid
= fork ())
3807 case -1: /* Error in fork */
3808 return (-1); /* Errno is set already */
3810 case 0: /* Child process */
3811 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3818 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
3819 _exit (-1); /* Can't exec /bin/rmdir */
3821 default: /* Parent process */
3822 wait_for_termination (cpid
);
3825 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3827 errno
= EIO
; /* We don't know why, but */
3828 return -1; /* /bin/rmdir failed */
3833 #endif /* !HAVE_RMDIR */
3837 /* Functions for VMS */
3839 #include "vms-pwd.h"
3844 /* Return as a string the VMS error string pertaining to STATUS.
3845 Reuses the same static buffer each time it is called. */
3849 int status
; /* VMS status code */
3853 static char buf
[257];
3855 bufadr
[0] = sizeof buf
- 1;
3856 bufadr
[1] = (int) buf
;
3857 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3858 return "untranslatable VMS error status";
3866 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3867 * not work correctly. (It also doesn't work well in version 2.3.)
3872 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3873 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3877 unsigned short s_buflen
;
3878 unsigned short s_code
;
3880 unsigned short *s_retlenadr
;
3884 #define buflen s.s_buflen
3885 #define code s.s_code
3886 #define bufadr s.s_bufadr
3887 #define retlenadr s.s_retlenadr
3889 #define R_OK 4 /* test for read permission */
3890 #define W_OK 2 /* test for write permission */
3891 #define X_OK 1 /* test for execute (search) permission */
3892 #define F_OK 0 /* test for presence of file */
3895 sys_access (path
, mode
)
3899 static char *user
= NULL
;
3902 /* translate possible directory spec into .DIR file name, so brain-dead
3903 * access can treat the directory like a file. */
3904 if (directory_file_name (path
, dir_fn
))
3908 return access (path
, mode
);
3909 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3915 unsigned short int dummy
;
3917 static int constant
= ACL$C_FILE
;
3918 DESCRIPTOR (path_desc
, path
);
3919 DESCRIPTOR (user_desc
, user
);
3923 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3926 acces
|= CHP$M_READ
;
3928 acces
|= CHP$M_WRITE
;
3929 itemlst
[0].buflen
= sizeof (int);
3930 itemlst
[0].code
= CHP$_FLAGS
;
3931 itemlst
[0].bufadr
= (char *) &flags
;
3932 itemlst
[0].retlenadr
= &dummy
;
3933 itemlst
[1].buflen
= sizeof (int);
3934 itemlst
[1].code
= CHP$_ACCESS
;
3935 itemlst
[1].bufadr
= (char *) &acces
;
3936 itemlst
[1].retlenadr
= &dummy
;
3937 itemlst
[2].end
= CHP$_END
;
3938 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3939 return stat
== SS$_NORMAL
? 0 : -1;
3943 #else /* not VMS4_4 */
3946 #define ACE$M_WRITE 2
3947 #define ACE$C_KEYID 1
3949 static unsigned short memid
, grpid
;
3950 static unsigned int uic
;
3952 /* Called from init_sys_modes, so it happens not very often
3953 but at least each time Emacs is loaded. */
3955 sys_access_reinit ()
3961 sys_access (filename
, type
)
3967 int status
, size
, i
, typecode
, acl_controlled
;
3968 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3969 union prvdef prvmask
;
3971 /* Get UIC and GRP values for protection checking. */
3974 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3977 memid
= uic
& 0xFFFF;
3981 if (type
!= 2) /* not checking write access */
3982 return access (filename
, type
);
3984 /* Check write protection. */
3986 #define CHECKPRIV(bit) (prvmask.bit)
3987 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3989 /* Find privilege bits */
3990 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3992 error ("Unable to find privileges: %s", vmserrstr (status
));
3993 if (CHECKPRIV (PRV$V_BYPASS
))
3994 return 0; /* BYPASS enabled */
3996 fab
.fab$b_fac
= FAB$M_GET
;
3997 fab
.fab$l_fna
= filename
;
3998 fab
.fab$b_fns
= strlen (filename
);
3999 fab
.fab$l_xab
= &xab
;
4000 xab
= cc$rms_xabpro
;
4001 xab
.xab$l_aclbuf
= aclbuf
;
4002 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
4003 status
= SYS$
OPEN (&fab
, 0, 0);
4006 SYS$
CLOSE (&fab
, 0, 0);
4007 /* Check system access */
4008 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITABLE (XAB$V_SYS
))
4010 /* Check ACL entries, if any */
4012 if (xab
.xab$w_acllen
> 0)
4015 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
4016 while (*aclptr
&& aclptr
< aclend
)
4018 size
= (*aclptr
& 0xff) / 4;
4019 typecode
= (*aclptr
>> 8) & 0xff;
4020 if (typecode
== ACE$C_KEYID
)
4021 for (i
= size
- 1; i
> 1; i
--)
4022 if (aclptr
[i
] == uic
)
4025 if (aclptr
[1] & ACE$M_WRITE
)
4026 return 0; /* Write access through ACL */
4028 aclptr
= &aclptr
[size
];
4030 if (acl_controlled
) /* ACL specified, prohibits write access */
4033 /* No ACL entries specified, check normal protection */
4034 if (WRITABLE (XAB$V_WLD
)) /* World writable */
4036 if (WRITABLE (XAB$V_GRP
) &&
4037 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
4038 return 0; /* Group writable */
4039 if (WRITABLE (XAB$V_OWN
) &&
4040 (xab
.xab$l_uic
& 0xFFFF) == memid
)
4041 return 0; /* Owner writable */
4043 return -1; /* Not writable */
4045 #endif /* not VMS4_4 */
4048 static char vtbuf
[NAM$C_MAXRSS
+1];
4050 /* translate a vms file spec to a unix path */
4052 sys_translate_vms (vfile
)
4063 /* leading device or logical name is a root directory */
4064 if (p
= strchr (vfile
, ':'))
4073 if (*p
== '[' || *p
== '<')
4075 while (*++vfile
!= *p
+ 2)
4079 if (vfile
[-1] == *p
)
4102 static char utbuf
[NAM$C_MAXRSS
+1];
4104 /* translate a unix path to a VMS file spec */
4106 sys_translate_unix (ufile
)
4129 if (index (&ufile
[1], '/'))
4136 if (index (&ufile
[1], '/'))
4143 if (strncmp (ufile
, "./", 2) == 0)
4150 ufile
++; /* skip the dot */
4151 if (index (&ufile
[1], '/'))
4156 else if (strncmp (ufile
, "../", 3) == 0)
4164 ufile
+= 2; /* skip the dots */
4165 if (index (&ufile
[1], '/'))
4190 extern char *getcwd ();
4192 #define MAXPATHLEN 1024
4194 ptr
= xmalloc (MAXPATHLEN
);
4195 val
= getcwd (ptr
, MAXPATHLEN
);
4201 strcpy (pathname
, ptr
);
4210 long item_code
= JPI$_OWNER
;
4211 unsigned long parent_id
;
4214 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
4217 vaxc$errno
= status
;
4227 return (getgid () << 16) | getuid ();
4232 sys_read (fildes
, buf
, nbyte
)
4237 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
4242 sys_write (fildes
, buf
, nbyte
)
4247 register int nwrote
, rtnval
= 0;
4249 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
4255 return rtnval
? rtnval
: -1;
4256 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
4257 return rtnval
? rtnval
: -1;
4258 return (rtnval
+ nwrote
);
4263 * VAX/VMS VAX C RTL really loses. It insists that records
4264 * end with a newline (carriage return) character, and if they
4265 * don't it adds one (nice of it isn't it!)
4267 * Thus we do this stupidity below.
4272 sys_write (fildes
, buf
, nbytes
)
4275 unsigned int nbytes
;
4282 fstat (fildes
, &st
);
4288 /* Handle fixed-length files with carriage control. */
4289 if (st
.st_fab_rfm
== FAB$C_FIX
4290 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
4292 len
= st
.st_fab_mrs
;
4293 retval
= write (fildes
, p
, min (len
, nbytes
));
4296 retval
++; /* This skips the implied carriage control */
4300 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4301 while (*e
!= '\n' && e
> p
) e
--;
4302 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
4303 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4305 retval
= write (fildes
, p
, len
);
4316 /* Create file NEW copying its attributes from file OLD. If
4317 OLD is 0 or does not exist, create based on the value of
4320 /* Protection value the file should ultimately have.
4321 Set by create_copy_attrs, and use by rename_sansversions. */
4322 static unsigned short int fab_final_pro
;
4325 creat_copy_attrs (old
, new)
4328 struct FAB fab
= cc$rms_fab
;
4329 struct XABPRO xabpro
;
4330 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
4331 extern int vms_stmlf_recfm
;
4335 fab
.fab$b_fac
= FAB$M_GET
;
4336 fab
.fab$l_fna
= old
;
4337 fab
.fab$b_fns
= strlen (old
);
4338 fab
.fab$l_xab
= (char *) &xabpro
;
4339 xabpro
= cc$rms_xabpro
;
4340 xabpro
.xab$l_aclbuf
= aclbuf
;
4341 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
4342 /* Call $OPEN to fill in the fab & xabpro fields. */
4343 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4345 SYS$
CLOSE (&fab
, 0, 0);
4346 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
4347 if (xabpro
.xab$w_acllen
> 0)
4349 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
4350 /* If the acl buffer was too short, redo open with longer one.
4351 Wouldn't need to do this if there were some system imposed
4352 limit on the size of an ACL, but I can't find any such. */
4354 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
4355 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
4356 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4357 SYS$
CLOSE (&fab
, 0, 0);
4363 xabpro
.xab$l_aclbuf
= 0;
4368 fab
.fab$l_fna
= new;
4369 fab
.fab$b_fns
= strlen (new);
4373 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
4374 fab
.fab$b_rat
= FAB$M_CR
;
4377 /* Set the file protections such that we will be able to manipulate
4378 this file. Once we are done writing and renaming it, we will set
4379 the protections back. */
4381 fab_final_pro
= xabpro
.xab$w_pro
;
4383 SYS$
SETDFPROT (0, &fab_final_pro
);
4384 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
4386 /* Create the new file with either default attrs or attrs copied
4388 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
4390 SYS$
CLOSE (&fab
, 0, 0);
4391 /* As this is a "replacement" for creat, return a file descriptor
4392 opened for writing. */
4393 return open (new, O_WRONLY
);
4398 #include <varargs.h>
4401 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4406 sys_creat (va_alist
)
4409 va_list list_incrementer
;
4412 int rfd
; /* related file descriptor */
4413 int fd
; /* Our new file descriptor */
4420 extern int vms_stmlf_recfm
;
4423 va_start (list_incrementer
);
4424 name
= va_arg (list_incrementer
, char *);
4425 mode
= va_arg (list_incrementer
, int);
4427 rfd
= va_arg (list_incrementer
, int);
4428 va_end (list_incrementer
);
4431 /* Use information from the related file descriptor to set record
4432 format of the newly created file. */
4433 fstat (rfd
, &st_buf
);
4434 switch (st_buf
.st_fab_rfm
)
4437 strcpy (rfm
, "rfm = fix");
4438 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
4439 strcpy (rat
, "rat = ");
4440 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4442 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4443 strcat (rat
, "ftn");
4444 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4445 strcat (rat
, "prn");
4446 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4447 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4448 strcat (rat
, ", blk");
4450 strcat (rat
, "blk");
4451 return creat (name
, 0, rfm
, rat
, mrs
);
4454 strcpy (rfm
, "rfm = vfc");
4455 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
4456 strcpy (rat
, "rat = ");
4457 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4459 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4460 strcat (rat
, "ftn");
4461 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4462 strcat (rat
, "prn");
4463 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4464 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4465 strcat (rat
, ", blk");
4467 strcat (rat
, "blk");
4468 return creat (name
, 0, rfm
, rat
, fsz
);
4471 strcpy (rfm
, "rfm = stm");
4475 strcpy (rfm
, "rfm = stmcr");
4479 strcpy (rfm
, "rfm = stmlf");
4483 strcpy (rfm
, "rfm = udf");
4487 strcpy (rfm
, "rfm = var");
4490 strcpy (rat
, "rat = ");
4491 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4493 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4494 strcat (rat
, "ftn");
4495 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4496 strcat (rat
, "prn");
4497 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4498 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4499 strcat (rat
, ", blk");
4501 strcat (rat
, "blk");
4505 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
4506 strcpy (rat
, "rat=cr");
4508 /* Until the VAX C RTL fixes the many bugs with modes, always use
4509 mode 0 to get the user's default protection. */
4510 fd
= creat (name
, 0, rfm
, rat
);
4511 if (fd
< 0 && errno
== EEXIST
)
4513 if (unlink (name
) < 0)
4514 report_file_error ("delete", build_string (name
));
4515 fd
= creat (name
, 0, rfm
, rat
);
4521 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4523 sys_fwrite (ptr
, size
, num
, fp
)
4524 register char * ptr
;
4527 register int tot
= num
* size
;
4535 * The VMS C library routine creat actually creates a new version of an
4536 * existing file rather than truncating the old version. There are times
4537 * when this is not the desired behavior, for instance, when writing an
4538 * auto save file (you only want one version), or when you don't have
4539 * write permission in the directory containing the file (but the file
4540 * itself is writable). Hence this routine, which is equivalent to
4541 * "close (creat (fn, 0));" on Unix if fn already exists.
4547 struct FAB xfab
= cc$rms_fab
;
4548 struct RAB xrab
= cc$rms_rab
;
4551 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
4552 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
4553 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
4554 xfab
.fab$l_fna
= fn
;
4555 xfab
.fab$b_fns
= strlen (fn
);
4556 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
4558 xrab
.rab$l_fab
= &xfab
;
4560 /* This gibberish opens the file, positions to the first record, and
4561 deletes all records from there until the end of file. */
4562 if ((SYS$
OPEN (&xfab
) & 01) == 01)
4564 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
4565 (SYS$
FIND (&xrab
) & 01) == 01 &&
4566 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
4577 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4578 SYSPRV or a readable SYSUAF.DAT. */
4584 * Routine to read the VMS User Authorization File and return
4585 * a specific user's record.
4588 static struct UAF retuaf
;
4591 get_uaf_name (uname
)
4598 uaf_fab
= cc$rms_fab
;
4599 uaf_rab
= cc$rms_rab
;
4600 /* initialize fab fields */
4601 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4602 uaf_fab
.fab$b_fns
= 21;
4603 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4604 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4605 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4606 /* initialize rab fields */
4607 uaf_rab
.rab$l_fab
= &uaf_fab
;
4608 /* open the User Authorization File */
4609 status
= SYS$
OPEN (&uaf_fab
);
4613 vaxc$errno
= status
;
4616 status
= SYS$
CONNECT (&uaf_rab
);
4620 vaxc$errno
= status
;
4623 /* read the requested record - index is in uname */
4624 uaf_rab
.rab$l_kbf
= uname
;
4625 uaf_rab
.rab$b_ksz
= strlen (uname
);
4626 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4627 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4628 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4629 status
= SYS$
GET (&uaf_rab
);
4633 vaxc$errno
= status
;
4636 /* close the User Authorization File */
4637 status
= SYS$
DISCONNECT (&uaf_rab
);
4641 vaxc$errno
= status
;
4644 status
= SYS$
CLOSE (&uaf_fab
);
4648 vaxc$errno
= status
;
4662 uaf_fab
= cc$rms_fab
;
4663 uaf_rab
= cc$rms_rab
;
4664 /* initialize fab fields */
4665 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4666 uaf_fab
.fab$b_fns
= 21;
4667 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4668 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4669 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4670 /* initialize rab fields */
4671 uaf_rab
.rab$l_fab
= &uaf_fab
;
4672 /* open the User Authorization File */
4673 status
= SYS$
OPEN (&uaf_fab
);
4677 vaxc$errno
= status
;
4680 status
= SYS$
CONNECT (&uaf_rab
);
4684 vaxc$errno
= status
;
4687 /* read the requested record - index is in uic */
4688 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4689 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4690 uaf_rab
.rab$b_ksz
= sizeof uic
;
4691 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4692 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4693 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4694 status
= SYS$
GET (&uaf_rab
);
4698 vaxc$errno
= status
;
4701 /* close the User Authorization File */
4702 status
= SYS$
DISCONNECT (&uaf_rab
);
4706 vaxc$errno
= status
;
4709 status
= SYS$
CLOSE (&uaf_fab
);
4713 vaxc$errno
= status
;
4719 static struct passwd retpw
;
4727 /* copy these out first because if the username is 32 chars, the next
4728 section will overwrite the first byte of the UIC */
4729 retpw
.pw_uid
= up
->uaf$w_mem
;
4730 retpw
.pw_gid
= up
->uaf$w_grp
;
4732 /* I suppose this is not the best style, to possibly overwrite one
4733 byte beyond the end of the field, but what the heck... */
4734 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4735 while (ptr
[-1] == ' ')
4738 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4740 /* the rest of these are counted ascii strings */
4741 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4742 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4743 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4744 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4745 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4746 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4747 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4748 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4752 #else /* not READ_SYSUAF */
4753 static struct passwd retpw
;
4754 #endif /* not READ_SYSUAF */
4765 unsigned char * full
;
4766 #endif /* READ_SYSUAF */
4771 if ('a' <= *ptr
&& *ptr
<= 'z')
4776 if (!(up
= get_uaf_name (name
)))
4778 return cnv_uaf_pw (up
);
4780 if (strcmp (name
, getenv ("USER")) == 0)
4782 retpw
.pw_uid
= getuid ();
4783 retpw
.pw_gid
= getgid ();
4784 strcpy (retpw
.pw_name
, name
);
4785 if (full
= egetenv ("FULLNAME"))
4786 strcpy (retpw
.pw_gecos
, full
);
4788 *retpw
.pw_gecos
= '\0';
4789 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4790 *retpw
.pw_shell
= '\0';
4795 #endif /* not READ_SYSUAF */
4805 if (!(up
= get_uaf_uic (uid
)))
4807 return cnv_uaf_pw (up
);
4809 if (uid
== sys_getuid ())
4810 return getpwnam (egetenv ("USER"));
4813 #endif /* not READ_SYSUAF */
4816 /* return total address space available to the current process. This is
4817 the sum of the current p0 size, p1 size and free page table entries
4823 unsigned long free_pages
;
4824 unsigned long frep0va
;
4825 unsigned long frep1va
;
4828 item_code
= JPI$_FREPTECNT
;
4829 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4832 vaxc$errno
= status
;
4837 item_code
= JPI$_FREP0VA
;
4838 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4841 vaxc$errno
= status
;
4844 item_code
= JPI$_FREP1VA
;
4845 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4848 vaxc$errno
= status
;
4852 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4856 define_logical_name (varname
, string
)
4860 struct dsc$descriptor_s strdsc
=
4861 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4862 struct dsc$descriptor_s envdsc
=
4863 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4864 struct dsc$descriptor_s lnmdsc
=
4865 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4867 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4871 delete_logical_name (varname
)
4874 struct dsc$descriptor_s envdsc
=
4875 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4876 struct dsc$descriptor_s lnmdsc
=
4877 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4879 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4897 error ("execvp system call not implemented");
4906 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4907 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4908 char from_esn
[NAM$C_MAXRSS
];
4909 char to_esn
[NAM$C_MAXRSS
];
4911 from_fab
.fab$l_fna
= from
;
4912 from_fab
.fab$b_fns
= strlen (from
);
4913 from_fab
.fab$l_nam
= &from_nam
;
4914 from_fab
.fab$l_fop
= FAB$M_NAM
;
4916 from_nam
.nam$l_esa
= from_esn
;
4917 from_nam
.nam$b_ess
= sizeof from_esn
;
4919 to_fab
.fab$l_fna
= to
;
4920 to_fab
.fab$b_fns
= strlen (to
);
4921 to_fab
.fab$l_nam
= &to_nam
;
4922 to_fab
.fab$l_fop
= FAB$M_NAM
;
4924 to_nam
.nam$l_esa
= to_esn
;
4925 to_nam
.nam$b_ess
= sizeof to_esn
;
4927 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4933 if (status
== RMS$_DEV
)
4937 vaxc$errno
= status
;
4942 /* This function renames a file like `rename', but it strips
4943 the version number from the "to" filename, such that the "to" file is
4944 will always be a new version. It also sets the file protection once it is
4945 finished. The protection that we will use is stored in fab_final_pro,
4946 and was set when we did a creat_copy_attrs to create the file that we
4949 We could use the chmod function, but Eunichs uses 3 bits per user category
4950 to describe the protection, and VMS uses 4 (write and delete are separate
4951 bits). To maintain portability, the VMS implementation of `chmod' wires
4952 the W and D bits together. */
4955 static struct fibdef fib
; /* We need this initialized to zero */
4956 char vms_file_written
[NAM$C_MAXRSS
];
4959 rename_sans_version (from
,to
)
4966 struct FAB to_fab
= cc$rms_fab
;
4967 struct NAM to_nam
= cc$rms_nam
;
4968 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4969 struct dsc$descriptor fib_attr
[2]
4970 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4971 char to_esn
[NAM$C_MAXRSS
];
4973 $
DESCRIPTOR (disk
,to_esn
);
4975 to_fab
.fab$l_fna
= to
;
4976 to_fab
.fab$b_fns
= strlen (to
);
4977 to_fab
.fab$l_nam
= &to_nam
;
4978 to_fab
.fab$l_fop
= FAB$M_NAM
;
4980 to_nam
.nam$l_esa
= to_esn
;
4981 to_nam
.nam$b_ess
= sizeof to_esn
;
4983 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4985 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4986 *(to_nam
.nam$l_ver
) = '\0';
4988 stat
= rename (from
, to_esn
);
4992 strcpy (vms_file_written
, to_esn
);
4994 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4995 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4997 /* Now set the file protection to the correct value */
4998 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
5000 /* Copy these fields into the fib */
5001 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
5002 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
5003 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
5005 SYS$
CLOSE (&to_fab
, 0, 0);
5007 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
5010 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
5011 0, 0, 0, &fib_attr
, 0);
5014 stat
= SYS$
DASSGN (chan
);
5017 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
5028 unsigned short fid
[3];
5029 char esa
[NAM$C_MAXRSS
];
5032 fab
.fab$l_fop
= FAB$M_OFP
;
5033 fab
.fab$l_fna
= file
;
5034 fab
.fab$b_fns
= strlen (file
);
5035 fab
.fab$l_nam
= &nam
;
5038 nam
.nam$l_esa
= esa
;
5039 nam
.nam$b_ess
= NAM$C_MAXRSS
;
5041 status
= SYS$
PARSE (&fab
);
5042 if ((status
& 1) == 0)
5045 vaxc$errno
= status
;
5048 status
= SYS$
SEARCH (&fab
);
5049 if ((status
& 1) == 0)
5052 vaxc$errno
= status
;
5056 fid
[0] = nam
.nam$w_fid
[0];
5057 fid
[1] = nam
.nam$w_fid
[1];
5058 fid
[2] = nam
.nam$w_fid
[2];
5060 fab
.fab$l_fna
= new;
5061 fab
.fab$b_fns
= strlen (new);
5063 status
= SYS$
PARSE (&fab
);
5064 if ((status
& 1) == 0)
5067 vaxc$errno
= status
;
5071 nam
.nam$w_fid
[0] = fid
[0];
5072 nam
.nam$w_fid
[1] = fid
[1];
5073 nam
.nam$w_fid
[2] = fid
[2];
5075 nam
.nam$l_esa
= nam
.nam$l_name
;
5076 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
5078 status
= SYS$
ENTER (&fab
);
5079 if ((status
& 1) == 0)
5082 vaxc$errno
= status
;
5093 printf ("%s not yet implemented\r\n", badfunc
);
5101 /* Arrange to return a range centered on zero. */
5102 return rand () - (1 << 30);
5114 /* Called from init_sys_modes. */
5120 /* If we're not on an HFT we shouldn't do any of this. We determine
5121 if we are on an HFT by trying to get an HFT error code. If this
5122 call fails, we're not on an HFT. */
5124 if (ioctl (0, HFQERROR
, &junk
) < 0)
5126 #else /* not IBMR2AIX */
5127 if (ioctl (0, HFQEIO
, 0) < 0)
5129 #endif /* not IBMR2AIX */
5131 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5132 as the rubout key's ASCII code. Here this is changed. The bug is that
5133 there's no way to determine the old mapping, so in reset_sys_modes
5134 we need to assume that the normal map had been present. Of course, this
5135 code also doesn't help if on a terminal emulator which doesn't understand
5139 struct hfkeymap keymap
;
5141 buf
.hf_bufp
= (char *)&keymap
;
5142 buf
.hf_buflen
= sizeof (keymap
);
5143 keymap
.hf_nkeys
= 2;
5144 keymap
.hfkey
[0].hf_kpos
= 15;
5145 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5147 keymap
.hfkey
[0].hf_keyidh
= '<';
5148 #else /* not IBMR2AIX */
5149 keymap
.hfkey
[0].hf_page
= '<';
5150 #endif /* not IBMR2AIX */
5151 keymap
.hfkey
[0].hf_char
= 127;
5152 keymap
.hfkey
[1].hf_kpos
= 15;
5153 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5155 keymap
.hfkey
[1].hf_keyidh
= '<';
5156 #else /* not IBMR2AIX */
5157 keymap
.hfkey
[1].hf_page
= '<';
5158 #endif /* not IBMR2AIX */
5159 keymap
.hfkey
[1].hf_char
= 127;
5160 hftctl (0, HFSKBD
, &buf
);
5162 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
5164 line_ins_del_ok
= char_ins_del_ok
= 0;
5167 /* Reset the rubout key to backspace. */
5173 struct hfkeymap keymap
;
5177 if (ioctl (0, HFQERROR
, &junk
) < 0)
5179 #else /* not IBMR2AIX */
5180 if (ioctl (0, HFQEIO
, 0) < 0)
5182 #endif /* not IBMR2AIX */
5184 buf
.hf_bufp
= (char *)&keymap
;
5185 buf
.hf_buflen
= sizeof (keymap
);
5186 keymap
.hf_nkeys
= 2;
5187 keymap
.hfkey
[0].hf_kpos
= 15;
5188 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5190 keymap
.hfkey
[0].hf_keyidh
= '<';
5191 #else /* not IBMR2AIX */
5192 keymap
.hfkey
[0].hf_page
= '<';
5193 #endif /* not IBMR2AIX */
5194 keymap
.hfkey
[0].hf_char
= 8;
5195 keymap
.hfkey
[1].hf_kpos
= 15;
5196 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5198 keymap
.hfkey
[1].hf_keyidh
= '<';
5199 #else /* not IBMR2AIX */
5200 keymap
.hfkey
[1].hf_page
= '<';
5201 #endif /* not IBMR2AIX */
5202 keymap
.hfkey
[1].hf_char
= 8;
5203 hftctl (0, HFSKBD
, &buf
);
5210 /* These are included on Sunos 4.1 when we do not use shared libraries.
5211 X11 libraries may refer to these functions but (we hope) do not
5212 actually call them. */
5232 #endif /* USE_DL_STUBS */
5241 register int length
;
5245 long max_str
= 65535;
5247 while (length
> max_str
) {
5248 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5253 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5255 while (length
-- > 0)
5257 #endif /* not VMS */
5260 #endif /* no bzero */
5261 #endif /* BSTRING */
5263 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5266 /* Saying `void' requires a declaration, above, where bcopy is used
5267 and that declaration causes pain for systems where bcopy is a macro. */
5268 bcopy (b1
, b2
, length
)
5271 register int length
;
5274 long max_str
= 65535;
5276 while (length
> max_str
) {
5277 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
5283 (void) LIB$
MOVC3 (&length
, b1
, b2
);
5285 while (length
-- > 0)
5287 #endif /* not VMS */
5289 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5294 bcmp (b1
, b2
, length
) /* This could be a macro! */
5297 register int length
;
5300 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
5301 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
5303 return STR$
COMPARE (&src1
, &src2
);
5305 while (length
-- > 0)
5310 #endif /* not VMS */
5312 #endif /* no bcmp */
5313 #endif /* not BSTRING */
5315 #ifndef HAVE_STRSIGNAL
5322 if (0 <= code
&& code
< NSIG
)
5325 signame
= sys_errlist
[code
];
5327 /* Cast to suppress warning if the table has const char *. */
5328 signame
= (char *) sys_siglist
[code
];
5334 #endif /* HAVE_STRSIGNAL */