1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 86,87,88,93,94,95,1999,2000,01,2003
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
33 /* Including stdlib.h isn't necessarily enough to get srandom
34 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
36 #if 0 /* It turns out that defining _OSF_SOURCE in osf5-0.h gets
37 random prototyped as returning `int'. It looks to me as
38 though the best way to DTRT is to prefer the rand48 functions
39 (per libc.info). -- fx */
40 extern long int random
P_ ((void));
42 #if 0 /* Don't prototype srandom; it takes an unsigned argument on
43 some systems, and an unsigned long on others, like FreeBSD
45 extern void srandom
P_ ((unsigned int));
49 #include "blockinput.h"
53 /* It is essential to include stdlib.h so that this file picks up
54 the correct definitions of rand, srand, and RAND_MAX.
55 Otherwise random numbers will not work correctly. */
59 /* Nonzero means delete a process right away if it exits (process.c). */
60 static int delete_exited_processes
;
66 #define write sys_write
71 #endif /* not WINDOWSNT */
73 /* Does anyone other than VMS need this? */
75 #define sys_fwrite fwrite
80 #include <sys/types.h>
85 #if !defined (USG) || defined (BSD_PGRPS)
87 #define setpgrp setpgid
91 /* Get SI_SRPC_DOMAIN, if it is available. */
92 #ifdef HAVE_SYS_SYSTEMINFO_H
93 #include <sys/systeminfo.h>
96 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
100 #include <sys/param.h>
104 extern unsigned start
__asm__ ("start");
126 #include <sys/file.h>
134 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
138 #include <sys/file.h>
146 #include <sys/ioctl.h>
152 #ifdef BROKEN_TIOCGWINSZ
157 #if defined (USG) || defined (DGUX)
158 #include <sys/utsname.h>
159 #ifndef MEMORY_IN_STRING_H
162 #if defined (TIOCGWINSZ) || defined (ISC4_0)
164 #include <sys/sioctl.h>
167 #include <sys/stream.h>
168 #include <sys/ptem.h>
170 #endif /* TIOCGWINSZ or ISC4_0 */
171 #endif /* USG or DGUX */
173 extern int quit_char
;
175 #include "keyboard.h"
178 #include "termhooks.h"
179 #include "termchar.h"
180 #include "termopts.h"
181 #include "dispextern.h"
186 /* In process.h which conflicts with the local copy. */
188 int _CRTAPI1
_spawnlp (int, const char *, const char *, ...);
189 int _CRTAPI1
_getpid (void);
192 #ifdef NONSYSTEM_DIR_LIBRARY
194 #endif /* NONSYSTEM_DIR_LIBRARY */
196 #include "syssignal.h"
203 #ifndef HAVE_STRUCT_UTIMBUF
204 /* We want to use utime rather than utimes, but we couldn't find the
205 structure declaration. We'll use the traditional one. */
213 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
219 #define LNOFLSH 0100000
222 static int baud_convert
[] =
227 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
228 1800, 2400, 4800, 9600, 19200, 38400
235 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
237 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
245 /* The file descriptor for Emacs's input terminal.
246 Under Unix, this is normally zero except when using X;
247 under VMS, we place the input channel number here. */
250 void croak
P_ ((char *));
257 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
259 SIGMASKTYPE sigprocmask_set
;
262 /* Specify a different file descriptor for further input operations. */
271 /* Discard pending input on descriptor input_fd. */
277 struct emacs_tty buf
;
282 /* Discarding input is not safe when the input could contain
283 replies from the X server. So don't do it. */
284 if (read_socket_hook
)
289 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
290 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
296 ioctl (input_fd
, TIOCFLUSH
, &zero
);
298 #else /* not Apollo */
299 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
300 while (dos_keyread () != -1)
302 #else /* not MSDOS */
303 EMACS_GET_TTY (input_fd
, &buf
);
304 EMACS_SET_TTY (input_fd
, &buf
, 0);
305 #endif /* not MSDOS */
306 #endif /* not Apollo */
308 #endif /* not WINDOWSNT */
313 /* Arrange for character C to be read as the next input from
324 if (read_socket_hook
)
327 /* Should perhaps error if in batch mode */
329 ioctl (input_fd
, TIOCSTI
, &c
);
330 #else /* no TIOCSTI */
331 error ("Cannot stuff terminal input characters in this version of Unix");
332 #endif /* no TIOCSTI */
344 #ifdef INIT_BAUD_RATE
349 #else /* not DOS_NT */
353 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
354 &sg
.class, 12, 0, 0, 0, 0 );
355 emacs_ospeed
= sg
.xmit_baud
;
361 tcgetattr (input_fd
, &sg
);
362 emacs_ospeed
= cfgetospeed (&sg
);
363 #if defined (USE_GETOBAUD) && defined (getobaud)
364 /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
365 if (emacs_ospeed
== 0)
366 emacs_ospeed
= getobaud (sg
.c_cflag
);
368 #else /* neither VMS nor TERMIOS */
374 tcgetattr (input_fd
, &sg
);
376 ioctl (input_fd
, TCGETA
, &sg
);
378 emacs_ospeed
= sg
.c_cflag
& CBAUD
;
379 #else /* neither VMS nor TERMIOS nor TERMIO */
382 sg
.sg_ospeed
= B9600
;
383 if (ioctl (input_fd
, TIOCGETP
, &sg
) < 0)
385 emacs_ospeed
= sg
.sg_ospeed
;
386 #endif /* not HAVE_TERMIO */
387 #endif /* not HAVE_TERMIOS */
389 #endif /* not DOS_NT */
390 #endif /* not INIT_BAUD_RATE */
393 baud_rate
= (emacs_ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
394 ? baud_convert
[emacs_ospeed
] : 9600);
401 set_exclusive_use (fd
)
405 ioctl (fd
, FIOCLEX
, 0);
407 /* Ok to do nothing if this feature does not exist */
412 wait_without_blocking ()
415 wait3 (0, WNOHANG
| WUNTRACED
, 0);
417 croak ("wait_without_blocking");
419 synch_process_alive
= 0;
422 #endif /* not subprocesses */
424 int wait_debugging
; /* Set nonzero to make following function work under dbx
425 (at least for bsd). */
428 wait_for_termination_signal ()
431 /* Wait for subprocess with process id `pid' to terminate and
432 make sure it will get eliminated (not remain forever as a zombie) */
435 wait_for_termination (pid
)
444 status
= SYS$
FORCEX (&pid
, 0, 0);
447 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
448 /* Note that kill returns -1 even if the process is just a zombie now.
449 But inevitably a SIGCHLD interrupt should be generated
450 and child_sig will do wait3 and make the process go away. */
451 /* There is some indication that there is a bug involved with
452 termination of subprocesses, perhaps involving a kernel bug too,
453 but no idea what it is. Just as a hunch we signal SIGCHLD to see
454 if that causes the problem to go away or get worse. */
455 sigsetmask (sigmask (SIGCHLD
));
456 if (0 > kill (pid
, 0))
458 sigsetmask (SIGEMPTYMASK
);
459 kill (getpid (), SIGCHLD
);
465 sigpause (SIGEMPTYMASK
);
466 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
467 #if defined (UNIPLUS)
468 if (0 > kill (pid
, 0))
471 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
472 #ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */
473 sigblock (sigmask (SIGCHLD
));
475 if (kill (pid
, 0) == -1 && errno
== ESRCH
)
477 sigunblock (sigmask (SIGCHLD
));
481 sigsuspend (&empty_mask
);
482 #else /* not POSIX_SIGNALS */
483 #ifdef HAVE_SYSV_SIGPAUSE
485 if (0 > kill (pid
, 0))
491 #else /* not HAVE_SYSV_SIGPAUSE */
495 #else /* not WINDOWSNT */
496 if (0 > kill (pid
, 0))
498 /* Using sleep instead of pause avoids timing error.
499 If the inferior dies just before the sleep,
500 we lose just one second. */
502 #endif /* not WINDOWSNT */
503 #endif /* not HAVE_SYSV_SIGPAUSE */
504 #endif /* not POSIX_SIGNALS */
505 #endif /* not UNIPLUS */
506 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
508 #else /* not subprocesses */
511 #else /* not __DJGPP__ > 1 */
513 if (kill (pid
, 0) < 0)
519 if (status
== pid
|| status
== -1)
522 #endif /* not __DJGPP__ > 1*/
523 #endif /* not subprocesses */
530 * flush any pending output
531 * (may flush input as well; it does not matter the way we use it)
535 flush_pending_output (channel
)
539 /* If we try this, we get hit with SIGTTIN, because
540 the child's tty belongs to the child's pgrp. */
543 ioctl (channel
, TCFLSH
, 1);
547 /* 3rd arg should be ignored
548 but some 4.2 kernels actually want the address of an int
549 and nonzero means something different. */
550 ioctl (channel
, TIOCFLUSH
, &zero
);
557 /* Set up the terminal at the other end of a pseudo-terminal that
558 we will be controlling an inferior through.
559 It should not echo or do line-editing, since that is done
560 in Emacs. No padding needed for insertion into an Emacs buffer. */
563 child_setup_tty (out
)
569 EMACS_GET_TTY (out
, &s
);
571 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
572 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
573 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
575 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
576 /* No output delays */
578 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
579 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
580 #if 0 /* This causes bugs in (for instance) telnet to certain sites. */
581 s
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
582 #ifdef INLCR /* Just being cautious, since I can't check how
583 widespread INLCR is--rms. */
584 s
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
588 s
.main
.c_iflag
&= ~IUCLC
; /* Disable downcasing on input. */
591 s
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
594 s
.main
.c_oflag
&= ~OLCUC
; /* Disable upcasing on output. */
596 s
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
597 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CSIZE
) | CS8
; /* Don't strip 8th bit */
599 /* Said to be unnecessary: */
600 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
601 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
604 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
605 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
606 s
.main
.c_cc
[VERASE
] = CDISABLE
; /* disable erase processing */
607 s
.main
.c_cc
[VKILL
] = CDISABLE
; /* disable kill processing */
610 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
614 /* AIX enhanced edit loses NULs, so disable it */
617 s
.main
.c_iflag
&= ~ASCEDIT
;
619 /* Also, PTY overloads NUL and BREAK.
620 don't ignore break, but don't signal either, so it looks like NUL. */
621 s
.main
.c_iflag
&= ~IGNBRK
;
622 s
.main
.c_iflag
&= ~BRKINT
;
623 /* QUIT and INTR work better as signals, so disable character forms */
624 s
.main
.c_cc
[VINTR
] = 0377;
625 #ifdef SIGNALS_VIA_CHARACTERS
626 /* the QUIT and INTR character are used in process_send_signal
627 so set them here to something useful. */
628 if (s
.main
.c_cc
[VQUIT
] == 0377)
629 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
630 if (s
.main
.c_cc
[VINTR
] == 0377)
631 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
632 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
633 /* QUIT and INTR work better as signals, so disable character forms */
634 s
.main
.c_cc
[VQUIT
] = 0377;
635 s
.main
.c_cc
[VINTR
] = 0377;
636 s
.main
.c_lflag
&= ~ISIG
;
637 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
638 s
.main
.c_cc
[VEOL
] = 0377;
639 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
642 #else /* not HAVE_TERMIO */
644 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
646 s
.main
.sg_flags
|= LPASS8
;
647 s
.main
.sg_erase
= 0377;
648 s
.main
.sg_kill
= 0377;
649 s
.lmode
= LLITOUT
| s
.lmode
; /* Don't strip 8th bit */
651 #endif /* not HAVE_TERMIO */
653 EMACS_SET_TTY (out
, &s
, 0);
662 ioctl (out
, FIOASYNC
, &zero
);
665 #endif /* not DOS_NT */
669 #endif /* subprocesses */
671 /* Record a signal code and the handler for it. */
675 SIGTYPE (*handler
) P_ ((int));
678 static void save_signal_handlers
P_ ((struct save_signal
*));
679 static void restore_signal_handlers
P_ ((struct save_signal
*));
681 /* Suspend the Emacs process; give terminal to its superior. */
687 /* "Foster" parentage allows emacs to return to a subprocess that attached
688 to the current emacs as a cheaper than starting a whole new process. This
689 is set up by KEPTEDITOR.COM. */
690 unsigned long parent_id
, foster_parent_id
;
693 fpid_string
= getenv ("EMACS_PARENT_PID");
694 if (fpid_string
!= NULL
)
696 sscanf (fpid_string
, "%x", &foster_parent_id
);
697 if (foster_parent_id
!= 0)
698 parent_id
= foster_parent_id
;
700 parent_id
= getppid ();
703 parent_id
= getppid ();
705 xfree (fpid_string
); /* On VMS, this was malloc'd */
707 if (parent_id
&& parent_id
!= 0xffffffff)
709 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
710 int status
= LIB$
ATTACH (&parent_id
) & 1;
711 signal (SIGINT
, oldsig
);
720 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
721 d_prompt
.a
= "Emacs: "; /* Just a reminder */
722 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
727 #if defined (SIGTSTP) && !defined (MSDOS)
730 int pgrp
= EMACS_GETPGRP (0);
731 EMACS_KILLPG (pgrp
, SIGTSTP
);
734 #else /* No SIGTSTP */
735 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
736 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
737 kill (getpid (), SIGQUIT
);
739 #else /* No SIGTSTP or USG_JOBCTRL */
741 /* On a system where suspending is not implemented,
742 instead fork a subshell and let it talk directly to the terminal
746 #endif /* no USG_JOBCTRL */
747 #endif /* no SIGTSTP */
751 /* Fork a subshell. */
758 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
760 char oldwd
[MAXPATHLEN
+1]; /* Fixed length is safe on MSDOS. */
763 struct save_signal saved_handlers
[5];
765 unsigned char *str
= 0;
768 saved_handlers
[0].code
= SIGINT
;
769 saved_handlers
[1].code
= SIGQUIT
;
770 saved_handlers
[2].code
= SIGTERM
;
772 saved_handlers
[3].code
= SIGIO
;
773 saved_handlers
[4].code
= 0;
775 saved_handlers
[3].code
= 0;
778 /* Mentioning current_buffer->buffer would mean including buffer.h,
779 which somehow wedges the hp compiler. So instead... */
781 dir
= intern ("default-directory");
782 if (NILP (Fboundp (dir
)))
784 dir
= Fsymbol_value (dir
);
788 dir
= expand_and_dir_to_file (Funhandled_file_name_directory (dir
), Qnil
);
789 str
= (unsigned char *) alloca (SCHARS (dir
) + 2);
791 bcopy (SDATA (dir
), str
, len
);
792 if (str
[len
- 1] != '/') str
[len
++] = '/';
799 save_signal_handlers (saved_handlers
);
800 synch_process_alive
= 1;
801 #endif /* __DJGPP__ > 1 */
805 error ("Can't spawn subshell");
812 #ifdef DOS_NT /* MW, Aug 1993 */
815 sh
= (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
818 sh
= (char *) egetenv ("SHELL");
822 /* Use our buffer's default directory for the subshell. */
824 chdir ((char *) str
);
827 close_process_descs (); /* Close Emacs's pipes/ptys */
830 #ifdef SET_EMACS_PRIORITY
832 extern EMACS_INT emacs_priority
;
834 if (emacs_priority
< 0)
835 nice (-emacs_priority
);
839 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
841 char *epwd
= getenv ("PWD");
842 char old_pwd
[MAXPATHLEN
+1+4];
844 /* If PWD is set, pass it with corrected value. */
847 strcpy (old_pwd
, epwd
);
848 if (str
[len
- 1] == '/')
850 setenv ("PWD", str
, 1);
855 putenv (old_pwd
); /* restore previous value */
857 #if 0 /* This is also reported if last command executed in subshell failed, KFS */
859 report_file_error ("Can't execute subshell", Fcons (build_string (sh
), Qnil
));
861 #else /* not MSDOS */
863 /* Waits for process completion */
864 pid
= _spawnlp (_P_WAIT
, sh
, sh
, NULL
);
867 write (1, "Can't execute subshell", 22);
868 #else /* not WINDOWSNT */
870 write (1, "Can't execute subshell", 22);
872 #endif /* not WINDOWSNT */
873 #endif /* not MSDOS */
876 /* Do this now if we did not do it before. */
877 #if !defined (MSDOS) || __DJGPP__ == 1
878 save_signal_handlers (saved_handlers
);
879 synch_process_alive
= 1;
883 wait_for_termination (pid
);
885 restore_signal_handlers (saved_handlers
);
886 synch_process_alive
= 0;
889 #endif /* !MAC_OS8 */
892 save_signal_handlers (saved_handlers
)
893 struct save_signal
*saved_handlers
;
895 while (saved_handlers
->code
)
897 saved_handlers
->handler
898 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers
->code
, SIG_IGN
);
904 restore_signal_handlers (saved_handlers
)
905 struct save_signal
*saved_handlers
;
907 while (saved_handlers
->code
)
909 signal (saved_handlers
->code
, saved_handlers
->handler
);
923 old_fcntl_flags
= fcntl (fd
, F_GETFL
, 0) & ~FASYNC
;
924 fcntl (fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
926 interrupts_deferred
= 0;
935 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
940 if (read_socket_hook
)
944 sigunblock (sigmask (SIGWINCH
));
946 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
948 interrupts_deferred
= 0;
954 if (read_socket_hook
)
958 sigblock (sigmask (SIGWINCH
));
960 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
);
961 interrupts_deferred
= 1;
964 #else /* no FASYNC */
965 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
972 if (read_socket_hook
)
975 ioctl (input_fd
, FIOASYNC
, &on
);
976 interrupts_deferred
= 0;
984 if (read_socket_hook
)
987 ioctl (input_fd
, FIOASYNC
, &off
);
988 interrupts_deferred
= 1;
991 #else /* not FASYNC, not STRIDE */
1003 if (read_socket_hook
)
1007 sigaddset (&st
, SIGIO
);
1008 ioctl (input_fd
, FIOASYNC
, &on
);
1009 interrupts_deferred
= 0;
1010 sigprocmask (SIG_UNBLOCK
, &st
, (sigset_t
*)0);
1018 if (read_socket_hook
)
1021 ioctl (input_fd
, FIOASYNC
, &off
);
1022 interrupts_deferred
= 1;
1025 #else /* ! _CX_UX */
1031 if (read_socket_hook
)
1034 croak ("request_sigio");
1040 if (read_socket_hook
)
1043 croak ("unrequest_sigio");
1050 #endif /* F_SETFL */
1052 /* Saving and restoring the process group of Emacs's terminal. */
1056 /* The process group of which Emacs was a member when it initially
1059 If Emacs was in its own process group (i.e. inherited_pgroup ==
1060 getpid ()), then we know we're running under a shell with job
1061 control (Emacs would never be run as part of a pipeline).
1064 If Emacs was not in its own process group, then we know we're
1065 running under a shell (or a caller) that doesn't know how to
1066 separate itself from Emacs (like sh). Emacs must be in its own
1067 process group in order to receive SIGIO correctly. In this
1068 situation, we put ourselves in our own pgroup, forcibly set the
1069 tty's pgroup to our pgroup, and make sure to restore and reinstate
1070 the tty's pgroup just like any other terminal setting. If
1071 inherited_group was not the tty's pgroup, then we'll get a
1072 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1073 it goes foreground in the future, which is what should happen. */
1074 int inherited_pgroup
;
1076 /* Split off the foreground process group to Emacs alone.
1077 When we are in the foreground, but not started in our own process
1078 group, redirect the TTY to point to our own process group. We need
1079 to be in our own process group to receive SIGIO properly. */
1081 narrow_foreground_group ()
1085 setpgrp (0, inherited_pgroup
);
1086 if (inherited_pgroup
!= me
)
1087 EMACS_SET_TTY_PGRP (input_fd
, &me
);
1091 /* Set the tty to our original foreground group. */
1093 widen_foreground_group ()
1095 if (inherited_pgroup
!= getpid ())
1096 EMACS_SET_TTY_PGRP (input_fd
, &inherited_pgroup
);
1097 setpgrp (0, inherited_pgroup
);
1100 #endif /* BSD_PGRPS */
1102 /* Getting and setting emacs_tty structures. */
1104 /* Set *TC to the parameters associated with the terminal FD.
1105 Return zero if all's well, or -1 if we ran into an error we
1106 couldn't deal with. */
1108 emacs_get_tty (fd
, settings
)
1110 struct emacs_tty
*settings
;
1112 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1114 /* We have those nifty POSIX tcmumbleattr functions. */
1115 bzero (&settings
->main
, sizeof (settings
->main
));
1116 if (tcgetattr (fd
, &settings
->main
) < 0)
1121 /* The SYSV-style interface? */
1122 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
1127 /* Vehemently Monstrous System? :-) */
1128 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
1129 &settings
->main
.class, 12, 0, 0, 0, 0)
1135 /* I give up - I hope you have the BSD ioctls. */
1136 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
1138 #endif /* not DOS_NT */
1143 /* Suivant - Do we have to get struct ltchars data? */
1145 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
1149 /* How about a struct tchars and a wordful of lmode bits? */
1151 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
1152 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
1156 /* We have survived the tempest. */
1161 /* Set the parameters of the tty on FD according to the contents of
1162 *SETTINGS. If FLUSHP is non-zero, we discard input.
1163 Return 0 if all went well, and -1 if anything failed. */
1166 emacs_set_tty (fd
, settings
, flushp
)
1168 struct emacs_tty
*settings
;
1171 /* Set the primary parameters - baud rate, character size, etcetera. */
1174 /* We have those nifty POSIX tcmumbleattr functions.
1175 William J. Smith <wjs@wiis.wang.com> writes:
1176 "POSIX 1003.1 defines tcsetattr to return success if it was
1177 able to perform any of the requested actions, even if some
1178 of the requested actions could not be performed.
1179 We must read settings back to ensure tty setup properly.
1180 AIX requires this to keep tty from hanging occasionally." */
1181 /* This make sure that we don't loop indefinitely in here. */
1182 for (i
= 0 ; i
< 10 ; i
++)
1183 if (tcsetattr (fd
, flushp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
1194 bzero (&new, sizeof (new));
1195 /* Get the current settings, and see if they're what we asked for. */
1196 tcgetattr (fd
, &new);
1197 /* We cannot use memcmp on the whole structure here because under
1198 * aix386 the termios structure has some reserved field that may
1201 if ( new.c_iflag
== settings
->main
.c_iflag
1202 && new.c_oflag
== settings
->main
.c_oflag
1203 && new.c_cflag
== settings
->main
.c_cflag
1204 && new.c_lflag
== settings
->main
.c_lflag
1205 && memcmp (new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
1213 /* The SYSV-style interface? */
1214 if (ioctl (fd
, flushp
? TCSETAF
: TCSETAW
, &settings
->main
) < 0)
1219 /* Vehemently Monstrous System? :-) */
1220 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
1221 &settings
->main
.class, 12, 0, 0, 0, 0)
1227 /* I give up - I hope you have the BSD ioctls. */
1228 if (ioctl (fd
, (flushp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
1230 #endif /* not DOS_NT */
1236 /* Suivant - Do we have to get struct ltchars data? */
1238 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
1242 /* How about a struct tchars and a wordful of lmode bits? */
1244 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
1245 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
1249 /* We have survived the tempest. */
1254 /* The initial tty mode bits */
1255 struct emacs_tty old_tty
;
1257 /* 1 if we have been through init_sys_modes. */
1260 /* 1 if outer tty status has been recorded. */
1264 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1269 #ifndef F_SETOWN_BUG
1271 int old_fcntl_owner
;
1272 #endif /* F_SETOWN */
1273 #endif /* F_SETOWN_BUG */
1275 /* This may also be defined in stdio,
1276 but if so, this does no harm,
1277 and using the same name avoids wasting the other one's space. */
1280 extern char *_sobuf
;
1282 #if defined (USG) || defined (DGUX)
1283 unsigned char _sobuf
[BUFSIZ
+8];
1285 char _sobuf
[BUFSIZ
];
1290 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
1293 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
1299 struct emacs_tty tty
;
1302 /* cus-start.el complains if delete-exited-processes is not defined */
1303 #ifndef subprocesses
1304 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes
,
1305 doc
: /* *Non-nil means delete processes immediately when they exit.
1306 nil means don't delete them until `list-processes' is run. */);
1307 delete_exited_processes
= 0;
1309 #endif /* MAC_OS8 */
1313 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
1314 extern int (*interrupt_signal
) ();
1318 Vtty_erase_char
= Qnil
;
1325 input_ef
= get_kbd_event_flag ();
1326 /* LIB$GET_EF (&input_ef); */
1327 SYS$
CLREF (input_ef
);
1328 waiting_for_ast
= 0;
1330 timer_ef
= get_timer_event_flag ();
1331 /* LIB$GET_EF (&timer_ef); */
1332 SYS$
CLREF (timer_ef
);
1336 LIB$
GET_EF (&process_ef
);
1337 SYS$
CLREF (process_ef
);
1339 if (input_ef
/ 32 != process_ef
/ 32)
1340 croak ("Input and process event flags in different clusters.");
1342 if (input_ef
/ 32 != timer_ef
/ 32)
1343 croak ("Input and timer event flags in different clusters.");
1345 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1346 ((unsigned) 1 << (process_ef
% 32));
1348 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1349 ((unsigned) 1 << (timer_ef
% 32));
1351 sys_access_reinit ();
1353 #endif /* not VMS */
1356 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1357 narrow_foreground_group ();
1360 #ifdef HAVE_WINDOW_SYSTEM
1361 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1362 needs the initialization code below. */
1363 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1366 EMACS_GET_TTY (input_fd
, &old_tty
);
1372 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1373 XSETINT (Vtty_erase_char
, old_tty
.main
.c_cc
[VERASE
]);
1376 /* This allows meta to be sent on 8th bit. */
1377 tty
.main
.c_iflag
&= ~INPCK
; /* don't check input for parity */
1379 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1380 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1381 #ifdef INLCR /* I'm just being cautious,
1382 since I can't check how widespread INLCR is--rms. */
1383 tty
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
1386 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1388 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1389 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1391 tty
.main
.c_lflag
&= ~IEXTEN
; /* Disable other editing characters. */
1393 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1396 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1398 tty
.main
.c_iflag
&= ~IXANY
;
1402 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1403 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1405 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1409 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1410 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1413 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1414 /* Set up C-g for both SIGQUIT and SIGINT.
1415 We don't know which we will get, but we handle both alike
1416 so which one it really gives us does not matter. */
1417 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1418 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1419 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1421 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1425 #if defined (mips) || defined (HAVE_TCATTR)
1427 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1430 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1431 #endif /* V_DSUSP */
1432 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1433 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1436 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1439 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1440 #endif /* VREPRINT */
1442 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1443 #endif /* VWERASE */
1445 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1446 #endif /* VDISCARD */
1451 tty
.main
.c_cc
[VSTART
] = '\021';
1454 tty
.main
.c_cc
[VSTOP
] = '\023';
1460 tty
.main
.c_cc
[VSTART
] = CDISABLE
;
1463 tty
.main
.c_cc
[VSTOP
] = CDISABLE
;
1466 #endif /* mips or HAVE_TCATTR */
1468 #ifdef SET_LINE_DISCIPLINE
1469 /* Need to explicitly request TERMIODISC line discipline or
1470 Ultrix's termios does not work correctly. */
1471 tty
.main
.c_line
= SET_LINE_DISCIPLINE
;
1475 /* AIX enhanced edit loses NULs, so disable it. */
1476 tty
.main
.c_line
= 0;
1477 tty
.main
.c_iflag
&= ~ASCEDIT
;
1479 tty
.main
.c_cc
[VSTRT
] = 255;
1480 tty
.main
.c_cc
[VSTOP
] = 255;
1481 tty
.main
.c_cc
[VSUSP
] = 255;
1482 tty
.main
.c_cc
[VDSUSP
] = 255;
1483 #endif /* IBMR2AIX */
1487 tty
.main
.c_cc
[VSTART
] = '\021';
1490 tty
.main
.c_cc
[VSTOP
] = '\023';
1493 /* Also, PTY overloads NUL and BREAK.
1494 don't ignore break, but don't signal either, so it looks like NUL.
1495 This really serves a purpose only if running in an XTERM window
1496 or via TELNET or the like, but does no harm elsewhere. */
1497 tty
.main
.c_iflag
&= ~IGNBRK
;
1498 tty
.main
.c_iflag
&= ~BRKINT
;
1500 #else /* if not HAVE_TERMIO */
1502 tty
.main
.tt_char
|= TT$M_NOECHO
;
1504 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1506 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1508 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1509 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1510 #else /* not VMS (BSD, that is) */
1512 XSETINT (Vtty_erase_char
, tty
.main
.sg_erase
);
1513 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1515 tty
.main
.sg_flags
|= ANYP
;
1516 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1517 #endif /* not DOS_NT */
1518 #endif /* not VMS (BSD, that is) */
1519 #endif /* not HAVE_TERMIO */
1521 /* If going to use CBREAK mode, we must request C-g to interrupt
1522 and turn off start and stop chars, etc. If not going to use
1523 CBREAK mode, do this anyway so as to turn off local flow
1524 control for user coming over network on 4.2; in this case,
1525 only t_stopc and t_startc really matter. */
1528 /* Note: if not using CBREAK mode, it makes no difference how we
1530 tty
.tchars
= new_tchars
;
1531 tty
.tchars
.t_intrc
= quit_char
;
1534 tty
.tchars
.t_startc
= '\021';
1535 tty
.tchars
.t_stopc
= '\023';
1538 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1540 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1541 anything, and leaving it in breaks the meta key. Go figure. */
1542 tty
.lmode
&= ~LLITOUT
;
1549 #endif /* HAVE_TCHARS */
1550 #endif /* not HAVE_TERMIO */
1553 tty
.ltchars
= new_ltchars
;
1554 #endif /* HAVE_LTCHARS */
1555 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1557 internal_terminal_init ();
1561 EMACS_SET_TTY (input_fd
, &tty
, 0);
1563 /* This code added to insure that, if flow-control is not to be used,
1564 we have an unlocked terminal at the start. */
1567 if (!flow_control
) ioctl (input_fd
, TCXONC
, 1);
1571 if (!flow_control
) ioctl (input_fd
, TIOCSTART
, 0);
1575 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1577 if (!flow_control
) tcflow (input_fd
, TCOON
);
1585 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1586 to be only LF. This is the way that is done. */
1589 if (ioctl (1, HFTGETID
, &tty
) != -1)
1590 write (1, "\033[20l", 5);
1596 /* Appears to do nothing when in PASTHRU mode.
1597 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1598 interrupt_signal, oob_chars, 0, 0, 0, 0);
1600 queue_kbd_input (0);
1605 #ifndef F_SETOWN_BUG
1606 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1608 && ! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1610 old_fcntl_owner
= fcntl (input_fd
, F_GETOWN
, 0);
1611 fcntl (input_fd
, F_SETOWN
, getpid ());
1612 init_sigio (input_fd
);
1614 #endif /* F_GETOWN */
1615 #endif /* F_SETOWN_BUG */
1616 #endif /* F_SETFL */
1619 if (interrupt_input
)
1620 init_sigio (input_fd
);
1623 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1627 /* This symbol is defined on recent USG systems.
1628 Someone says without this call USG won't really buffer the file
1629 even with a call to setbuf. */
1630 setvbuf (stdout
, (char *) _sobuf
, _IOFBF
, sizeof _sobuf
);
1632 setbuf (stdout
, (char *) _sobuf
);
1634 #ifdef HAVE_WINDOW_SYSTEM
1635 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1636 needs the initialization code below. */
1637 if (EQ (Vwindow_system
, Qnil
)
1639 /* When running in tty mode on NT/Win95, we have a read_socket
1640 hook, but still need the rest of the initialization code below. */
1641 && (! read_socket_hook
)
1645 set_terminal_modes ();
1648 && FRAMEP (Vterminal_frame
)
1649 && FRAME_TERMCAP_P (XFRAME (Vterminal_frame
)))
1650 init_frame_faces (XFRAME (Vterminal_frame
));
1652 if (term_initted
&& no_redraw_on_reenter
)
1654 if (display_completed
)
1655 direct_output_forward_char (0);
1660 if (FRAMEP (Vterminal_frame
))
1661 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1667 /* Return nonzero if safe to use tabs in output.
1668 At the time this is called, init_sys_modes has not been done yet. */
1673 struct emacs_tty tty
;
1675 EMACS_GET_TTY (input_fd
, &tty
);
1676 return EMACS_TTY_TABS_OK (&tty
);
1679 /* Get terminal size from system.
1680 Store number of lines into *HEIGHTP and width into *WIDTHP.
1681 We store 0 if there's no valid information. */
1684 get_frame_size (widthp
, heightp
)
1685 int *widthp
, *heightp
;
1691 struct winsize size
;
1693 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1694 *widthp
= *heightp
= 0;
1697 *widthp
= size
.ws_col
;
1698 *heightp
= size
.ws_row
;
1704 /* SunOS - style. */
1705 struct ttysize size
;
1707 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1708 *widthp
= *heightp
= 0;
1711 *widthp
= size
.ts_cols
;
1712 *heightp
= size
.ts_lines
;
1718 struct sensemode tty
;
1720 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1721 &tty
.class, 12, 0, 0, 0, 0);
1722 *widthp
= tty
.scr_wid
;
1723 *heightp
= tty
.scr_len
;
1727 *widthp
= ScreenCols ();
1728 *heightp
= ScreenRows ();
1729 #else /* system doesn't know size */
1734 #endif /* not VMS */
1735 #endif /* not SunOS-style */
1736 #endif /* not BSD-style */
1739 /* Set the logical window size associated with descriptor FD
1740 to HEIGHT and WIDTH. This is used mainly with ptys. */
1743 set_window_size (fd
, height
, width
)
1744 int fd
, height
, width
;
1749 struct winsize size
;
1750 size
.ws_row
= height
;
1751 size
.ws_col
= width
;
1753 if (ioctl (fd
, TIOCSWINSZ
, &size
) == -1)
1754 return 0; /* error */
1761 /* SunOS - style. */
1762 struct ttysize size
;
1763 size
.ts_lines
= height
;
1764 size
.ts_cols
= width
;
1766 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1772 #endif /* not SunOS-style */
1773 #endif /* not BSD-style */
1777 /* Prepare the terminal for exiting Emacs; move the cursor to the
1778 bottom of the frame, turn off interrupt-driven I/O, etc. */
1791 #ifdef HAVE_WINDOW_SYSTEM
1792 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1793 needs the clean-up code below. */
1794 if (!EQ (Vwindow_system
, Qnil
)
1796 /* When running in tty mode on NT/Win95, we have a read_socket
1797 hook, but still need the rest of the clean-up code below. */
1803 sf
= SELECTED_FRAME ();
1804 cursor_to (FRAME_LINES (sf
) - 1, 0);
1805 clear_end_of_line (FRAME_COLS (sf
));
1806 /* clear_end_of_line may move the cursor */
1807 cursor_to (FRAME_LINES (sf
) - 1, 0);
1808 #if defined (IBMR2AIX) && defined (AIXHFT)
1810 /* HFT devices normally use ^J as a LF/CR. We forced it to
1811 do the LF only. Now, we need to reset it. */
1814 if (ioctl (1, HFTGETID
, &tty
) != -1)
1815 write (1, "\033[20h", 5);
1819 reset_terminal_modes ();
1823 /* Avoid possible loss of output when changing terminal modes. */
1824 fsync (fileno (stdout
));
1829 #ifndef F_SETOWN_BUG
1830 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1831 if (interrupt_input
)
1834 fcntl (input_fd
, F_SETOWN
, old_fcntl_owner
);
1836 #endif /* F_SETOWN */
1837 #endif /* F_SETOWN_BUG */
1839 fcntl (input_fd
, F_SETFL
, fcntl (input_fd
, F_GETFL
, 0) & ~O_NDELAY
);
1841 #endif /* F_SETFL */
1843 if (interrupt_input
)
1848 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1851 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1855 #ifdef SET_LINE_DISCIPLINE
1856 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1857 A different old line discipline is therefore not restored, yet.
1858 Restore the old line discipline by hand. */
1859 ioctl (0, TIOCSETD
, &old_tty
.main
.c_line
);
1867 widen_foreground_group ();
1873 /* Set up the proper status flags for use of a pty. */
1879 /* I'm told that TOICREMOTE does not mean control chars
1880 "can't be sent" but rather that they don't have
1881 input-editing or signaling effects.
1882 That should be good, because we have other ways
1883 to do those things in Emacs.
1884 However, telnet mode seems not to work on 4.2.
1885 So TIOCREMOTE is turned off now. */
1887 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1888 will hang. In particular, the "timeout" feature (which
1889 causes a read to return if there is no data available)
1890 does this. Also it is known that telnet mode will hang
1891 in such a way that Emacs must be stopped (perhaps this
1892 is the same problem).
1894 If TIOCREMOTE is turned off, then there is a bug in
1895 hp-ux which sometimes loses data. Apparently the
1896 code which blocks the master process when the internal
1897 buffer fills up does not work. Other than this,
1898 though, everything else seems to work fine.
1900 Since the latter lossage is more benign, we may as well
1901 lose that way. -- cph */
1903 #if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
1906 ioctl (fd
, FIONBIO
, &on
);
1911 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1912 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1913 /* cause EMACS not to die when it should, i.e., when its own controlling */
1914 /* tty goes away. I've complained to the AIX developers, and they may */
1915 /* change this behavior, but I'm not going to hold my breath. */
1916 signal (SIGHUP
, SIG_IGN
);
1919 #endif /* HAVE_PTYS */
1923 /* Assigning an input channel is done at the start of Emacs execution.
1924 This is called each time Emacs is resumed, also, but does nothing
1925 because input_chain is no longer zero. */
1934 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1940 /* Deassigning the input channel is done before exiting. */
1945 return SYS$
DASSGN (input_fd
);
1950 /* Request reading one character into the keyboard buffer.
1951 This is done as soon as the buffer becomes empty. */
1957 extern kbd_input_ast ();
1959 waiting_for_ast
= 0;
1961 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1962 &input_iosb
, kbd_input_ast
, 1,
1963 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1968 /* Ast routine that is called when keyboard input comes in
1969 in accord with the SYS$QIO above. */
1974 register int c
= -1;
1975 int old_errno
= errno
;
1976 extern EMACS_TIME
*input_available_clear_time
;
1978 if (waiting_for_ast
)
1979 SYS$
SETEF (input_ef
);
1980 waiting_for_ast
= 0;
1983 if (input_count
== 25)
1985 printf ("Ast # %d,", input_count
);
1986 printf (" iosb = %x, %x, %x, %x",
1987 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1990 if (input_iosb
.offset
)
1994 printf (", char = 0%o", c
);
2006 struct input_event e
;
2009 e
.kind
= ASCII_KEYSTROKE_EVENT
;
2010 XSETINT (e
.code
, c
);
2011 e
.frame_or_window
= selected_frame
;
2012 kbd_buffer_store_event (&e
);
2014 if (input_available_clear_time
)
2015 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
2019 /* Wait until there is something in kbd_buffer. */
2022 wait_for_kbd_input ()
2024 extern int have_process_input
, process_exited
;
2026 /* If already something, avoid doing system calls. */
2027 if (detect_input_pending ())
2031 /* Clear a flag, and tell ast routine above to set it. */
2032 SYS$
CLREF (input_ef
);
2033 waiting_for_ast
= 1;
2034 /* Check for timing error: ast happened while we were doing that. */
2035 if (!detect_input_pending ())
2037 /* No timing error: wait for flag to be set. */
2038 set_waiting_for_input (0);
2039 SYS$
WFLOR (input_ef
, input_eflist
);
2040 clear_waiting_for_input ();
2041 if (!detect_input_pending ())
2042 /* Check for subprocess input availability */
2044 int dsp
= have_process_input
|| process_exited
;
2046 SYS$
CLREF (process_ef
);
2047 if (have_process_input
)
2048 process_command_input ();
2053 update_mode_lines
++;
2054 prepare_menu_bars ();
2055 redisplay_preserve_echo_area (18);
2059 waiting_for_ast
= 0;
2062 /* Get rid of any pending QIO, when we are about to suspend
2063 or when we want to throw away pending input.
2064 We wait for a positive sign that the AST routine has run
2065 and therefore there is no I/O request queued when we return.
2066 SYS$SETAST is used to avoid a timing error. */
2072 printf ("At end_kbd_input.\n");
2076 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2078 SYS$
CANCEL (input_fd
);
2083 /* Clear a flag, and tell ast routine above to set it. */
2084 SYS$
CLREF (input_ef
);
2085 waiting_for_ast
= 1;
2087 SYS$
CANCEL (input_fd
);
2089 SYS$
WAITFR (input_ef
);
2090 waiting_for_ast
= 0;
2093 /* Wait for either input available or time interval expiry. */
2096 input_wait_timeout (timeval
)
2097 int timeval
; /* Time to wait, in seconds */
2100 static int zero
= 0;
2101 static int large
= -10000000;
2103 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2105 /* If already something, avoid doing system calls. */
2106 if (detect_input_pending ())
2110 /* Clear a flag, and tell ast routine above to set it. */
2111 SYS$
CLREF (input_ef
);
2112 waiting_for_ast
= 1;
2113 /* Check for timing error: ast happened while we were doing that. */
2114 if (!detect_input_pending ())
2116 /* No timing error: wait for flag to be set. */
2118 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2119 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
2121 waiting_for_ast
= 0;
2124 /* The standard `sleep' routine works some other way
2125 and it stops working if you have ever quit out of it.
2126 This one continues to work. */
2132 static int zero
= 0;
2133 static int large
= -10000000;
2135 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2138 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2139 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
2157 croak ("request sigio");
2163 croak ("unrequest sigio");
2168 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2173 #ifndef SYSTEM_MALLOC
2180 /* Some systems that cannot dump also cannot implement these. */
2183 * Return the address of the start of the text segment prior to
2184 * doing an unexec. After unexec the return value is undefined.
2185 * See crt0.c for further explanation and _start.
2189 #if !(defined (__NetBSD__) && defined (__ELF__))
2190 #ifndef HAVE_TEXT_START
2195 return ((char *) TEXT_START
);
2199 return ((char *) csrt
);
2200 #else /* not GOULD */
2201 extern int _start ();
2202 return ((char *) _start
);
2204 #endif /* TEXT_START */
2206 #endif /* not HAVE_TEXT_START */
2210 * Return the address of the start of the data segment prior to
2211 * doing an unexec. After unexec the return value is undefined.
2212 * See crt0.c for further information and definition of data_start.
2214 * Apparently, on BSD systems this is etext at startup. On
2215 * USG systems (swapping) this is highly mmu dependent and
2216 * is also dependent on whether or not the program is running
2217 * with shared text. Generally there is a (possibly large)
2218 * gap between end of text and start of data with shared text.
2220 * On Uniplus+ systems with shared text, data starts at a
2221 * fixed address. Each port (from a given oem) is generally
2222 * different, and the specific value of the start of data can
2223 * be obtained via the UniPlus+ specific "uvar" system call,
2224 * however the method outlined in crt0.c seems to be more portable.
2226 * Probably what will have to happen when a USG unexec is available,
2227 * at least on UniPlus, is temacs will have to be made unshared so
2228 * that text and data are contiguous. Then once loadup is complete,
2229 * unexec will produce a shared executable where the data can be
2230 * at the normal shared text boundary and the startofdata variable
2231 * will be patched by unexec to the correct value.
2235 #ifndef start_of_data
2240 return ((char *) DATA_START
);
2242 #ifdef ORDINARY_LINK
2244 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2245 * data_start isn't defined. We take the address of environ, which
2246 * is known to live at or near the start of the system crt0.c, and
2247 * we don't sweat the handful of bytes that might lose.
2249 extern char **environ
;
2251 return ((char *) &environ
);
2253 extern int data_start
;
2254 return ((char *) &data_start
);
2255 #endif /* ORDINARY_LINK */
2256 #endif /* DATA_START */
2258 #endif /* start_of_data */
2259 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2261 /* init_system_name sets up the string for the Lisp function
2262 system-name to return. */
2268 extern Lisp_Object Vsystem_name
;
2273 #include <sys/socket.h>
2275 #endif /* HAVE_SOCKETS */
2276 #endif /* not VMS */
2277 #endif /* not BSD4_1 */
2280 #ifndef HAVE_H_ERRNO
2283 #endif /* TRY_AGAIN */
2289 Vsystem_name
= build_string (sysname
);
2293 if ((sp
= egetenv ("SYS$NODE")) == 0)
2294 Vsystem_name
= build_string ("vax-vms");
2295 else if ((end
= index (sp
, ':')) == 0)
2296 Vsystem_name
= build_string (sp
);
2298 Vsystem_name
= make_string (sp
, end
- sp
);
2300 #ifndef HAVE_GETHOSTNAME
2303 Vsystem_name
= build_string (uts
.nodename
);
2304 #else /* HAVE_GETHOSTNAME */
2305 unsigned int hostname_size
= 256;
2306 char *hostname
= (char *) alloca (hostname_size
);
2308 /* Try to get the host name; if the buffer is too short, try
2309 again. Apparently, the only indication gethostname gives of
2310 whether the buffer was large enough is the presence or absence
2311 of a '\0' in the string. Eech. */
2314 gethostname (hostname
, hostname_size
- 1);
2315 hostname
[hostname_size
- 1] = '\0';
2317 /* Was the buffer large enough for the '\0'? */
2318 if (strlen (hostname
) < hostname_size
- 1)
2321 hostname_size
<<= 1;
2322 hostname
= (char *) alloca (hostname_size
);
2325 /* Turn the hostname into the official, fully-qualified hostname.
2326 Don't do this if we're going to dump; this can confuse system
2327 libraries on some machines and make the dumped emacs core dump. */
2330 #endif /* not CANNOT_DUMP */
2331 if (! index (hostname
, '.'))
2335 for (count
= 0;; count
++)
2340 hp
= gethostbyname (hostname
);
2342 if (! (hp
== 0 && h_errno
== TRY_AGAIN
))
2347 Fsleep_for (make_number (1), Qnil
);
2351 char *fqdn
= (char *) hp
->h_name
;
2356 if (!index (fqdn
, '.'))
2358 /* We still don't have a fully qualified domain name.
2359 Try to find one in the list of alternate names */
2360 char **alias
= hp
->h_aliases
;
2361 while (*alias
&& !index (*alias
, '.'))
2368 /* Convert the host name to lower case. */
2369 /* Using ctype.h here would introduce a possible locale
2370 dependence that is probably wrong for hostnames. */
2374 if (*p
>= 'A' && *p
<= 'Z')
2381 #endif /* HAVE_SOCKETS */
2382 /* We used to try using getdomainname here,
2383 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2384 getdomainname gets the NIS/YP domain which often is not the same
2385 as in Internet domain name. */
2386 #if 0 /* Turned off because sysinfo is not really likely to return the
2387 correct Internet domain. */
2388 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2389 if (! index (hostname
, '.'))
2391 /* The hostname is not fully qualified. Append the domain name. */
2393 int hostlen
= strlen (hostname
);
2394 int domain_size
= 256;
2398 char *domain
= (char *) alloca (domain_size
+ 1);
2399 char *fqdn
= (char *) alloca (hostlen
+ 1 + domain_size
+ 1);
2400 int sys_domain_size
= sysinfo (SI_SRPC_DOMAIN
, domain
, domain_size
);
2401 if (sys_domain_size
<= 0)
2403 if (domain_size
< sys_domain_size
)
2405 domain_size
= sys_domain_size
;
2408 strcpy (fqdn
, hostname
);
2409 if (domain
[0] == '.')
2410 strcpy (fqdn
+ hostlen
, domain
);
2411 else if (domain
[0] != 0)
2413 fqdn
[hostlen
] = '.';
2414 strcpy (fqdn
+ hostlen
+ 1, domain
);
2420 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2422 Vsystem_name
= build_string (hostname
);
2423 #endif /* HAVE_GETHOSTNAME */
2428 for (p
= SDATA (Vsystem_name
); *p
; p
++)
2429 if (*p
== ' ' || *p
== '\t')
2436 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2438 #include "sysselect.h"
2441 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2442 /* Cause explanatory error message at compile time,
2443 since the select emulation is not good enough for X. */
2444 int *x
= &x_windows_lose_if_no_select_system_call
;
2447 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2448 * Only checks read descriptors.
2450 /* How long to wait between checking fds in select */
2451 #define SELECT_PAUSE 1
2454 /* For longjmp'ing back to read_input_waiting. */
2456 jmp_buf read_alarm_throw
;
2458 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2459 The read_socket_hook function sets this to 1 while it is waiting. */
2461 int read_alarm_should_throw
;
2469 #else /* not BSD4_1 */
2470 signal (SIGALRM
, SIG_IGN
);
2471 #endif /* not BSD4_1 */
2472 if (read_alarm_should_throw
)
2473 longjmp (read_alarm_throw
, 1);
2477 /* Only rfds are checked. */
2479 sys_select (nfds
, rfds
, wfds
, efds
, timeout
)
2481 SELECT_TYPE
*rfds
, *wfds
, *efds
;
2482 EMACS_TIME
*timeout
;
2488 extern int proc_buffered_char
[];
2489 #ifndef subprocesses
2490 int process_tick
= 0, update_tick
= 0;
2492 extern int process_tick
, update_tick
;
2496 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2497 /* If we're using X, then the native select will work; we only need the
2498 emulation for non-X usage. */
2499 if (!NILP (Vwindow_system
))
2500 return select (nfds
, rfds
, wfds
, efds
, timeout
);
2502 timeoutval
= timeout
? EMACS_SECS (*timeout
) : 100000;
2503 local_timeout
= &timeoutval
;
2515 /* If we are looking only for the terminal, with no timeout,
2516 just read it and wait -- that's more efficient. */
2517 if (*local_timeout
== 100000 && process_tick
== update_tick
2518 && FD_ISSET (0, &orfds
))
2521 for (fd
= 1; fd
< nfds
; ++fd
)
2522 if (FD_ISSET (fd
, &orfds
))
2524 if (! detect_input_pending ())
2525 read_input_waiting ();
2531 /* Once a second, till the timer expires, check all the flagged read
2532 * descriptors to see if any input is available. If there is some then
2533 * set the corresponding bit in the return copy of rfds.
2537 register int to_check
, fd
;
2541 for (to_check
= nfds
, fd
= 0; --to_check
>= 0; fd
++)
2543 if (FD_ISSET (fd
, &orfds
))
2545 int avail
= 0, status
= 0;
2548 avail
= detect_input_pending (); /* Special keyboard handler */
2552 status
= ioctl (fd
, FIONREAD
, &avail
);
2553 #else /* no FIONREAD */
2554 /* Hoping it will return -1 if nothing available
2555 or 0 if all 0 chars requested are read. */
2556 if (proc_buffered_char
[fd
] >= 0)
2560 avail
= read (fd
, &buf
, 1);
2562 proc_buffered_char
[fd
] = buf
;
2564 #endif /* no FIONREAD */
2566 if (status
>= 0 && avail
> 0)
2574 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2577 turn_on_atimers (0);
2578 signal (SIGALRM
, select_alarm
);
2580 alarm (SELECT_PAUSE
);
2582 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2583 while (select_alarmed
== 0 && *local_timeout
!= 0
2584 && process_tick
== update_tick
)
2586 /* If we are interested in terminal input,
2587 wait by reading the terminal.
2588 That makes instant wakeup for terminal input at least. */
2589 if (FD_ISSET (0, &orfds
))
2591 read_input_waiting ();
2592 if (detect_input_pending ())
2598 (*local_timeout
) -= SELECT_PAUSE
;
2600 /* Reset the old alarm if there was one. */
2601 turn_on_atimers (1);
2603 if (*local_timeout
== 0) /* Stop on timer being cleared */
2608 #endif /* not WINDOWSNT */
2610 /* Read keyboard input into the standard buffer,
2611 waiting for at least one character. */
2614 read_input_waiting ()
2617 extern int quit_char
;
2619 if (read_socket_hook
)
2621 struct input_event hold_quit
;
2623 EVENT_INIT (hold_quit
);
2624 hold_quit
.kind
= NO_EVENT
;
2626 read_alarm_should_throw
= 0;
2627 if (! setjmp (read_alarm_throw
))
2628 nread
= (*read_socket_hook
) (0, 1, &hold_quit
);
2632 if (hold_quit
.kind
!= NO_EVENT
)
2633 kbd_buffer_store_event (&hold_quit
);
2637 struct input_event e
;
2639 nread
= read (fileno (stdin
), buf
, 1);
2642 /* Scan the chars for C-g and store them in kbd_buffer. */
2643 e
.kind
= ASCII_KEYSTROKE_EVENT
;
2644 e
.frame_or_window
= selected_frame
;
2646 for (i
= 0; i
< nread
; i
++)
2648 /* Convert chars > 0177 to meta events if desired.
2649 We do this under the same conditions that read_avail_input does. */
2650 if (read_socket_hook
== 0)
2652 /* If the user says she has a meta key, then believe her. */
2653 if (meta_key
== 1 && (buf
[i
] & 0x80))
2654 e
.modifiers
= meta_modifier
;
2659 XSETINT (e
.code
, buf
[i
]);
2660 kbd_buffer_store_event (&e
);
2661 /* Don't look at input that follows a C-g too closely.
2662 This reduces lossage due to autorepeat on C-g. */
2663 if (buf
[i
] == quit_char
)
2669 #endif /* not HAVE_SELECT */
2670 #endif /* not VMS */
2671 #endif /* not MSDOS */
2680 lmode
= LINTRUP
| lmode
;
2681 ioctl (fd
, TIOCLSET
, &lmode
);
2689 lmode
= ~LINTRUP
& lmode
;
2690 ioctl (0, TIOCLSET
, &lmode
);
2698 interrupts_deferred
= 0;
2706 interrupts_deferred
= 1;
2709 /* still inside #ifdef BSD4_1 */
2712 int sigheld
; /* Mask of held signals */
2718 sigheld
|= sigbit (signum
);
2726 sigheld
|= sigbit (signum
);
2733 sigheld
&= ~sigbit (signum
);
2738 sigfree () /* Free all held signals */
2741 for (i
= 0; i
< NSIG
; i
++)
2742 if (sigheld
& sigbit (i
))
2750 return 1 << (i
- 1);
2752 #endif /* subprocesses */
2755 /* POSIX signals support - DJB */
2756 /* Anyone with POSIX signals should have ANSI C declarations */
2758 #ifdef POSIX_SIGNALS
2760 sigset_t empty_mask
, full_mask
;
2763 sys_signal (int signal_number
, signal_handler_t action
)
2765 struct sigaction new_action
, old_action
;
2766 sigemptyset (&new_action
.sa_mask
);
2767 new_action
.sa_handler
= action
;
2768 #if defined (SA_RESTART) && ! defined (BROKEN_SA_RESTART)
2769 /* Emacs mostly works better with restartable system services. If this
2770 flag exists, we probably want to turn it on here.
2771 However, on some systems this resets the timeout of `select'
2772 which means that `select' never finishes if it keeps getting signals.
2773 BROKEN_SA_RESTART is defined on those systems. */
2774 new_action
.sa_flags
= SA_RESTART
;
2776 new_action
.sa_flags
= 0;
2778 sigaction (signal_number
, &new_action
, &old_action
);
2779 return (old_action
.sa_handler
);
2783 /* If we're compiling with GCC, we don't need this function, since it
2784 can be written as a macro. */
2786 sys_sigmask (int sig
)
2789 sigemptyset (&mask
);
2790 sigaddset (&mask
, sig
);
2795 /* I'd like to have these guys return pointers to the mask storage in here,
2796 but there'd be trouble if the code was saving multiple masks. I'll be
2797 safe and pass the structure. It normally won't be more than 2 bytes
2801 sys_sigblock (sigset_t new_mask
)
2804 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2809 sys_sigunblock (sigset_t new_mask
)
2812 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2817 sys_sigsetmask (sigset_t new_mask
)
2820 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2824 #endif /* POSIX_SIGNALS */
2826 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2827 static char *my_sys_siglist
[NSIG
];
2831 # define sys_siglist my_sys_siglist
2837 #ifdef POSIX_SIGNALS
2838 sigemptyset (&empty_mask
);
2839 sigfillset (&full_mask
);
2842 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2846 sys_siglist
[SIGABRT
] = "Aborted";
2849 sys_siglist
[SIGAIO
] = "LAN I/O interrupt";
2852 sys_siglist
[SIGALRM
] = "Alarm clock";
2855 sys_siglist
[SIGBUS
] = "Bus error";
2858 sys_siglist
[SIGCLD
] = "Child status changed";
2861 sys_siglist
[SIGCHLD
] = "Child status changed";
2864 sys_siglist
[SIGCONT
] = "Continued";
2867 sys_siglist
[SIGDANGER
] = "Swap space dangerously low";
2870 sys_siglist
[SIGDGNOTIFY
] = "Notification message in queue";
2873 sys_siglist
[SIGEMT
] = "Emulation trap";
2876 sys_siglist
[SIGFPE
] = "Arithmetic exception";
2879 sys_siglist
[SIGFREEZE
] = "SIGFREEZE";
2882 sys_siglist
[SIGGRANT
] = "Monitor mode granted";
2885 sys_siglist
[SIGHUP
] = "Hangup";
2888 sys_siglist
[SIGILL
] = "Illegal instruction";
2891 sys_siglist
[SIGINT
] = "Interrupt";
2894 sys_siglist
[SIGIO
] = "I/O possible";
2897 sys_siglist
[SIGIOINT
] = "I/O intervention required";
2900 sys_siglist
[SIGIOT
] = "IOT trap";
2903 sys_siglist
[SIGKILL
] = "Killed";
2906 sys_siglist
[SIGLOST
] = "Resource lost";
2909 sys_siglist
[SIGLWP
] = "SIGLWP";
2912 sys_siglist
[SIGMSG
] = "Monitor mode data available";
2915 sys_siglist
[SIGWIND
] = "SIGPHONE";
2918 sys_siglist
[SIGPIPE
] = "Broken pipe";
2921 sys_siglist
[SIGPOLL
] = "Pollable event occurred";
2924 sys_siglist
[SIGPROF
] = "Profiling timer expired";
2927 sys_siglist
[SIGPTY
] = "PTY I/O interrupt";
2930 sys_siglist
[SIGPWR
] = "Power-fail restart";
2933 sys_siglist
[SIGQUIT
] = "Quit";
2936 sys_siglist
[SIGRETRACT
] = "Need to relinguish monitor mode";
2939 sys_siglist
[SIGSAK
] = "Secure attention";
2942 sys_siglist
[SIGSEGV
] = "Segmentation violation";
2945 sys_siglist
[SIGSOUND
] = "Sound completed";
2948 sys_siglist
[SIGSTOP
] = "Stopped (signal)";
2951 sys_siglist
[SIGSTP
] = "Stopped (user)";
2954 sys_siglist
[SIGSYS
] = "Bad argument to system call";
2957 sys_siglist
[SIGTERM
] = "Terminated";
2960 sys_siglist
[SIGTHAW
] = "SIGTHAW";
2963 sys_siglist
[SIGTRAP
] = "Trace/breakpoint trap";
2966 sys_siglist
[SIGTSTP
] = "Stopped (user)";
2969 sys_siglist
[SIGTTIN
] = "Stopped (tty input)";
2972 sys_siglist
[SIGTTOU
] = "Stopped (tty output)";
2975 sys_siglist
[SIGURG
] = "Urgent I/O condition";
2978 sys_siglist
[SIGUSR1
] = "User defined signal 1";
2981 sys_siglist
[SIGUSR2
] = "User defined signal 2";
2984 sys_siglist
[SIGVTALRM
] = "Virtual timer expired";
2987 sys_siglist
[SIGWAITING
] = "Process's LWPs are blocked";
2990 sys_siglist
[SIGWINCH
] = "Window size changed";
2993 sys_siglist
[SIGWIND
] = "SIGWIND";
2996 sys_siglist
[SIGXCPU
] = "CPU time limit exceeded";
2999 sys_siglist
[SIGXFSZ
] = "File size limit exceeded";
3002 #endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
3011 /* Figure out how many bits the system's random number generator uses.
3012 `random' and `lrand48' are assumed to return 31 usable bits.
3013 BSD `rand' returns a 31 bit value but the low order bits are unusable;
3014 so we'll shift it and treat it like the 15-bit USG `rand'. */
3018 # define RAND_BITS 31
3019 # else /* !HAVE_RANDOM */
3020 # ifdef HAVE_LRAND48
3021 # define RAND_BITS 31
3022 # define random lrand48
3023 # else /* !HAVE_LRAND48 */
3024 # define RAND_BITS 15
3025 # if RAND_MAX == 32767
3026 # define random rand
3027 # else /* RAND_MAX != 32767 */
3028 # if RAND_MAX == 2147483647
3029 # define random() (rand () >> 16)
3030 # else /* RAND_MAX != 2147483647 */
3032 # define random rand
3034 # define random() (rand () >> 16)
3036 # endif /* RAND_MAX != 2147483647 */
3037 # endif /* RAND_MAX != 32767 */
3038 # endif /* !HAVE_LRAND48 */
3039 # endif /* !HAVE_RANDOM */
3040 #endif /* !RAND_BITS */
3047 srandom ((unsigned int)arg
);
3049 # ifdef HAVE_LRAND48
3052 srand ((unsigned int)arg
);
3058 * Build a full Emacs-sized word out of whatever we've got.
3059 * This suffices even for a 64-bit architecture with a 15-bit rand.
3064 long val
= random ();
3065 #if VALBITS > RAND_BITS
3066 val
= (val
<< RAND_BITS
) ^ random ();
3067 #if VALBITS > 2*RAND_BITS
3068 val
= (val
<< RAND_BITS
) ^ random ();
3069 #if VALBITS > 3*RAND_BITS
3070 val
= (val
<< RAND_BITS
) ^ random ();
3071 #if VALBITS > 4*RAND_BITS
3072 val
= (val
<< RAND_BITS
) ^ random ();
3073 #endif /* need at least 5 */
3074 #endif /* need at least 4 */
3075 #endif /* need at least 3 */
3076 #endif /* need at least 2 */
3077 return val
& ((1L << VALBITS
) - 1);
3080 #ifdef WRONG_NAME_INSQUE
3093 /* If any place else asks for the TERM variable,
3094 allow it to be overridden with the EMACS_TERM variable
3095 before attempting to translate the logical name TERM. As a last
3096 resort, ask for VAX C's special idea of the TERM variable. */
3103 static char buf
[256];
3104 static struct dsc$descriptor_s equiv
3105 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
3106 static struct dsc$descriptor_s d_name
3107 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
3110 if (!strcmp (name
, "TERM"))
3112 val
= (char *) getenv ("EMACS_TERM");
3117 d_name
.dsc$w_length
= strlen (name
);
3118 d_name
.dsc$a_pointer
= name
;
3119 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
3121 char *str
= (char *) xmalloc (eqlen
+ 1);
3122 bcopy (buf
, str
, eqlen
);
3124 /* This is a storage leak, but a pain to fix. With luck,
3125 no one will ever notice. */
3128 return (char *) getenv (name
);
3133 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
3134 to force a call on the debugger from within the image. */
3139 LIB$
SIGNAL (SS$_DEBUG
);
3145 #ifdef LINK_CRTL_SHARE
3146 #ifdef SHARABLE_LIB_BUG
3147 /* Variables declared noshare and initialized in sharable libraries
3148 cannot be shared. The VMS linker incorrectly forces you to use a private
3149 version which is uninitialized... If not for this "feature", we
3150 could use the C library definition of sys_nerr and sys_errlist. */
3152 char *sys_errlist
[] =
3156 "no such file or directory",
3158 "interrupted system call",
3160 "no such device or address",
3161 "argument list too long",
3162 "exec format error",
3165 "no more processes",
3166 "not enough memory",
3167 "permission denied",
3169 "block device required",
3170 "mount devices busy",
3172 "cross-device link",
3177 "file table overflow",
3178 "too many open files",
3182 "no space left on device",
3184 "read-only file system",
3190 "vax/vms specific error code nontranslatable error"
3192 #endif /* SHARABLE_LIB_BUG */
3193 #endif /* LINK_CRTL_SHARE */
3196 #ifndef HAVE_STRERROR
3202 extern char *sys_errlist
[];
3203 extern int sys_nerr
;
3205 if (errnum
>= 0 && errnum
< sys_nerr
)
3206 return sys_errlist
[errnum
];
3207 return (char *) "Unknown error";
3209 #endif /* not WINDOWSNT */
3210 #endif /* ! HAVE_STRERROR */
3213 emacs_open (path
, oflag
, mode
)
3217 register int rtnval
;
3220 if (oflag
& O_CREAT
)
3221 return creat (path
, mode
);
3224 while ((rtnval
= open (path
, oflag
, mode
)) == -1
3225 && (errno
== EINTR
));
3234 register int rtnval
;
3236 while ((rtnval
= close (fd
)) == -1
3237 && (errno
== EINTR
))
3240 /* If close is interrupted SunOS 4.1 may or may not have closed the
3241 file descriptor. If it did the second close will fail with
3242 errno = EBADF. That means we have succeeded. */
3243 if (rtnval
== -1 && did_retry
&& errno
== EBADF
)
3250 emacs_read (fildes
, buf
, nbyte
)
3255 register int rtnval
;
3257 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
3258 && (errno
== EINTR
));
3263 emacs_write (fildes
, buf
, nbyte
)
3268 register int rtnval
, bytes_written
;
3274 rtnval
= write (fildes
, buf
, nbyte
);
3281 return (bytes_written
? bytes_written
: -1);
3286 bytes_written
+= rtnval
;
3288 return (bytes_written
);
3293 * All of the following are for USG.
3295 * On USG systems the system calls are INTERRUPTIBLE by signals
3296 * that the user program has elected to catch. Thus the system call
3297 * must be retried in these cases. To handle this without massive
3298 * changes in the source code, we remap the standard system call names
3299 * to names for our own functions in sysdep.c that do the system call
3300 * with retries. Actually, for portability reasons, it is good
3301 * programming practice, as this example shows, to limit all actual
3302 * system calls to a single occurrence in the source. Sure, this
3303 * adds an extra level of function call overhead but it is almost
3304 * always negligible. Fred Fish, Unisoft Systems Inc.
3308 * Warning, this function may not duplicate 4.2 action properly
3309 * under error conditions.
3313 /* In 4.1, param.h fails to define this. */
3314 #define MAXPATHLEN 1024
3323 char *npath
, *spath
;
3324 extern char *getcwd ();
3326 BLOCK_INPUT
; /* getcwd uses malloc */
3327 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
3333 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3334 up to first slash. Should be harmless on other systems. */
3335 while (*npath
&& *npath
!= '/')
3337 strcpy (pathname
, npath
);
3338 free (spath
); /* getcwd uses malloc */
3343 #endif /* HAVE_GETWD */
3346 * Emulate rename using unlink/link. Note that this is
3347 * only partially correct. Also, doesn't enforce restriction
3348 * that files be of same type (regular->regular, dir->dir, etc).
3357 if (access (from
, 0) == 0)
3360 if (link (from
, to
) == 0)
3361 if (unlink (from
) == 0)
3373 /* HPUX curses library references perror, but as far as we know
3374 it won't be called. Anyway this definition will do for now. */
3380 #endif /* not HAVE_PERROR */
3386 * Emulate BSD dup2. First close newd if it already exists.
3387 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3388 * until we are, then close the unsuccessful ones.
3395 register int fd
, ret
;
3400 return fcntl (oldd
, F_DUPFD
, newd
);
3407 ret
= dup2 (old
,new);
3413 #endif /* not HAVE_DUP2 */
3416 * Gettimeofday. Simulate as much as possible. Only accurate
3417 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3418 * Only needed when subprocesses are defined.
3423 #ifndef HAVE_GETTIMEOFDAY
3428 gettimeofday (tp
, tzp
)
3430 struct timezone
*tzp
;
3432 extern long time ();
3434 tp
->tv_sec
= time ((long *)0);
3437 tzp
->tz_minuteswest
= -1;
3444 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3447 * This function will go away as soon as all the stubs fixed. (fnf)
3454 printf ("%s not yet implemented\r\n", badfunc
);
3461 /* Directory routines for systems that don't have them. */
3463 #ifdef SYSV_SYSTEM_DIR
3467 #if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
3471 register DIR *dirp
; /* stream from opendir */
3475 rtnval
= emacs_close (dirp
->dd_fd
);
3477 /* Some systems (like Solaris) allocate the buffer and the DIR all
3478 in one block. Why in the world are we freeing this ourselves
3480 #if ! (defined (sun) && defined (USG5_4))
3481 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
3483 xfree ((char *) dirp
);
3487 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3488 #endif /* SYSV_SYSTEM_DIR */
3490 #ifdef NONSYSTEM_DIR_LIBRARY
3494 char *filename
; /* name of directory */
3496 register DIR *dirp
; /* -> malloc'ed storage */
3497 register int fd
; /* file descriptor for read */
3498 struct stat sbuf
; /* result of fstat */
3500 fd
= emacs_open (filename
, O_RDONLY
, 0);
3505 if (fstat (fd
, &sbuf
) < 0
3506 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
3507 || (dirp
= (DIR *) xmalloc (sizeof (DIR))) == 0)
3511 return 0; /* bad luck today */
3516 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
3523 register DIR *dirp
; /* stream from opendir */
3525 emacs_close (dirp
->dd_fd
);
3526 xfree ((char *) dirp
);
3534 ino_t od_ino
; /* inode */
3535 char od_name
[DIRSIZ
]; /* filename */
3537 #endif /* not VMS */
3539 struct direct dir_static
; /* simulated directory contents */
3544 register DIR *dirp
; /* stream from opendir */
3547 register struct olddir
*dp
; /* -> directory data */
3549 register struct dir$_name
*dp
; /* -> directory data */
3550 register struct dir$_version
*dv
; /* -> version data */
3555 if (dirp
->dd_loc
>= dirp
->dd_size
)
3556 dirp
->dd_loc
= dirp
->dd_size
= 0;
3558 if (dirp
->dd_size
== 0 /* refill buffer */
3559 && (dirp
->dd_size
= emacs_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3563 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3564 dirp
->dd_loc
+= sizeof (struct olddir
);
3566 if (dp
->od_ino
!= 0) /* not deleted entry */
3568 dir_static
.d_ino
= dp
->od_ino
;
3569 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3570 dir_static
.d_name
[DIRSIZ
] = '\0';
3571 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3572 dir_static
.d_reclen
= sizeof (struct direct
)
3574 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3575 return &dir_static
; /* -> simulated structure */
3578 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3579 if (dirp
->dd_loc
== 0)
3580 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3581 : dp
->dir$b_namecount
;
3582 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3583 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3584 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3585 dir_static
.d_reclen
= sizeof (struct direct
)
3587 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3588 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3589 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3590 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3597 /* readdirver is just like readdir except it returns all versions of a file
3598 as separate entries. */
3603 register DIR *dirp
; /* stream from opendir */
3605 register struct dir$_name
*dp
; /* -> directory data */
3606 register struct dir$_version
*dv
; /* -> version data */
3608 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3609 dirp
->dd_loc
= dirp
->dd_size
= 0;
3611 if (dirp
->dd_size
== 0 /* refill buffer */
3612 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3615 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3616 if (dirp
->dd_loc
== 0)
3617 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3618 : dp
->dir$b_namecount
;
3619 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3620 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3621 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3622 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3623 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3624 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3625 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3626 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3632 #endif /* NONSYSTEM_DIR_LIBRARY */
3636 set_file_times (filename
, atime
, mtime
)
3637 const char *filename
;
3638 EMACS_TIME atime
, mtime
;
3641 struct timeval tv
[2];
3644 return utimes (filename
, tv
);
3645 #else /* not HAVE_UTIMES */
3647 utb
.actime
= EMACS_SECS (atime
);
3648 utb
.modtime
= EMACS_SECS (mtime
);
3649 return utime (filename
, &utb
);
3650 #endif /* not HAVE_UTIMES */
3653 /* mkdir and rmdir functions, for systems which don't have them. */
3657 * Written by Robert Rother, Mariah Corporation, August 1985.
3659 * If you want it, it's yours. All I ask in return is that if you
3660 * figure out how to do this in a Bourne Shell script you send me
3662 * sdcsvax!rmr or rmr@uscd
3664 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3665 * subroutine. 11Mar86; hoptoad!gnu
3667 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3668 * subroutine didn't return EEXIST. It does now.
3674 #ifdef MKDIR_PROTOTYPE
3678 mkdir (dpath
, dmode
)
3683 int cpid
, status
, fd
;
3684 struct stat statbuf
;
3686 if (stat (dpath
, &statbuf
) == 0)
3688 errno
= EEXIST
; /* Stat worked, so it already exists */
3692 /* If stat fails for a reason other than non-existence, return error */
3693 if (errno
!= ENOENT
)
3696 synch_process_alive
= 1;
3697 switch (cpid
= fork ())
3700 case -1: /* Error in fork */
3701 return (-1); /* Errno is set already */
3703 case 0: /* Child process */
3705 * Cheap hack to set mode of new directory. Since this
3706 * child process is going away anyway, we zap its umask.
3707 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3708 * directory. Does anybody care?
3710 status
= umask (0); /* Get current umask */
3711 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3712 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3719 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3720 _exit (-1); /* Can't exec /bin/mkdir */
3722 default: /* Parent process */
3723 wait_for_termination (cpid
);
3726 if (synch_process_death
!= 0 || synch_process_retcode
!= 0
3727 || synch_process_termsig
!= 0)
3729 errno
= EIO
; /* We don't know why, but */
3730 return -1; /* /bin/mkdir failed */
3735 #endif /* not HAVE_MKDIR */
3742 int cpid
, status
, fd
;
3743 struct stat statbuf
;
3745 if (stat (dpath
, &statbuf
) != 0)
3747 /* Stat just set errno. We don't have to */
3751 synch_process_alive
= 1;
3752 switch (cpid
= fork ())
3755 case -1: /* Error in fork */
3756 return (-1); /* Errno is set already */
3758 case 0: /* Child process */
3759 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3766 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
3767 _exit (-1); /* Can't exec /bin/rmdir */
3769 default: /* Parent process */
3770 wait_for_termination (cpid
);
3773 if (synch_process_death
!= 0 || synch_process_retcode
!= 0
3774 || synch_process_termsig
!= 0)
3776 errno
= EIO
; /* We don't know why, but */
3777 return -1; /* /bin/rmdir failed */
3782 #endif /* !HAVE_RMDIR */
3786 /* Functions for VMS */
3788 #include "vms-pwd.h"
3793 /* Return as a string the VMS error string pertaining to STATUS.
3794 Reuses the same static buffer each time it is called. */
3798 int status
; /* VMS status code */
3802 static char buf
[257];
3804 bufadr
[0] = sizeof buf
- 1;
3805 bufadr
[1] = (int) buf
;
3806 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3807 return "untranslatable VMS error status";
3815 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3816 * not work correctly. (It also doesn't work well in version 2.3.)
3821 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3822 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3826 unsigned short s_buflen
;
3827 unsigned short s_code
;
3829 unsigned short *s_retlenadr
;
3833 #define buflen s.s_buflen
3834 #define code s.s_code
3835 #define bufadr s.s_bufadr
3836 #define retlenadr s.s_retlenadr
3838 #define R_OK 4 /* test for read permission */
3839 #define W_OK 2 /* test for write permission */
3840 #define X_OK 1 /* test for execute (search) permission */
3841 #define F_OK 0 /* test for presence of file */
3844 sys_access (path
, mode
)
3848 static char *user
= NULL
;
3851 /* translate possible directory spec into .DIR file name, so brain-dead
3852 * access can treat the directory like a file. */
3853 if (directory_file_name (path
, dir_fn
))
3857 return access (path
, mode
);
3858 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3864 unsigned short int dummy
;
3866 static int constant
= ACL$C_FILE
;
3867 DESCRIPTOR (path_desc
, path
);
3868 DESCRIPTOR (user_desc
, user
);
3872 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3875 acces
|= CHP$M_READ
;
3877 acces
|= CHP$M_WRITE
;
3878 itemlst
[0].buflen
= sizeof (int);
3879 itemlst
[0].code
= CHP$_FLAGS
;
3880 itemlst
[0].bufadr
= (char *) &flags
;
3881 itemlst
[0].retlenadr
= &dummy
;
3882 itemlst
[1].buflen
= sizeof (int);
3883 itemlst
[1].code
= CHP$_ACCESS
;
3884 itemlst
[1].bufadr
= (char *) &acces
;
3885 itemlst
[1].retlenadr
= &dummy
;
3886 itemlst
[2].end
= CHP$_END
;
3887 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3888 return stat
== SS$_NORMAL
? 0 : -1;
3892 #else /* not VMS4_4 */
3895 #define ACE$M_WRITE 2
3896 #define ACE$C_KEYID 1
3898 static unsigned short memid
, grpid
;
3899 static unsigned int uic
;
3901 /* Called from init_sys_modes, so it happens not very often
3902 but at least each time Emacs is loaded. */
3904 sys_access_reinit ()
3910 sys_access (filename
, type
)
3916 int status
, size
, i
, typecode
, acl_controlled
;
3917 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3918 union prvdef prvmask
;
3920 /* Get UIC and GRP values for protection checking. */
3923 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3926 memid
= uic
& 0xFFFF;
3930 if (type
!= 2) /* not checking write access */
3931 return access (filename
, type
);
3933 /* Check write protection. */
3935 #define CHECKPRIV(bit) (prvmask.bit)
3936 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3938 /* Find privilege bits */
3939 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3941 error ("Unable to find privileges: %s", vmserrstr (status
));
3942 if (CHECKPRIV (PRV$V_BYPASS
))
3943 return 0; /* BYPASS enabled */
3945 fab
.fab$b_fac
= FAB$M_GET
;
3946 fab
.fab$l_fna
= filename
;
3947 fab
.fab$b_fns
= strlen (filename
);
3948 fab
.fab$l_xab
= &xab
;
3949 xab
= cc$rms_xabpro
;
3950 xab
.xab$l_aclbuf
= aclbuf
;
3951 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3952 status
= SYS$
OPEN (&fab
, 0, 0);
3955 SYS$
CLOSE (&fab
, 0, 0);
3956 /* Check system access */
3957 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITABLE (XAB$V_SYS
))
3959 /* Check ACL entries, if any */
3961 if (xab
.xab$w_acllen
> 0)
3964 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3965 while (*aclptr
&& aclptr
< aclend
)
3967 size
= (*aclptr
& 0xff) / 4;
3968 typecode
= (*aclptr
>> 8) & 0xff;
3969 if (typecode
== ACE$C_KEYID
)
3970 for (i
= size
- 1; i
> 1; i
--)
3971 if (aclptr
[i
] == uic
)
3974 if (aclptr
[1] & ACE$M_WRITE
)
3975 return 0; /* Write access through ACL */
3977 aclptr
= &aclptr
[size
];
3979 if (acl_controlled
) /* ACL specified, prohibits write access */
3982 /* No ACL entries specified, check normal protection */
3983 if (WRITABLE (XAB$V_WLD
)) /* World writable */
3985 if (WRITABLE (XAB$V_GRP
) &&
3986 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3987 return 0; /* Group writable */
3988 if (WRITABLE (XAB$V_OWN
) &&
3989 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3990 return 0; /* Owner writable */
3992 return -1; /* Not writable */
3994 #endif /* not VMS4_4 */
3997 static char vtbuf
[NAM$C_MAXRSS
+1];
3999 /* translate a vms file spec to a unix path */
4001 sys_translate_vms (vfile
)
4012 /* leading device or logical name is a root directory */
4013 if (p
= strchr (vfile
, ':'))
4022 if (*p
== '[' || *p
== '<')
4024 while (*++vfile
!= *p
+ 2)
4028 if (vfile
[-1] == *p
)
4051 static char utbuf
[NAM$C_MAXRSS
+1];
4053 /* translate a unix path to a VMS file spec */
4055 sys_translate_unix (ufile
)
4078 if (index (&ufile
[1], '/'))
4085 if (index (&ufile
[1], '/'))
4092 if (strncmp (ufile
, "./", 2) == 0)
4099 ufile
++; /* skip the dot */
4100 if (index (&ufile
[1], '/'))
4105 else if (strncmp (ufile
, "../", 3) == 0)
4113 ufile
+= 2; /* skip the dots */
4114 if (index (&ufile
[1], '/'))
4139 extern char *getcwd ();
4141 #define MAXPATHLEN 1024
4143 ptr
= xmalloc (MAXPATHLEN
);
4144 val
= getcwd (ptr
, MAXPATHLEN
);
4150 strcpy (pathname
, ptr
);
4159 long item_code
= JPI$_OWNER
;
4160 unsigned long parent_id
;
4163 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
4166 vaxc$errno
= status
;
4176 return (getgid () << 16) | getuid ();
4181 sys_read (fildes
, buf
, nbyte
)
4186 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
4191 sys_write (fildes
, buf
, nbyte
)
4196 register int nwrote
, rtnval
= 0;
4198 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
4204 return rtnval
? rtnval
: -1;
4205 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
4206 return rtnval
? rtnval
: -1;
4207 return (rtnval
+ nwrote
);
4212 * VAX/VMS VAX C RTL really loses. It insists that records
4213 * end with a newline (carriage return) character, and if they
4214 * don't it adds one (nice of it isn't it!)
4216 * Thus we do this stupidity below.
4221 sys_write (fildes
, buf
, nbytes
)
4224 unsigned int nbytes
;
4231 fstat (fildes
, &st
);
4237 /* Handle fixed-length files with carriage control. */
4238 if (st
.st_fab_rfm
== FAB$C_FIX
4239 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
4241 len
= st
.st_fab_mrs
;
4242 retval
= write (fildes
, p
, min (len
, nbytes
));
4245 retval
++; /* This skips the implied carriage control */
4249 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4250 while (*e
!= '\n' && e
> p
) e
--;
4251 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
4252 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4254 retval
= write (fildes
, p
, len
);
4265 /* Create file NEW copying its attributes from file OLD. If
4266 OLD is 0 or does not exist, create based on the value of
4269 /* Protection value the file should ultimately have.
4270 Set by create_copy_attrs, and use by rename_sansversions. */
4271 static unsigned short int fab_final_pro
;
4274 creat_copy_attrs (old
, new)
4277 struct FAB fab
= cc$rms_fab
;
4278 struct XABPRO xabpro
;
4279 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
4280 extern int vms_stmlf_recfm
;
4284 fab
.fab$b_fac
= FAB$M_GET
;
4285 fab
.fab$l_fna
= old
;
4286 fab
.fab$b_fns
= strlen (old
);
4287 fab
.fab$l_xab
= (char *) &xabpro
;
4288 xabpro
= cc$rms_xabpro
;
4289 xabpro
.xab$l_aclbuf
= aclbuf
;
4290 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
4291 /* Call $OPEN to fill in the fab & xabpro fields. */
4292 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4294 SYS$
CLOSE (&fab
, 0, 0);
4295 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
4296 if (xabpro
.xab$w_acllen
> 0)
4298 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
4299 /* If the acl buffer was too short, redo open with longer one.
4300 Wouldn't need to do this if there were some system imposed
4301 limit on the size of an ACL, but I can't find any such. */
4303 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
4304 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
4305 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4306 SYS$
CLOSE (&fab
, 0, 0);
4312 xabpro
.xab$l_aclbuf
= 0;
4317 fab
.fab$l_fna
= new;
4318 fab
.fab$b_fns
= strlen (new);
4322 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
4323 fab
.fab$b_rat
= FAB$M_CR
;
4326 /* Set the file protections such that we will be able to manipulate
4327 this file. Once we are done writing and renaming it, we will set
4328 the protections back. */
4330 fab_final_pro
= xabpro
.xab$w_pro
;
4332 SYS$
SETDFPROT (0, &fab_final_pro
);
4333 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
4335 /* Create the new file with either default attrs or attrs copied
4337 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
4339 SYS$
CLOSE (&fab
, 0, 0);
4340 /* As this is a "replacement" for creat, return a file descriptor
4341 opened for writing. */
4342 return open (new, O_WRONLY
);
4347 #include <varargs.h>
4350 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4355 sys_creat (va_alist
)
4358 va_list list_incrementer
;
4361 int rfd
; /* related file descriptor */
4362 int fd
; /* Our new file descriptor */
4369 extern int vms_stmlf_recfm
;
4372 va_start (list_incrementer
);
4373 name
= va_arg (list_incrementer
, char *);
4374 mode
= va_arg (list_incrementer
, int);
4376 rfd
= va_arg (list_incrementer
, int);
4377 va_end (list_incrementer
);
4380 /* Use information from the related file descriptor to set record
4381 format of the newly created file. */
4382 fstat (rfd
, &st_buf
);
4383 switch (st_buf
.st_fab_rfm
)
4386 strcpy (rfm
, "rfm = fix");
4387 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
4388 strcpy (rat
, "rat = ");
4389 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4391 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4392 strcat (rat
, "ftn");
4393 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4394 strcat (rat
, "prn");
4395 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4396 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4397 strcat (rat
, ", blk");
4399 strcat (rat
, "blk");
4400 return creat (name
, 0, rfm
, rat
, mrs
);
4403 strcpy (rfm
, "rfm = vfc");
4404 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
4405 strcpy (rat
, "rat = ");
4406 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4408 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4409 strcat (rat
, "ftn");
4410 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4411 strcat (rat
, "prn");
4412 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4413 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4414 strcat (rat
, ", blk");
4416 strcat (rat
, "blk");
4417 return creat (name
, 0, rfm
, rat
, fsz
);
4420 strcpy (rfm
, "rfm = stm");
4424 strcpy (rfm
, "rfm = stmcr");
4428 strcpy (rfm
, "rfm = stmlf");
4432 strcpy (rfm
, "rfm = udf");
4436 strcpy (rfm
, "rfm = var");
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");
4454 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
4455 strcpy (rat
, "rat=cr");
4457 /* Until the VAX C RTL fixes the many bugs with modes, always use
4458 mode 0 to get the user's default protection. */
4459 fd
= creat (name
, 0, rfm
, rat
);
4460 if (fd
< 0 && errno
== EEXIST
)
4462 if (unlink (name
) < 0)
4463 report_file_error ("delete", build_string (name
));
4464 fd
= creat (name
, 0, rfm
, rat
);
4470 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4472 sys_fwrite (ptr
, size
, num
, fp
)
4473 register char * ptr
;
4476 register int tot
= num
* size
;
4484 * The VMS C library routine creat actually creates a new version of an
4485 * existing file rather than truncating the old version. There are times
4486 * when this is not the desired behavior, for instance, when writing an
4487 * auto save file (you only want one version), or when you don't have
4488 * write permission in the directory containing the file (but the file
4489 * itself is writable). Hence this routine, which is equivalent to
4490 * "close (creat (fn, 0));" on Unix if fn already exists.
4496 struct FAB xfab
= cc$rms_fab
;
4497 struct RAB xrab
= cc$rms_rab
;
4500 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
4501 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
4502 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
4503 xfab
.fab$l_fna
= fn
;
4504 xfab
.fab$b_fns
= strlen (fn
);
4505 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
4507 xrab
.rab$l_fab
= &xfab
;
4509 /* This gibberish opens the file, positions to the first record, and
4510 deletes all records from there until the end of file. */
4511 if ((SYS$
OPEN (&xfab
) & 01) == 01)
4513 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
4514 (SYS$
FIND (&xrab
) & 01) == 01 &&
4515 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
4526 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4527 SYSPRV or a readable SYSUAF.DAT. */
4533 * Routine to read the VMS User Authorization File and return
4534 * a specific user's record.
4537 static struct UAF retuaf
;
4540 get_uaf_name (uname
)
4547 uaf_fab
= cc$rms_fab
;
4548 uaf_rab
= cc$rms_rab
;
4549 /* initialize fab fields */
4550 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4551 uaf_fab
.fab$b_fns
= 21;
4552 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4553 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4554 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4555 /* initialize rab fields */
4556 uaf_rab
.rab$l_fab
= &uaf_fab
;
4557 /* open the User Authorization File */
4558 status
= SYS$
OPEN (&uaf_fab
);
4562 vaxc$errno
= status
;
4565 status
= SYS$
CONNECT (&uaf_rab
);
4569 vaxc$errno
= status
;
4572 /* read the requested record - index is in uname */
4573 uaf_rab
.rab$l_kbf
= uname
;
4574 uaf_rab
.rab$b_ksz
= strlen (uname
);
4575 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4576 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4577 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4578 status
= SYS$
GET (&uaf_rab
);
4582 vaxc$errno
= status
;
4585 /* close the User Authorization File */
4586 status
= SYS$
DISCONNECT (&uaf_rab
);
4590 vaxc$errno
= status
;
4593 status
= SYS$
CLOSE (&uaf_fab
);
4597 vaxc$errno
= status
;
4611 uaf_fab
= cc$rms_fab
;
4612 uaf_rab
= cc$rms_rab
;
4613 /* initialize fab fields */
4614 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4615 uaf_fab
.fab$b_fns
= 21;
4616 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4617 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4618 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4619 /* initialize rab fields */
4620 uaf_rab
.rab$l_fab
= &uaf_fab
;
4621 /* open the User Authorization File */
4622 status
= SYS$
OPEN (&uaf_fab
);
4626 vaxc$errno
= status
;
4629 status
= SYS$
CONNECT (&uaf_rab
);
4633 vaxc$errno
= status
;
4636 /* read the requested record - index is in uic */
4637 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4638 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4639 uaf_rab
.rab$b_ksz
= sizeof uic
;
4640 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4641 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4642 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4643 status
= SYS$
GET (&uaf_rab
);
4647 vaxc$errno
= status
;
4650 /* close the User Authorization File */
4651 status
= SYS$
DISCONNECT (&uaf_rab
);
4655 vaxc$errno
= status
;
4658 status
= SYS$
CLOSE (&uaf_fab
);
4662 vaxc$errno
= status
;
4668 static struct passwd retpw
;
4676 /* copy these out first because if the username is 32 chars, the next
4677 section will overwrite the first byte of the UIC */
4678 retpw
.pw_uid
= up
->uaf$w_mem
;
4679 retpw
.pw_gid
= up
->uaf$w_grp
;
4681 /* I suppose this is not the best style, to possibly overwrite one
4682 byte beyond the end of the field, but what the heck... */
4683 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4684 while (ptr
[-1] == ' ')
4687 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4689 /* the rest of these are counted ascii strings */
4690 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4691 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4692 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4693 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4694 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4695 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4696 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4697 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4701 #else /* not READ_SYSUAF */
4702 static struct passwd retpw
;
4703 #endif /* not READ_SYSUAF */
4714 unsigned char * full
;
4715 #endif /* READ_SYSUAF */
4720 if ('a' <= *ptr
&& *ptr
<= 'z')
4725 if (!(up
= get_uaf_name (name
)))
4727 return cnv_uaf_pw (up
);
4729 if (strcmp (name
, getenv ("USER")) == 0)
4731 retpw
.pw_uid
= getuid ();
4732 retpw
.pw_gid
= getgid ();
4733 strcpy (retpw
.pw_name
, name
);
4734 if (full
= egetenv ("FULLNAME"))
4735 strcpy (retpw
.pw_gecos
, full
);
4737 *retpw
.pw_gecos
= '\0';
4738 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4739 *retpw
.pw_shell
= '\0';
4744 #endif /* not READ_SYSUAF */
4754 if (!(up
= get_uaf_uic (uid
)))
4756 return cnv_uaf_pw (up
);
4758 if (uid
== sys_getuid ())
4759 return getpwnam (egetenv ("USER"));
4762 #endif /* not READ_SYSUAF */
4765 /* return total address space available to the current process. This is
4766 the sum of the current p0 size, p1 size and free page table entries
4772 unsigned long free_pages
;
4773 unsigned long frep0va
;
4774 unsigned long frep1va
;
4777 item_code
= JPI$_FREPTECNT
;
4778 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4781 vaxc$errno
= status
;
4786 item_code
= JPI$_FREP0VA
;
4787 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4790 vaxc$errno
= status
;
4793 item_code
= JPI$_FREP1VA
;
4794 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4797 vaxc$errno
= status
;
4801 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4805 define_logical_name (varname
, string
)
4809 struct dsc$descriptor_s strdsc
=
4810 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4811 struct dsc$descriptor_s envdsc
=
4812 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4813 struct dsc$descriptor_s lnmdsc
=
4814 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4816 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4820 delete_logical_name (varname
)
4823 struct dsc$descriptor_s envdsc
=
4824 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4825 struct dsc$descriptor_s lnmdsc
=
4826 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4828 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4846 error ("execvp system call not implemented");
4855 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4856 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4857 char from_esn
[NAM$C_MAXRSS
];
4858 char to_esn
[NAM$C_MAXRSS
];
4860 from_fab
.fab$l_fna
= from
;
4861 from_fab
.fab$b_fns
= strlen (from
);
4862 from_fab
.fab$l_nam
= &from_nam
;
4863 from_fab
.fab$l_fop
= FAB$M_NAM
;
4865 from_nam
.nam$l_esa
= from_esn
;
4866 from_nam
.nam$b_ess
= sizeof from_esn
;
4868 to_fab
.fab$l_fna
= to
;
4869 to_fab
.fab$b_fns
= strlen (to
);
4870 to_fab
.fab$l_nam
= &to_nam
;
4871 to_fab
.fab$l_fop
= FAB$M_NAM
;
4873 to_nam
.nam$l_esa
= to_esn
;
4874 to_nam
.nam$b_ess
= sizeof to_esn
;
4876 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4882 if (status
== RMS$_DEV
)
4886 vaxc$errno
= status
;
4891 /* This function renames a file like `rename', but it strips
4892 the version number from the "to" filename, such that the "to" file is
4893 will always be a new version. It also sets the file protection once it is
4894 finished. The protection that we will use is stored in fab_final_pro,
4895 and was set when we did a creat_copy_attrs to create the file that we
4898 We could use the chmod function, but Eunichs uses 3 bits per user category
4899 to describe the protection, and VMS uses 4 (write and delete are separate
4900 bits). To maintain portability, the VMS implementation of `chmod' wires
4901 the W and D bits together. */
4904 static struct fibdef fib
; /* We need this initialized to zero */
4905 char vms_file_written
[NAM$C_MAXRSS
];
4908 rename_sans_version (from
,to
)
4915 struct FAB to_fab
= cc$rms_fab
;
4916 struct NAM to_nam
= cc$rms_nam
;
4917 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4918 struct dsc$descriptor fib_attr
[2]
4919 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4920 char to_esn
[NAM$C_MAXRSS
];
4922 $
DESCRIPTOR (disk
,to_esn
);
4924 to_fab
.fab$l_fna
= to
;
4925 to_fab
.fab$b_fns
= strlen (to
);
4926 to_fab
.fab$l_nam
= &to_nam
;
4927 to_fab
.fab$l_fop
= FAB$M_NAM
;
4929 to_nam
.nam$l_esa
= to_esn
;
4930 to_nam
.nam$b_ess
= sizeof to_esn
;
4932 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4934 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4935 *(to_nam
.nam$l_ver
) = '\0';
4937 stat
= rename (from
, to_esn
);
4941 strcpy (vms_file_written
, to_esn
);
4943 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4944 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4946 /* Now set the file protection to the correct value */
4947 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4949 /* Copy these fields into the fib */
4950 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4951 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4952 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4954 SYS$
CLOSE (&to_fab
, 0, 0);
4956 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4959 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4960 0, 0, 0, &fib_attr
, 0);
4963 stat
= SYS$
DASSGN (chan
);
4966 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4977 unsigned short fid
[3];
4978 char esa
[NAM$C_MAXRSS
];
4981 fab
.fab$l_fop
= FAB$M_OFP
;
4982 fab
.fab$l_fna
= file
;
4983 fab
.fab$b_fns
= strlen (file
);
4984 fab
.fab$l_nam
= &nam
;
4987 nam
.nam$l_esa
= esa
;
4988 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4990 status
= SYS$
PARSE (&fab
);
4991 if ((status
& 1) == 0)
4994 vaxc$errno
= status
;
4997 status
= SYS$
SEARCH (&fab
);
4998 if ((status
& 1) == 0)
5001 vaxc$errno
= status
;
5005 fid
[0] = nam
.nam$w_fid
[0];
5006 fid
[1] = nam
.nam$w_fid
[1];
5007 fid
[2] = nam
.nam$w_fid
[2];
5009 fab
.fab$l_fna
= new;
5010 fab
.fab$b_fns
= strlen (new);
5012 status
= SYS$
PARSE (&fab
);
5013 if ((status
& 1) == 0)
5016 vaxc$errno
= status
;
5020 nam
.nam$w_fid
[0] = fid
[0];
5021 nam
.nam$w_fid
[1] = fid
[1];
5022 nam
.nam$w_fid
[2] = fid
[2];
5024 nam
.nam$l_esa
= nam
.nam$l_name
;
5025 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
5027 status
= SYS$
ENTER (&fab
);
5028 if ((status
& 1) == 0)
5031 vaxc$errno
= status
;
5042 printf ("%s not yet implemented\r\n", badfunc
);
5050 /* Arrange to return a range centered on zero. */
5051 return rand () - (1 << 30);
5063 /* Called from init_sys_modes. */
5069 /* If we're not on an HFT we shouldn't do any of this. We determine
5070 if we are on an HFT by trying to get an HFT error code. If this
5071 call fails, we're not on an HFT. */
5073 if (ioctl (0, HFQERROR
, &junk
) < 0)
5075 #else /* not IBMR2AIX */
5076 if (ioctl (0, HFQEIO
, 0) < 0)
5078 #endif /* not IBMR2AIX */
5080 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5081 as the rubout key's ASCII code. Here this is changed. The bug is that
5082 there's no way to determine the old mapping, so in reset_sys_modes
5083 we need to assume that the normal map had been present. Of course, this
5084 code also doesn't help if on a terminal emulator which doesn't understand
5088 struct hfkeymap keymap
;
5090 buf
.hf_bufp
= (char *)&keymap
;
5091 buf
.hf_buflen
= sizeof (keymap
);
5092 keymap
.hf_nkeys
= 2;
5093 keymap
.hfkey
[0].hf_kpos
= 15;
5094 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5096 keymap
.hfkey
[0].hf_keyidh
= '<';
5097 #else /* not IBMR2AIX */
5098 keymap
.hfkey
[0].hf_page
= '<';
5099 #endif /* not IBMR2AIX */
5100 keymap
.hfkey
[0].hf_char
= 127;
5101 keymap
.hfkey
[1].hf_kpos
= 15;
5102 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5104 keymap
.hfkey
[1].hf_keyidh
= '<';
5105 #else /* not IBMR2AIX */
5106 keymap
.hfkey
[1].hf_page
= '<';
5107 #endif /* not IBMR2AIX */
5108 keymap
.hfkey
[1].hf_char
= 127;
5109 hftctl (0, HFSKBD
, &buf
);
5111 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
5113 line_ins_del_ok
= char_ins_del_ok
= 0;
5116 /* Reset the rubout key to backspace. */
5122 struct hfkeymap keymap
;
5126 if (ioctl (0, HFQERROR
, &junk
) < 0)
5128 #else /* not IBMR2AIX */
5129 if (ioctl (0, HFQEIO
, 0) < 0)
5131 #endif /* not IBMR2AIX */
5133 buf
.hf_bufp
= (char *)&keymap
;
5134 buf
.hf_buflen
= sizeof (keymap
);
5135 keymap
.hf_nkeys
= 2;
5136 keymap
.hfkey
[0].hf_kpos
= 15;
5137 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5139 keymap
.hfkey
[0].hf_keyidh
= '<';
5140 #else /* not IBMR2AIX */
5141 keymap
.hfkey
[0].hf_page
= '<';
5142 #endif /* not IBMR2AIX */
5143 keymap
.hfkey
[0].hf_char
= 8;
5144 keymap
.hfkey
[1].hf_kpos
= 15;
5145 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5147 keymap
.hfkey
[1].hf_keyidh
= '<';
5148 #else /* not IBMR2AIX */
5149 keymap
.hfkey
[1].hf_page
= '<';
5150 #endif /* not IBMR2AIX */
5151 keymap
.hfkey
[1].hf_char
= 8;
5152 hftctl (0, HFSKBD
, &buf
);
5159 /* These are included on Sunos 4.1 when we do not use shared libraries.
5160 X11 libraries may refer to these functions but (we hope) do not
5161 actually call them. */
5181 #endif /* USE_DL_STUBS */
5190 register int length
;
5194 long max_str
= 65535;
5196 while (length
> max_str
) {
5197 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5202 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5204 while (length
-- > 0)
5206 #endif /* not VMS */
5209 #endif /* no bzero */
5210 #endif /* BSTRING */
5212 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5215 /* Saying `void' requires a declaration, above, where bcopy is used
5216 and that declaration causes pain for systems where bcopy is a macro. */
5217 bcopy (b1
, b2
, length
)
5220 register int length
;
5223 long max_str
= 65535;
5225 while (length
> max_str
) {
5226 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
5232 (void) LIB$
MOVC3 (&length
, b1
, b2
);
5234 while (length
-- > 0)
5236 #endif /* not VMS */
5238 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5243 bcmp (b1
, b2
, length
) /* This could be a macro! */
5246 register int length
;
5249 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
5250 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
5252 return STR$
COMPARE (&src1
, &src2
);
5254 while (length
-- > 0)
5259 #endif /* not VMS */
5261 #endif /* no bcmp */
5262 #endif /* not BSTRING */
5264 #ifndef HAVE_STRSIGNAL
5271 if (0 <= code
&& code
< NSIG
)
5274 signame
= sys_errlist
[code
];
5276 /* Cast to suppress warning if the table has const char *. */
5277 signame
= (char *) sys_siglist
[code
];
5283 #endif /* HAVE_STRSIGNAL */
5285 /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
5286 (do not change this comment) */