1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 86,87,88,93,94,95, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
30 /* Including stdlib.h isn't necessarily enough to get srandom
31 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
33 #if 0 /* It turns out that defining _OSF_SOURCE in osf5-0.h gets
34 random prototyped as returning `int'. It looks to me as
35 though the best way to DTRT is to prefer the rand48 functions
36 (per libc.info). -- fx */
37 extern long int random
P_ ((void));
39 #if 0 /* Don't prototype srandom; it takes an unsigned argument on
40 some systems, and an unsigned long on others, like FreeBSD
42 extern void srandom
P_ ((unsigned int));
46 #include "blockinput.h"
50 /* It is essential to include stdlib.h so that this file picks up
51 the correct definitions of rand, srand, and RAND_MAX.
52 Otherwise random numbers will not work correctly. */
56 /* Nonzero means delete a process right away if it exits (process.c). */
57 static int delete_exited_processes
;
59 #endif /* macintosh */
63 #define write sys_write
68 #endif /* not WINDOWSNT */
70 /* Does anyone other than VMS need this? */
72 #define sys_fwrite fwrite
78 #include <sys/types.h>
82 /* Get _POSIX_VDISABLE, if it is available. */
92 #if !defined (USG) || defined (BSD_PGRPS)
94 #define setpgrp setpgid
98 /* Get SI_SRPC_DOMAIN, if it is available. */
99 #ifdef HAVE_SYS_SYSTEMINFO_H
100 #include <sys/systeminfo.h>
103 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
107 #include <sys/param.h>
111 extern unsigned start
__asm__ ("start");
133 #include <sys/file.h>
141 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
145 #ifdef BSD_SYSTEM /* avoid writing defined (BSD_SYSTEM) || defined (USG)
146 because the vms compiler doesn't grok `defined' */
154 #endif /* not 4.1 bsd */
157 #include <sys/ioctl.h>
163 #ifdef BROKEN_TIOCGWINSZ
168 #if defined (USG) || defined (DGUX)
169 #include <sys/utsname.h>
170 #ifndef MEMORY_IN_STRING_H
173 #if defined (TIOCGWINSZ) || defined (ISC4_0)
175 #include <sys/sioctl.h>
178 #include <sys/stream.h>
179 #include <sys/ptem.h>
181 #endif /* TIOCGWINSZ or ISC4_0 */
182 #endif /* USG or DGUX */
184 extern int quit_char
;
186 #include "keyboard.h"
189 #include "termhooks.h"
190 #include "termchar.h"
191 #include "termopts.h"
192 #include "dispextern.h"
197 /* In process.h which conflicts with the local copy. */
199 int _CRTAPI1
_spawnlp (int, const char *, const char *, ...);
200 int _CRTAPI1
_getpid (void);
203 #ifdef NONSYSTEM_DIR_LIBRARY
205 #endif /* NONSYSTEM_DIR_LIBRARY */
207 #include "syssignal.h"
214 #ifndef HAVE_STRUCT_UTIMBUF
215 /* We want to use utime rather than utimes, but we couldn't find the
216 structure declaration. We'll use the traditional one. */
224 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
230 #define LNOFLSH 0100000
233 static int baud_convert
[] =
238 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
239 1800, 2400, 4800, 9600, 19200, 38400
246 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
248 #if defined (HAVE_TERMIOS_H) && defined (LINUX)
256 /* The file descriptor for Emacs's input terminal.
257 Under Unix, this is normally zero except when using X;
258 under VMS, we place the input channel number here. */
261 void croak
P_ ((char *));
268 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
270 SIGMASKTYPE sigprocmask_set
;
273 /* Specify a different file descriptor for further input operations. */
282 /* Discard pending input on descriptor input_fd. */
288 struct emacs_tty buf
;
293 /* Discarding input is not safe when the input could contain
294 replies from the X server. So don't do it. */
295 if (read_socket_hook
)
300 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
301 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
307 ioctl (input_fd
, TIOCFLUSH
, &zero
);
309 #else /* not Apollo */
310 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
311 while (dos_keyread () != -1)
313 #else /* not MSDOS */
314 EMACS_GET_TTY (input_fd
, &buf
);
315 EMACS_SET_TTY (input_fd
, &buf
, 0);
316 #endif /* not MSDOS */
317 #endif /* not Apollo */
319 #endif /* not WINDOWSNT */
324 /* Arrange for character C to be read as the next input from
331 if (read_socket_hook
)
334 /* Should perhaps error if in batch mode */
336 ioctl (input_fd
, TIOCSTI
, &c
);
337 #else /* no TIOCSTI */
338 error ("Cannot stuff terminal input characters in this version of Unix");
339 #endif /* no TIOCSTI */
351 #ifdef INIT_BAUD_RATE
356 #else /* not DOS_NT */
360 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
361 &sg
.class, 12, 0, 0, 0, 0 );
362 emacs_ospeed
= sg
.xmit_baud
;
368 tcgetattr (input_fd
, &sg
);
369 emacs_ospeed
= cfgetospeed (&sg
);
370 #if defined (USE_GETOBAUD) && defined (getobaud)
371 /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
372 if (emacs_ospeed
== 0)
373 emacs_ospeed
= getobaud (sg
.c_cflag
);
375 #else /* neither VMS nor TERMIOS */
381 tcgetattr (input_fd
, &sg
);
383 ioctl (input_fd
, TCGETA
, &sg
);
385 emacs_ospeed
= sg
.c_cflag
& CBAUD
;
386 #else /* neither VMS nor TERMIOS nor TERMIO */
389 sg
.sg_ospeed
= B9600
;
390 if (ioctl (input_fd
, TIOCGETP
, &sg
) < 0)
392 emacs_ospeed
= sg
.sg_ospeed
;
393 #endif /* not HAVE_TERMIO */
394 #endif /* not HAVE_TERMIOS */
396 #endif /* not DOS_NT */
397 #endif /* not INIT_BAUD_RATE */
400 baud_rate
= (emacs_ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
401 ? baud_convert
[emacs_ospeed
] : 9600);
408 set_exclusive_use (fd
)
412 ioctl (fd
, FIOCLEX
, 0);
414 /* Ok to do nothing if this feature does not exist */
419 wait_without_blocking ()
422 wait3 (0, WNOHANG
| WUNTRACED
, 0);
424 croak ("wait_without_blocking");
426 synch_process_alive
= 0;
429 #endif /* not subprocesses */
431 int wait_debugging
; /* Set nonzero to make following function work under dbx
432 (at least for bsd). */
435 wait_for_termination_signal ()
438 /* Wait for subprocess with process id `pid' to terminate and
439 make sure it will get eliminated (not remain forever as a zombie) */
442 wait_for_termination (pid
)
451 status
= SYS$
FORCEX (&pid
, 0, 0);
454 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
455 /* Note that kill returns -1 even if the process is just a zombie now.
456 But inevitably a SIGCHLD interrupt should be generated
457 and child_sig will do wait3 and make the process go away. */
458 /* There is some indication that there is a bug involved with
459 termination of subprocesses, perhaps involving a kernel bug too,
460 but no idea what it is. Just as a hunch we signal SIGCHLD to see
461 if that causes the problem to go away or get worse. */
462 sigsetmask (sigmask (SIGCHLD
));
463 if (0 > kill (pid
, 0))
465 sigsetmask (SIGEMPTYMASK
);
466 kill (getpid (), SIGCHLD
);
472 sigpause (SIGEMPTYMASK
);
473 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
474 #if defined (UNIPLUS)
475 if (0 > kill (pid
, 0))
478 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
479 #ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
480 sigblock (sigmask (SIGCHLD
));
482 if (kill (pid
, 0) == -1 && errno
== ESRCH
)
484 sigunblock (sigmask (SIGCHLD
));
488 /* FIXME: Since sigpause is not POSIX and its use is deprecated,
489 this should probably be `sigsuspend (&empty_mask)', which is
490 POSIX. I'm not making that change right away because the
491 release is nearing. 2001-09-20 gerd. */
492 sigpause (SIGEMPTYMASK
);
493 #else /* not POSIX_SIGNALS */
494 #ifdef HAVE_SYSV_SIGPAUSE
496 if (0 > kill (pid
, 0))
502 #else /* not HAVE_SYSV_SIGPAUSE */
506 #else /* not WINDOWSNT */
507 if (0 > kill (pid
, 0))
509 /* Using sleep instead of pause avoids timing error.
510 If the inferior dies just before the sleep,
511 we lose just one second. */
513 #endif /* not WINDOWSNT */
514 #endif /* not HAVE_SYSV_SIGPAUSE */
515 #endif /* not POSIX_SIGNALS */
516 #endif /* not UNIPLUS */
517 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
519 #else /* not subprocesses */
522 #else /* not __DJGPP__ > 1 */
524 if (kill (pid
, 0) < 0)
530 if (status
== pid
|| status
== -1)
533 #endif /* not __DJGPP__ > 1*/
534 #endif /* not subprocesses */
541 * flush any pending output
542 * (may flush input as well; it does not matter the way we use it)
546 flush_pending_output (channel
)
550 /* If we try this, we get hit with SIGTTIN, because
551 the child's tty belongs to the child's pgrp. */
554 ioctl (channel
, TCFLSH
, 1);
558 /* 3rd arg should be ignored
559 but some 4.2 kernels actually want the address of an int
560 and nonzero means something different. */
561 ioctl (channel
, TIOCFLUSH
, &zero
);
568 /* Set up the terminal at the other end of a pseudo-terminal that
569 we will be controlling an inferior through.
570 It should not echo or do line-editing, since that is done
571 in Emacs. No padding needed for insertion into an Emacs buffer. */
574 child_setup_tty (out
)
580 EMACS_GET_TTY (out
, &s
);
582 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
583 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
584 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
586 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
587 /* No output delays */
589 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
590 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
591 #if 0 /* This causes bugs in (for instance) telnet to certain sites. */
592 s
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
593 #ifdef INLCR /* Just being cautious, since I can't check how
594 widespread INLCR is--rms. */
595 s
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
599 s
.main
.c_iflag
&= ~IUCLC
; /* Disable downcasing on input. */
602 s
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
605 s
.main
.c_oflag
&= ~OLCUC
; /* Disable upcasing on output. */
607 s
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
608 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CSIZE
) | CS8
; /* Don't strip 8th bit */
610 /* Said to be unnecessary: */
611 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
612 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
615 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
616 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
617 s
.main
.c_cc
[VERASE
] = CDISABLE
; /* disable erase processing */
618 s
.main
.c_cc
[VKILL
] = CDISABLE
; /* disable kill processing */
621 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
625 /* AIX enhanced edit loses NULs, so disable it */
628 s
.main
.c_iflag
&= ~ASCEDIT
;
630 /* Also, PTY overloads NUL and BREAK.
631 don't ignore break, but don't signal either, so it looks like NUL. */
632 s
.main
.c_iflag
&= ~IGNBRK
;
633 s
.main
.c_iflag
&= ~BRKINT
;
634 /* QUIT and INTR work better as signals, so disable character forms */
635 s
.main
.c_cc
[VINTR
] = 0377;
636 #ifdef SIGNALS_VIA_CHARACTERS
637 /* the QUIT and INTR character are used in process_send_signal
638 so set them here to something useful. */
639 if (s
.main
.c_cc
[VQUIT
] == 0377)
640 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
641 if (s
.main
.c_cc
[VINTR
] == 0377)
642 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
643 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
644 /* QUIT and INTR work better as signals, so disable character forms */
645 s
.main
.c_cc
[VQUIT
] = 0377;
646 s
.main
.c_cc
[VINTR
] = 0377;
647 s
.main
.c_lflag
&= ~ISIG
;
648 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
649 s
.main
.c_cc
[VEOL
] = 0377;
650 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
653 #else /* not HAVE_TERMIO */
655 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
657 s
.main
.sg_flags
|= LPASS8
;
658 s
.main
.sg_erase
= 0377;
659 s
.main
.sg_kill
= 0377;
660 s
.lmode
= LLITOUT
| s
.lmode
; /* Don't strip 8th bit */
662 #endif /* not HAVE_TERMIO */
664 EMACS_SET_TTY (out
, &s
, 0);
673 ioctl (out
, FIOASYNC
, &zero
);
676 #endif /* not DOS_NT */
680 #endif /* subprocesses */
682 /* Record a signal code and the handler for it. */
686 SIGTYPE (*handler
) P_ ((int));
689 static void save_signal_handlers
P_ ((struct save_signal
*));
690 static void restore_signal_handlers
P_ ((struct save_signal
*));
692 /* Suspend the Emacs process; give terminal to its superior. */
698 /* "Foster" parentage allows emacs to return to a subprocess that attached
699 to the current emacs as a cheaper than starting a whole new process. This
700 is set up by KEPTEDITOR.COM. */
701 unsigned long parent_id
, foster_parent_id
;
704 fpid_string
= getenv ("EMACS_PARENT_PID");
705 if (fpid_string
!= NULL
)
707 sscanf (fpid_string
, "%x", &foster_parent_id
);
708 if (foster_parent_id
!= 0)
709 parent_id
= foster_parent_id
;
711 parent_id
= getppid ();
714 parent_id
= getppid ();
716 xfree (fpid_string
); /* On VMS, this was malloc'd */
718 if (parent_id
&& parent_id
!= 0xffffffff)
720 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
721 int status
= LIB$
ATTACH (&parent_id
) & 1;
722 signal (SIGINT
, oldsig
);
731 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
732 d_prompt
.a
= "Emacs: "; /* Just a reminder */
733 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
738 #if defined (SIGTSTP) && !defined (MSDOS)
741 int pgrp
= EMACS_GETPGRP (0);
742 EMACS_KILLPG (pgrp
, SIGTSTP
);
745 #else /* No SIGTSTP */
746 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
747 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
748 kill (getpid (), SIGQUIT
);
750 #else /* No SIGTSTP or USG_JOBCTRL */
752 /* On a system where suspending is not implemented,
753 instead fork a subshell and let it talk directly to the terminal
757 #endif /* no USG_JOBCTRL */
758 #endif /* no SIGTSTP */
762 /* Fork a subshell. */
769 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
771 char oldwd
[MAXPATHLEN
+1]; /* Fixed length is safe on MSDOS. */
774 struct save_signal saved_handlers
[5];
776 unsigned char *str
= 0;
779 saved_handlers
[0].code
= SIGINT
;
780 saved_handlers
[1].code
= SIGQUIT
;
781 saved_handlers
[2].code
= SIGTERM
;
783 saved_handlers
[3].code
= SIGIO
;
784 saved_handlers
[4].code
= 0;
786 saved_handlers
[3].code
= 0;
789 /* Mentioning current_buffer->buffer would mean including buffer.h,
790 which somehow wedges the hp compiler. So instead... */
792 dir
= intern ("default-directory");
793 if (NILP (Fboundp (dir
)))
795 dir
= Fsymbol_value (dir
);
799 dir
= expand_and_dir_to_file (Funhandled_file_name_directory (dir
), Qnil
);
800 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
801 len
= XSTRING (dir
)->size
;
802 bcopy (XSTRING (dir
)->data
, str
, len
);
803 if (str
[len
- 1] != '/') str
[len
++] = '/';
810 save_signal_handlers (saved_handlers
);
811 synch_process_alive
= 1;
812 #endif /* __DJGPP__ > 1 */
816 error ("Can't spawn subshell");
823 #ifdef DOS_NT /* MW, Aug 1993 */
826 sh
= (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
829 sh
= (char *) egetenv ("SHELL");
833 /* Use our buffer's default directory for the subshell. */
835 chdir ((char *) str
);
838 close_process_descs (); /* Close Emacs's pipes/ptys */
841 #ifdef SET_EMACS_PRIORITY
843 extern int emacs_priority
;
845 if (emacs_priority
< 0)
846 nice (-emacs_priority
);
850 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
853 #if 0 /* This is also reported if last command executed in subshell failed, KFS */
855 report_file_error ("Can't execute subshell", Fcons (build_string (sh
), Qnil
));
857 #else /* not MSDOS */
859 /* Waits for process completion */
860 pid
= _spawnlp (_P_WAIT
, sh
, sh
, NULL
);
863 write (1, "Can't execute subshell", 22);
864 #else /* not WINDOWSNT */
866 write (1, "Can't execute subshell", 22);
868 #endif /* not WINDOWSNT */
869 #endif /* not MSDOS */
872 /* Do this now if we did not do it before. */
873 #if !defined (MSDOS) || __DJGPP__ == 1
874 save_signal_handlers (saved_handlers
);
875 synch_process_alive
= 1;
879 wait_for_termination (pid
);
881 restore_signal_handlers (saved_handlers
);
882 synch_process_alive
= 0;
885 #endif /* !macintosh */
888 save_signal_handlers (saved_handlers
)
889 struct save_signal
*saved_handlers
;
891 while (saved_handlers
->code
)
893 saved_handlers
->handler
894 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers
->code
, SIG_IGN
);
900 restore_signal_handlers (saved_handlers
)
901 struct save_signal
*saved_handlers
;
903 while (saved_handlers
->code
)
905 signal (saved_handlers
->code
, saved_handlers
->handler
);
919 old_fcntl_flags
= fcntl (fd
, F_GETFL
, 0) & ~FASYNC
;
920 fcntl (fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
922 interrupts_deferred
= 0;
931 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
936 if (read_socket_hook
)
940 sigunblock (sigmask (SIGWINCH
));
942 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
944 interrupts_deferred
= 0;
950 if (read_socket_hook
)
954 sigblock (sigmask (SIGWINCH
));
956 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
);
957 interrupts_deferred
= 1;
960 #else /* no FASYNC */
961 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
968 if (read_socket_hook
)
971 ioctl (input_fd
, FIOASYNC
, &on
);
972 interrupts_deferred
= 0;
980 if (read_socket_hook
)
983 ioctl (input_fd
, FIOASYNC
, &off
);
984 interrupts_deferred
= 1;
987 #else /* not FASYNC, not STRIDE */
999 if (read_socket_hook
)
1003 sigaddset (&st
, SIGIO
);
1004 ioctl (input_fd
, FIOASYNC
, &on
);
1005 interrupts_deferred
= 0;
1006 sigprocmask (SIG_UNBLOCK
, &st
, (sigset_t
*)0);
1014 if (read_socket_hook
)
1017 ioctl (input_fd
, FIOASYNC
, &off
);
1018 interrupts_deferred
= 1;
1021 #else /* ! _CX_UX */
1026 if (read_socket_hook
)
1029 croak ("request_sigio");
1035 if (read_socket_hook
)
1038 croak ("unrequest_sigio");
1044 #endif /* F_SETFL */
1046 /* Saving and restoring the process group of Emacs's terminal. */
1050 /* The process group of which Emacs was a member when it initially
1053 If Emacs was in its own process group (i.e. inherited_pgroup ==
1054 getpid ()), then we know we're running under a shell with job
1055 control (Emacs would never be run as part of a pipeline).
1058 If Emacs was not in its own process group, then we know we're
1059 running under a shell (or a caller) that doesn't know how to
1060 separate itself from Emacs (like sh). Emacs must be in its own
1061 process group in order to receive SIGIO correctly. In this
1062 situation, we put ourselves in our own pgroup, forcibly set the
1063 tty's pgroup to our pgroup, and make sure to restore and reinstate
1064 the tty's pgroup just like any other terminal setting. If
1065 inherited_group was not the tty's pgroup, then we'll get a
1066 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1067 it goes foreground in the future, which is what should happen. */
1068 int inherited_pgroup
;
1070 /* Split off the foreground process group to Emacs alone.
1071 When we are in the foreground, but not started in our own process
1072 group, redirect the TTY to point to our own process group. We need
1073 to be in our own process group to receive SIGIO properly. */
1075 narrow_foreground_group ()
1079 setpgrp (0, inherited_pgroup
);
1080 if (inherited_pgroup
!= me
)
1081 EMACS_SET_TTY_PGRP (input_fd
, &me
);
1085 /* Set the tty to our original foreground group. */
1087 widen_foreground_group ()
1089 if (inherited_pgroup
!= getpid ())
1090 EMACS_SET_TTY_PGRP (input_fd
, &inherited_pgroup
);
1091 setpgrp (0, inherited_pgroup
);
1094 #endif /* BSD_PGRPS */
1096 /* Getting and setting emacs_tty structures. */
1098 /* Set *TC to the parameters associated with the terminal FD.
1099 Return zero if all's well, or -1 if we ran into an error we
1100 couldn't deal with. */
1102 emacs_get_tty (fd
, settings
)
1104 struct emacs_tty
*settings
;
1106 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1108 /* We have those nifty POSIX tcmumbleattr functions. */
1109 bzero (&settings
->main
, sizeof (settings
->main
));
1110 if (tcgetattr (fd
, &settings
->main
) < 0)
1115 /* The SYSV-style interface? */
1116 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
1121 /* Vehemently Monstrous System? :-) */
1122 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
1123 &settings
->main
.class, 12, 0, 0, 0, 0)
1129 /* I give up - I hope you have the BSD ioctls. */
1130 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
1132 #endif /* not DOS_NT */
1137 /* Suivant - Do we have to get struct ltchars data? */
1139 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
1143 /* How about a struct tchars and a wordful of lmode bits? */
1145 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
1146 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
1150 /* We have survived the tempest. */
1155 /* Set the parameters of the tty on FD according to the contents of
1156 *SETTINGS. If FLUSHP is non-zero, we discard input.
1157 Return 0 if all went well, and -1 if anything failed. */
1160 emacs_set_tty (fd
, settings
, flushp
)
1162 struct emacs_tty
*settings
;
1165 /* Set the primary parameters - baud rate, character size, etcetera. */
1168 /* We have those nifty POSIX tcmumbleattr functions.
1169 William J. Smith <wjs@wiis.wang.com> writes:
1170 "POSIX 1003.1 defines tcsetattr to return success if it was
1171 able to perform any of the requested actions, even if some
1172 of the requested actions could not be performed.
1173 We must read settings back to ensure tty setup properly.
1174 AIX requires this to keep tty from hanging occasionally." */
1175 /* This make sure that we don't loop indefinitely in here. */
1176 for (i
= 0 ; i
< 10 ; i
++)
1177 if (tcsetattr (fd
, flushp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
1188 bzero (&new, sizeof (new));
1189 /* Get the current settings, and see if they're what we asked for. */
1190 tcgetattr (fd
, &new);
1191 /* We cannot use memcmp on the whole structure here because under
1192 * aix386 the termios structure has some reserved field that may
1195 if ( new.c_iflag
== settings
->main
.c_iflag
1196 && new.c_oflag
== settings
->main
.c_oflag
1197 && new.c_cflag
== settings
->main
.c_cflag
1198 && new.c_lflag
== settings
->main
.c_lflag
1199 && memcmp (new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
1207 /* The SYSV-style interface? */
1208 if (ioctl (fd
, flushp
? TCSETAF
: TCSETAW
, &settings
->main
) < 0)
1213 /* Vehemently Monstrous System? :-) */
1214 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
1215 &settings
->main
.class, 12, 0, 0, 0, 0)
1221 /* I give up - I hope you have the BSD ioctls. */
1222 if (ioctl (fd
, (flushp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
1224 #endif /* not DOS_NT */
1230 /* Suivant - Do we have to get struct ltchars data? */
1232 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
1236 /* How about a struct tchars and a wordful of lmode bits? */
1238 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
1239 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
1243 /* We have survived the tempest. */
1248 /* The initial tty mode bits */
1249 struct emacs_tty old_tty
;
1251 /* 1 if we have been through init_sys_modes. */
1254 /* 1 if outer tty status has been recorded. */
1258 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1263 #ifndef F_SETOWN_BUG
1265 int old_fcntl_owner
;
1266 #endif /* F_SETOWN */
1267 #endif /* F_SETOWN_BUG */
1269 /* This may also be defined in stdio,
1270 but if so, this does no harm,
1271 and using the same name avoids wasting the other one's space. */
1274 extern char *_sobuf
;
1276 #if defined (USG) || defined (DGUX)
1277 unsigned char _sobuf
[BUFSIZ
+8];
1279 char _sobuf
[BUFSIZ
];
1284 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
1287 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
1293 struct emacs_tty tty
;
1296 /* cus-start.el complains if delete-exited-processes is not defined */
1297 #ifndef subprocesses
1298 DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes
,
1299 doc
: /* *Non-nil means delete processes immediately when they exit.
1300 nil means don't delete them until `list-processes' is run. */);
1301 delete_exited_processes
= 0;
1303 #endif /* not macintosh */
1307 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
1308 extern int (*interrupt_signal
) ();
1312 Vtty_erase_char
= Qnil
;
1319 input_ef
= get_kbd_event_flag ();
1320 /* LIB$GET_EF (&input_ef); */
1321 SYS$
CLREF (input_ef
);
1322 waiting_for_ast
= 0;
1324 timer_ef
= get_timer_event_flag ();
1325 /* LIB$GET_EF (&timer_ef); */
1326 SYS$
CLREF (timer_ef
);
1330 LIB$
GET_EF (&process_ef
);
1331 SYS$
CLREF (process_ef
);
1333 if (input_ef
/ 32 != process_ef
/ 32)
1334 croak ("Input and process event flags in different clusters.");
1336 if (input_ef
/ 32 != timer_ef
/ 32)
1337 croak ("Input and timer event flags in different clusters.");
1339 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1340 ((unsigned) 1 << (process_ef
% 32));
1342 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1343 ((unsigned) 1 << (timer_ef
% 32));
1345 sys_access_reinit ();
1347 #endif /* not VMS */
1350 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1351 narrow_foreground_group ();
1354 #ifdef HAVE_WINDOW_SYSTEM
1355 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1356 needs the initialization code below. */
1357 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1360 EMACS_GET_TTY (input_fd
, &old_tty
);
1366 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1367 XSETINT (Vtty_erase_char
, old_tty
.main
.c_cc
[VERASE
]);
1370 /* This allows meta to be sent on 8th bit. */
1371 tty
.main
.c_iflag
&= ~INPCK
; /* don't check input for parity */
1373 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1374 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1375 #ifdef INLCR /* I'm just being cautious,
1376 since I can't check how widespread INLCR is--rms. */
1377 tty
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
1380 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1382 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1383 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1385 tty
.main
.c_lflag
&= ~IEXTEN
; /* Disable other editing characters. */
1387 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1390 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1392 tty
.main
.c_iflag
&= ~IXANY
;
1396 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1397 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1399 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1403 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1404 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1407 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1408 /* Set up C-g for both SIGQUIT and SIGINT.
1409 We don't know which we will get, but we handle both alike
1410 so which one it really gives us does not matter. */
1411 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1412 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1413 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1415 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1419 #if defined (mips) || defined (HAVE_TCATTR)
1421 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1424 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1425 #endif /* V_DSUSP */
1426 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1427 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1430 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1433 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1434 #endif /* VREPRINT */
1436 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1437 #endif /* VWERASE */
1439 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1440 #endif /* VDISCARD */
1445 tty
.main
.c_cc
[VSTART
] = '\021';
1448 tty
.main
.c_cc
[VSTOP
] = '\023';
1454 tty
.main
.c_cc
[VSTART
] = CDISABLE
;
1457 tty
.main
.c_cc
[VSTOP
] = CDISABLE
;
1460 #endif /* mips or HAVE_TCATTR */
1462 #ifdef SET_LINE_DISCIPLINE
1463 /* Need to explicitly request TERMIODISC line discipline or
1464 Ultrix's termios does not work correctly. */
1465 tty
.main
.c_line
= SET_LINE_DISCIPLINE
;
1469 /* AIX enhanced edit loses NULs, so disable it. */
1470 tty
.main
.c_line
= 0;
1471 tty
.main
.c_iflag
&= ~ASCEDIT
;
1473 tty
.main
.c_cc
[VSTRT
] = 255;
1474 tty
.main
.c_cc
[VSTOP
] = 255;
1475 tty
.main
.c_cc
[VSUSP
] = 255;
1476 tty
.main
.c_cc
[VDSUSP
] = 255;
1477 #endif /* IBMR2AIX */
1481 tty
.main
.c_cc
[VSTART
] = '\021';
1484 tty
.main
.c_cc
[VSTOP
] = '\023';
1487 /* Also, PTY overloads NUL and BREAK.
1488 don't ignore break, but don't signal either, so it looks like NUL.
1489 This really serves a purpose only if running in an XTERM window
1490 or via TELNET or the like, but does no harm elsewhere. */
1491 tty
.main
.c_iflag
&= ~IGNBRK
;
1492 tty
.main
.c_iflag
&= ~BRKINT
;
1494 #else /* if not HAVE_TERMIO */
1496 tty
.main
.tt_char
|= TT$M_NOECHO
;
1498 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1500 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1502 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1503 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1504 #else /* not VMS (BSD, that is) */
1506 XSETINT (Vtty_erase_char
, tty
.main
.sg_erase
);
1507 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1509 tty
.main
.sg_flags
|= ANYP
;
1510 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1511 #endif /* not DOS_NT */
1512 #endif /* not VMS (BSD, that is) */
1513 #endif /* not HAVE_TERMIO */
1515 /* If going to use CBREAK mode, we must request C-g to interrupt
1516 and turn off start and stop chars, etc. If not going to use
1517 CBREAK mode, do this anyway so as to turn off local flow
1518 control for user coming over network on 4.2; in this case,
1519 only t_stopc and t_startc really matter. */
1522 /* Note: if not using CBREAK mode, it makes no difference how we
1524 tty
.tchars
= new_tchars
;
1525 tty
.tchars
.t_intrc
= quit_char
;
1528 tty
.tchars
.t_startc
= '\021';
1529 tty
.tchars
.t_stopc
= '\023';
1532 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1534 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1535 anything, and leaving it in breaks the meta key. Go figure. */
1536 tty
.lmode
&= ~LLITOUT
;
1543 #endif /* HAVE_TCHARS */
1544 #endif /* not HAVE_TERMIO */
1547 tty
.ltchars
= new_ltchars
;
1548 #endif /* HAVE_LTCHARS */
1549 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1551 internal_terminal_init ();
1555 EMACS_SET_TTY (input_fd
, &tty
, 0);
1557 /* This code added to insure that, if flow-control is not to be used,
1558 we have an unlocked terminal at the start. */
1561 if (!flow_control
) ioctl (input_fd
, TCXONC
, 1);
1565 if (!flow_control
) ioctl (input_fd
, TIOCSTART
, 0);
1569 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1571 if (!flow_control
) tcflow (input_fd
, TCOON
);
1579 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1580 to be only LF. This is the way that is done. */
1583 if (ioctl (1, HFTGETID
, &tty
) != -1)
1584 write (1, "\033[20l", 5);
1590 /* Appears to do nothing when in PASTHRU mode.
1591 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1592 interrupt_signal, oob_chars, 0, 0, 0, 0);
1594 queue_kbd_input (0);
1599 #ifndef F_SETOWN_BUG
1600 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1602 && ! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1604 old_fcntl_owner
= fcntl (input_fd
, F_GETOWN
, 0);
1605 fcntl (input_fd
, F_SETOWN
, getpid ());
1606 init_sigio (input_fd
);
1608 #endif /* F_GETOWN */
1609 #endif /* F_SETOWN_BUG */
1610 #endif /* F_SETFL */
1613 if (interrupt_input
)
1614 init_sigio (input_fd
);
1617 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1621 /* This symbol is defined on recent USG systems.
1622 Someone says without this call USG won't really buffer the file
1623 even with a call to setbuf. */
1624 setvbuf (stdout
, (char *) _sobuf
, _IOFBF
, sizeof _sobuf
);
1626 setbuf (stdout
, (char *) _sobuf
);
1628 #ifdef HAVE_WINDOW_SYSTEM
1629 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1630 needs the initialization code below. */
1631 if (EQ (Vwindow_system
, Qnil
)
1633 /* When running in tty mode on NT/Win95, we have a read_socket
1634 hook, but still need the rest of the initialization code below. */
1635 && (! read_socket_hook
)
1639 set_terminal_modes ();
1642 && FRAMEP (Vterminal_frame
)
1643 && FRAME_TERMCAP_P (XFRAME (Vterminal_frame
)))
1644 init_frame_faces (XFRAME (Vterminal_frame
));
1646 if (term_initted
&& no_redraw_on_reenter
)
1648 if (display_completed
)
1649 direct_output_forward_char (0);
1654 if (FRAMEP (Vterminal_frame
))
1655 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1661 /* Return nonzero if safe to use tabs in output.
1662 At the time this is called, init_sys_modes has not been done yet. */
1667 struct emacs_tty tty
;
1669 EMACS_GET_TTY (input_fd
, &tty
);
1670 return EMACS_TTY_TABS_OK (&tty
);
1673 /* Get terminal size from system.
1674 Store number of lines into *HEIGHTP and width into *WIDTHP.
1675 We store 0 if there's no valid information. */
1678 get_frame_size (widthp
, heightp
)
1679 int *widthp
, *heightp
;
1685 struct winsize size
;
1687 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1688 *widthp
= *heightp
= 0;
1691 *widthp
= size
.ws_col
;
1692 *heightp
= size
.ws_row
;
1698 /* SunOS - style. */
1699 struct ttysize size
;
1701 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1702 *widthp
= *heightp
= 0;
1705 *widthp
= size
.ts_cols
;
1706 *heightp
= size
.ts_lines
;
1712 struct sensemode tty
;
1714 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1715 &tty
.class, 12, 0, 0, 0, 0);
1716 *widthp
= tty
.scr_wid
;
1717 *heightp
= tty
.scr_len
;
1721 *widthp
= ScreenCols ();
1722 *heightp
= ScreenRows ();
1723 #else /* system doesn't know size */
1728 #endif /* not VMS */
1729 #endif /* not SunOS-style */
1730 #endif /* not BSD-style */
1733 /* Set the logical window size associated with descriptor FD
1734 to HEIGHT and WIDTH. This is used mainly with ptys. */
1737 set_window_size (fd
, height
, width
)
1738 int fd
, height
, width
;
1743 struct winsize size
;
1744 size
.ws_row
= height
;
1745 size
.ws_col
= width
;
1747 if (ioctl (fd
, TIOCSWINSZ
, &size
) == -1)
1748 return 0; /* error */
1755 /* SunOS - style. */
1756 struct ttysize size
;
1757 size
.ts_lines
= height
;
1758 size
.ts_cols
= width
;
1760 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1766 #endif /* not SunOS-style */
1767 #endif /* not BSD-style */
1771 /* Prepare the terminal for exiting Emacs; move the cursor to the
1772 bottom of the frame, turn off interrupt-driven I/O, etc. */
1785 #ifdef HAVE_WINDOW_SYSTEM
1786 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1787 needs the clean-up code below. */
1788 if (!EQ (Vwindow_system
, Qnil
)
1790 /* When running in tty mode on NT/Win95, we have a read_socket
1791 hook, but still need the rest of the clean-up code below. */
1797 sf
= SELECTED_FRAME ();
1798 cursor_to (FRAME_HEIGHT (sf
) - 1, 0);
1799 clear_end_of_line (FRAME_WIDTH (sf
));
1800 /* clear_end_of_line may move the cursor */
1801 cursor_to (FRAME_HEIGHT (sf
) - 1, 0);
1802 #if defined (IBMR2AIX) && defined (AIXHFT)
1804 /* HFT devices normally use ^J as a LF/CR. We forced it to
1805 do the LF only. Now, we need to reset it. */
1808 if (ioctl (1, HFTGETID
, &tty
) != -1)
1809 write (1, "\033[20h", 5);
1813 reset_terminal_modes ();
1817 /* Avoid possible loss of output when changing terminal modes. */
1818 fsync (fileno (stdout
));
1823 #ifndef F_SETOWN_BUG
1824 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1825 if (interrupt_input
)
1828 fcntl (input_fd
, F_SETOWN
, old_fcntl_owner
);
1830 #endif /* F_SETOWN */
1831 #endif /* F_SETOWN_BUG */
1833 fcntl (input_fd
, F_SETFL
, fcntl (input_fd
, F_GETFL
, 0) & ~O_NDELAY
);
1835 #endif /* F_SETFL */
1837 if (interrupt_input
)
1842 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1845 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1849 #ifdef SET_LINE_DISCIPLINE
1850 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1851 A different old line discipline is therefore not restored, yet.
1852 Restore the old line discipline by hand. */
1853 ioctl (0, TIOCSETD
, &old_tty
.main
.c_line
);
1861 widen_foreground_group ();
1867 /* Set up the proper status flags for use of a pty. */
1873 /* I'm told that TOICREMOTE does not mean control chars
1874 "can't be sent" but rather that they don't have
1875 input-editing or signaling effects.
1876 That should be good, because we have other ways
1877 to do those things in Emacs.
1878 However, telnet mode seems not to work on 4.2.
1879 So TIOCREMOTE is turned off now. */
1881 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1882 will hang. In particular, the "timeout" feature (which
1883 causes a read to return if there is no data available)
1884 does this. Also it is known that telnet mode will hang
1885 in such a way that Emacs must be stopped (perhaps this
1886 is the same problem).
1888 If TIOCREMOTE is turned off, then there is a bug in
1889 hp-ux which sometimes loses data. Apparently the
1890 code which blocks the master process when the internal
1891 buffer fills up does not work. Other than this,
1892 though, everything else seems to work fine.
1894 Since the latter lossage is more benign, we may as well
1895 lose that way. -- cph */
1897 #if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
1900 ioctl (fd
, FIONBIO
, &on
);
1905 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1906 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1907 /* cause EMACS not to die when it should, i.e., when its own controlling */
1908 /* tty goes away. I've complained to the AIX developers, and they may */
1909 /* change this behavior, but I'm not going to hold my breath. */
1910 signal (SIGHUP
, SIG_IGN
);
1913 #endif /* HAVE_PTYS */
1917 /* Assigning an input channel is done at the start of Emacs execution.
1918 This is called each time Emacs is resumed, also, but does nothing
1919 because input_chain is no longer zero. */
1928 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1934 /* Deassigning the input channel is done before exiting. */
1939 return SYS$
DASSGN (input_fd
);
1944 /* Request reading one character into the keyboard buffer.
1945 This is done as soon as the buffer becomes empty. */
1951 extern kbd_input_ast ();
1953 waiting_for_ast
= 0;
1955 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1956 &input_iosb
, kbd_input_ast
, 1,
1957 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1962 /* Ast routine that is called when keyboard input comes in
1963 in accord with the SYS$QIO above. */
1968 register int c
= -1;
1969 int old_errno
= errno
;
1970 extern EMACS_TIME
*input_available_clear_time
;
1972 if (waiting_for_ast
)
1973 SYS$
SETEF (input_ef
);
1974 waiting_for_ast
= 0;
1977 if (input_count
== 25)
1979 printf ("Ast # %d,", input_count
);
1980 printf (" iosb = %x, %x, %x, %x",
1981 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1984 if (input_iosb
.offset
)
1988 printf (", char = 0%o", c
);
2000 struct input_event e
;
2001 e
.kind
= ascii_keystroke
;
2002 XSETINT (e
.code
, c
);
2003 e
.frame_or_window
= selected_frame
;
2004 kbd_buffer_store_event (&e
);
2006 if (input_available_clear_time
)
2007 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
2011 /* Wait until there is something in kbd_buffer. */
2014 wait_for_kbd_input ()
2016 extern int have_process_input
, process_exited
;
2018 /* If already something, avoid doing system calls. */
2019 if (detect_input_pending ())
2023 /* Clear a flag, and tell ast routine above to set it. */
2024 SYS$
CLREF (input_ef
);
2025 waiting_for_ast
= 1;
2026 /* Check for timing error: ast happened while we were doing that. */
2027 if (!detect_input_pending ())
2029 /* No timing error: wait for flag to be set. */
2030 set_waiting_for_input (0);
2031 SYS$
WFLOR (input_ef
, input_eflist
);
2032 clear_waiting_for_input ();
2033 if (!detect_input_pending ())
2034 /* Check for subprocess input availability */
2036 int dsp
= have_process_input
|| process_exited
;
2038 SYS$
CLREF (process_ef
);
2039 if (have_process_input
)
2040 process_command_input ();
2045 update_mode_lines
++;
2046 prepare_menu_bars ();
2047 redisplay_preserve_echo_area (18);
2051 waiting_for_ast
= 0;
2054 /* Get rid of any pending QIO, when we are about to suspend
2055 or when we want to throw away pending input.
2056 We wait for a positive sign that the AST routine has run
2057 and therefore there is no I/O request queued when we return.
2058 SYS$SETAST is used to avoid a timing error. */
2064 printf ("At end_kbd_input.\n");
2068 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2070 SYS$
CANCEL (input_fd
);
2075 /* Clear a flag, and tell ast routine above to set it. */
2076 SYS$
CLREF (input_ef
);
2077 waiting_for_ast
= 1;
2079 SYS$
CANCEL (input_fd
);
2081 SYS$
WAITFR (input_ef
);
2082 waiting_for_ast
= 0;
2085 /* Wait for either input available or time interval expiry. */
2088 input_wait_timeout (timeval
)
2089 int timeval
; /* Time to wait, in seconds */
2092 static int zero
= 0;
2093 static int large
= -10000000;
2095 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2097 /* If already something, avoid doing system calls. */
2098 if (detect_input_pending ())
2102 /* Clear a flag, and tell ast routine above to set it. */
2103 SYS$
CLREF (input_ef
);
2104 waiting_for_ast
= 1;
2105 /* Check for timing error: ast happened while we were doing that. */
2106 if (!detect_input_pending ())
2108 /* No timing error: wait for flag to be set. */
2110 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2111 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
2113 waiting_for_ast
= 0;
2116 /* The standard `sleep' routine works some other way
2117 and it stops working if you have ever quit out of it.
2118 This one continues to work. */
2124 static int zero
= 0;
2125 static int large
= -10000000;
2127 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
2130 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
2131 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
2149 croak ("request sigio");
2155 croak ("unrequest sigio");
2160 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2165 #ifndef SYSTEM_MALLOC
2172 /* Some systems that cannot dump also cannot implement these. */
2175 * Return the address of the start of the text segment prior to
2176 * doing an unexec. After unexec the return value is undefined.
2177 * See crt0.c for further explanation and _start.
2181 #if !(defined (__NetBSD__) && defined (__ELF__))
2182 #ifndef HAVE_TEXT_START
2187 return ((char *) TEXT_START
);
2191 return ((char *) csrt
);
2192 #else /* not GOULD */
2193 extern int _start ();
2194 return ((char *) _start
);
2196 #endif /* TEXT_START */
2198 #endif /* not HAVE_TEXT_START */
2202 * Return the address of the start of the data segment prior to
2203 * doing an unexec. After unexec the return value is undefined.
2204 * See crt0.c for further information and definition of data_start.
2206 * Apparently, on BSD systems this is etext at startup. On
2207 * USG systems (swapping) this is highly mmu dependent and
2208 * is also dependent on whether or not the program is running
2209 * with shared text. Generally there is a (possibly large)
2210 * gap between end of text and start of data with shared text.
2212 * On Uniplus+ systems with shared text, data starts at a
2213 * fixed address. Each port (from a given oem) is generally
2214 * different, and the specific value of the start of data can
2215 * be obtained via the UniPlus+ specific "uvar" system call,
2216 * however the method outlined in crt0.c seems to be more portable.
2218 * Probably what will have to happen when a USG unexec is available,
2219 * at least on UniPlus, is temacs will have to be made unshared so
2220 * that text and data are contiguous. Then once loadup is complete,
2221 * unexec will produce a shared executable where the data can be
2222 * at the normal shared text boundary and the startofdata variable
2223 * will be patched by unexec to the correct value.
2231 return ((char *) DATA_START
);
2233 #ifdef ORDINARY_LINK
2235 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2236 * data_start isn't defined. We take the address of environ, which
2237 * is known to live at or near the start of the system crt0.c, and
2238 * we don't sweat the handful of bytes that might lose.
2240 extern char **environ
;
2242 return ((char *) &environ
);
2244 extern int data_start
;
2245 return ((char *) &data_start
);
2246 #endif /* ORDINARY_LINK */
2247 #endif /* DATA_START */
2249 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2252 /* Some systems that cannot dump also cannot implement these. */
2255 * Return the address of the end of the text segment prior to
2256 * doing an unexec. After unexec the return value is undefined.
2263 return ((char *) TEXT_END
);
2266 return ((char *) &etext
);
2271 * Return the address of the end of the data segment prior to
2272 * doing an unexec. After unexec the return value is undefined.
2279 return ((char *) DATA_END
);
2282 return ((char *) &edata
);
2286 #endif /* not CANNOT_DUMP */
2288 /* init_system_name sets up the string for the Lisp function
2289 system-name to return. */
2295 extern Lisp_Object Vsystem_name
;
2300 #include <sys/socket.h>
2302 #endif /* HAVE_SOCKETS */
2303 #endif /* not VMS */
2304 #endif /* not BSD4_1 */
2307 #ifndef HAVE_H_ERRNO
2310 #endif /* TRY_AGAIN */
2316 Vsystem_name
= build_string (sysname
);
2320 if ((sp
= egetenv ("SYS$NODE")) == 0)
2321 Vsystem_name
= build_string ("vax-vms");
2322 else if ((end
= index (sp
, ':')) == 0)
2323 Vsystem_name
= build_string (sp
);
2325 Vsystem_name
= make_string (sp
, end
- sp
);
2327 #ifndef HAVE_GETHOSTNAME
2330 Vsystem_name
= build_string (uts
.nodename
);
2331 #else /* HAVE_GETHOSTNAME */
2332 unsigned int hostname_size
= 256;
2333 char *hostname
= (char *) alloca (hostname_size
);
2335 /* Try to get the host name; if the buffer is too short, try
2336 again. Apparently, the only indication gethostname gives of
2337 whether the buffer was large enough is the presence or absence
2338 of a '\0' in the string. Eech. */
2341 gethostname (hostname
, hostname_size
- 1);
2342 hostname
[hostname_size
- 1] = '\0';
2344 /* Was the buffer large enough for the '\0'? */
2345 if (strlen (hostname
) < hostname_size
- 1)
2348 hostname_size
<<= 1;
2349 hostname
= (char *) alloca (hostname_size
);
2352 /* Turn the hostname into the official, fully-qualified hostname.
2353 Don't do this if we're going to dump; this can confuse system
2354 libraries on some machines and make the dumped emacs core dump. */
2357 #endif /* not CANNOT_DUMP */
2358 if (! index (hostname
, '.'))
2362 for (count
= 0;; count
++)
2367 hp
= gethostbyname (hostname
);
2369 if (! (hp
== 0 && h_errno
== TRY_AGAIN
))
2374 Fsleep_for (make_number (1), Qnil
);
2378 char *fqdn
= (char *) hp
->h_name
;
2381 if (!index (fqdn
, '.'))
2383 /* We still don't have a fully qualified domain name.
2384 Try to find one in the list of alternate names */
2385 char **alias
= hp
->h_aliases
;
2386 while (*alias
&& !index (*alias
, '.'))
2393 /* Convert the host name to lower case. */
2394 /* Using ctype.h here would introduce a possible locale
2395 dependence that is probably wrong for hostnames. */
2399 if (*p
>= 'A' && *p
<= 'Z')
2406 #endif /* HAVE_SOCKETS */
2407 /* We used to try using getdomainname here,
2408 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2409 getdomainname gets the NIS/YP domain which often is not the same
2410 as in Internet domain name. */
2411 #if 0 /* Turned off because sysinfo is not really likely to return the
2412 correct Internet domain. */
2413 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2414 if (! index (hostname
, '.'))
2416 /* The hostname is not fully qualified. Append the domain name. */
2418 int hostlen
= strlen (hostname
);
2419 int domain_size
= 256;
2423 char *domain
= (char *) alloca (domain_size
+ 1);
2424 char *fqdn
= (char *) alloca (hostlen
+ 1 + domain_size
+ 1);
2425 int sys_domain_size
= sysinfo (SI_SRPC_DOMAIN
, domain
, domain_size
);
2426 if (sys_domain_size
<= 0)
2428 if (domain_size
< sys_domain_size
)
2430 domain_size
= sys_domain_size
;
2433 strcpy (fqdn
, hostname
);
2434 if (domain
[0] == '.')
2435 strcpy (fqdn
+ hostlen
, domain
);
2436 else if (domain
[0] != 0)
2438 fqdn
[hostlen
] = '.';
2439 strcpy (fqdn
+ hostlen
+ 1, domain
);
2445 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2447 Vsystem_name
= build_string (hostname
);
2448 #endif /* HAVE_GETHOSTNAME */
2453 for (p
= XSTRING (Vsystem_name
)->data
; *p
; p
++)
2454 if (*p
== ' ' || *p
== '\t')
2461 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2463 #include "sysselect.h"
2466 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2467 /* Cause explanatory error message at compile time,
2468 since the select emulation is not good enough for X. */
2469 int *x
= &x_windows_lose_if_no_select_system_call
;
2472 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2473 * Only checks read descriptors.
2475 /* How long to wait between checking fds in select */
2476 #define SELECT_PAUSE 1
2479 /* For longjmp'ing back to read_input_waiting. */
2481 jmp_buf read_alarm_throw
;
2483 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2484 The read_socket_hook function sets this to 1 while it is waiting. */
2486 int read_alarm_should_throw
;
2494 #else /* not BSD4_1 */
2495 signal (SIGALRM
, SIG_IGN
);
2496 #endif /* not BSD4_1 */
2497 if (read_alarm_should_throw
)
2498 longjmp (read_alarm_throw
, 1);
2502 /* Only rfds are checked. */
2504 sys_select (nfds
, rfds
, wfds
, efds
, timeout
)
2506 SELECT_TYPE
*rfds
, *wfds
, *efds
;
2507 EMACS_TIME
*timeout
;
2513 extern int proc_buffered_char
[];
2514 #ifndef subprocesses
2515 int process_tick
= 0, update_tick
= 0;
2517 extern int process_tick
, update_tick
;
2521 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2522 /* If we're using X, then the native select will work; we only need the
2523 emulation for non-X usage. */
2524 if (!NILP (Vwindow_system
))
2525 return select (nfds
, rfds
, wfds
, efds
, timeout
);
2527 timeoutval
= timeout
? EMACS_SECS (*timeout
) : 100000;
2528 local_timeout
= &timeoutval
;
2540 /* If we are looking only for the terminal, with no timeout,
2541 just read it and wait -- that's more efficient. */
2542 if (*local_timeout
== 100000 && process_tick
== update_tick
2543 && FD_ISSET (0, &orfds
))
2546 for (fd
= 1; fd
< nfds
; ++fd
)
2547 if (FD_ISSET (fd
, &orfds
))
2549 if (! detect_input_pending ())
2550 read_input_waiting ();
2556 /* Once a second, till the timer expires, check all the flagged read
2557 * descriptors to see if any input is available. If there is some then
2558 * set the corresponding bit in the return copy of rfds.
2562 register int to_check
, fd
;
2566 for (to_check
= nfds
, fd
= 0; --to_check
>= 0; fd
++)
2568 if (FD_ISSET (fd
, &orfds
))
2570 int avail
= 0, status
= 0;
2573 avail
= detect_input_pending (); /* Special keyboard handler */
2577 status
= ioctl (fd
, FIONREAD
, &avail
);
2578 #else /* no FIONREAD */
2579 /* Hoping it will return -1 if nothing available
2580 or 0 if all 0 chars requested are read. */
2581 if (proc_buffered_char
[fd
] >= 0)
2585 avail
= read (fd
, &buf
, 1);
2587 proc_buffered_char
[fd
] = buf
;
2589 #endif /* no FIONREAD */
2591 if (status
>= 0 && avail
> 0)
2599 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2602 turn_on_atimers (0);
2603 signal (SIGALRM
, select_alarm
);
2605 alarm (SELECT_PAUSE
);
2607 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2608 while (select_alarmed
== 0 && *local_timeout
!= 0
2609 && process_tick
== update_tick
)
2611 /* If we are interested in terminal input,
2612 wait by reading the terminal.
2613 That makes instant wakeup for terminal input at least. */
2614 if (FD_ISSET (0, &orfds
))
2616 read_input_waiting ();
2617 if (detect_input_pending ())
2623 (*local_timeout
) -= SELECT_PAUSE
;
2625 /* Reset the old alarm if there was one. */
2626 turn_on_atimers (1);
2628 if (*local_timeout
== 0) /* Stop on timer being cleared */
2633 #endif /* not WINDOWSNT */
2635 /* Read keyboard input into the standard buffer,
2636 waiting for at least one character. */
2638 /* Make all keyboard buffers much bigger when using a window system. */
2639 #ifdef HAVE_WINDOW_SYSTEM
2640 #define BUFFER_SIZE_FACTOR 16
2642 #define BUFFER_SIZE_FACTOR 1
2646 read_input_waiting ()
2648 struct input_event e
;
2650 extern int quit_char
;
2652 if (read_socket_hook
)
2654 struct input_event buf
[256];
2656 read_alarm_should_throw
= 0;
2657 if (! setjmp (read_alarm_throw
))
2658 nread
= (*read_socket_hook
) (0, buf
, 256, 1);
2662 /* Scan the chars for C-g and store them in kbd_buffer. */
2663 for (i
= 0; i
< nread
; i
++)
2665 kbd_buffer_store_event (&buf
[i
]);
2666 /* Don't look at input that follows a C-g too closely.
2667 This reduces lossage due to autorepeat on C-g. */
2668 if (buf
[i
].kind
== ascii_keystroke
2669 && buf
[i
].code
== quit_char
)
2676 nread
= read (fileno (stdin
), buf
, 1);
2678 /* Scan the chars for C-g and store them in kbd_buffer. */
2679 e
.kind
= ascii_keystroke
;
2680 e
.frame_or_window
= selected_frame
;
2682 for (i
= 0; i
< nread
; i
++)
2684 /* Convert chars > 0177 to meta events if desired.
2685 We do this under the same conditions that read_avail_input does. */
2686 if (read_socket_hook
== 0)
2688 /* If the user says she has a meta key, then believe her. */
2689 if (meta_key
== 1 && (buf
[i
] & 0x80))
2690 e
.modifiers
= meta_modifier
;
2695 XSETINT (e
.code
, buf
[i
]);
2696 kbd_buffer_store_event (&e
);
2697 /* Don't look at input that follows a C-g too closely.
2698 This reduces lossage due to autorepeat on C-g. */
2699 if (buf
[i
] == quit_char
)
2705 #endif /* not HAVE_SELECT */
2706 #endif /* not VMS */
2707 #endif /* not MSDOS */
2716 lmode
= LINTRUP
| lmode
;
2717 ioctl (fd
, TIOCLSET
, &lmode
);
2725 lmode
= ~LINTRUP
& lmode
;
2726 ioctl (0, TIOCLSET
, &lmode
);
2734 interrupts_deferred
= 0;
2742 interrupts_deferred
= 1;
2745 /* still inside #ifdef BSD4_1 */
2748 int sigheld
; /* Mask of held signals */
2754 sigheld
|= sigbit (signum
);
2762 sigheld
|= sigbit (signum
);
2769 sigheld
&= ~sigbit (signum
);
2774 sigfree () /* Free all held signals */
2777 for (i
= 0; i
< NSIG
; i
++)
2778 if (sigheld
& sigbit (i
))
2786 return 1 << (i
- 1);
2788 #endif /* subprocesses */
2791 /* POSIX signals support - DJB */
2792 /* Anyone with POSIX signals should have ANSI C declarations */
2794 #ifdef POSIX_SIGNALS
2796 sigset_t empty_mask
, full_mask
;
2799 sys_signal (int signal_number
, signal_handler_t action
)
2801 struct sigaction new_action
, old_action
;
2802 sigemptyset (&new_action
.sa_mask
);
2803 new_action
.sa_handler
= action
;
2805 /* Emacs mostly works better with restartable system services. If this
2806 * flag exists, we probably want to turn it on here.
2808 new_action
.sa_flags
= SA_RESTART
;
2810 new_action
.sa_flags
= 0;
2812 sigaction (signal_number
, &new_action
, &old_action
);
2813 return (old_action
.sa_handler
);
2817 /* If we're compiling with GCC, we don't need this function, since it
2818 can be written as a macro. */
2820 sys_sigmask (int sig
)
2823 sigemptyset (&mask
);
2824 sigaddset (&mask
, sig
);
2829 /* I'd like to have these guys return pointers to the mask storage in here,
2830 but there'd be trouble if the code was saving multiple masks. I'll be
2831 safe and pass the structure. It normally won't be more than 2 bytes
2835 sys_sigblock (sigset_t new_mask
)
2838 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2843 sys_sigunblock (sigset_t new_mask
)
2846 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2851 sys_sigsetmask (sigset_t new_mask
)
2854 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2858 #endif /* POSIX_SIGNALS */
2860 #if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
2861 static char *my_sys_siglist
[NSIG
];
2865 # define sys_siglist my_sys_siglist
2871 #ifdef POSIX_SIGNALS
2872 sigemptyset (&empty_mask
);
2873 sigfillset (&full_mask
);
2876 #if !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED
2880 sys_siglist
[SIGABRT
] = "Aborted";
2883 sys_siglist
[SIGAIO
] = "LAN I/O interrupt";
2886 sys_siglist
[SIGALRM
] = "Alarm clock";
2889 sys_siglist
[SIGBUS
] = "Bus error";
2892 sys_siglist
[SIGCLD
] = "Child status changed";
2895 sys_siglist
[SIGCHLD
] = "Child status changed";
2898 sys_siglist
[SIGCONT
] = "Continued";
2901 sys_siglist
[SIGDANGER
] = "Swap space dangerously low";
2904 sys_siglist
[SIGDGNOTIFY
] = "Notification message in queue";
2907 sys_siglist
[SIGEMT
] = "Emulation trap";
2910 sys_siglist
[SIGFPE
] = "Arithmetic exception";
2913 sys_siglist
[SIGFREEZE
] = "SIGFREEZE";
2916 sys_siglist
[SIGGRANT
] = "Monitor mode granted";
2919 sys_siglist
[SIGHUP
] = "Hangup";
2922 sys_siglist
[SIGILL
] = "Illegal instruction";
2925 sys_siglist
[SIGINT
] = "Interrupt";
2928 sys_siglist
[SIGIO
] = "I/O possible";
2931 sys_siglist
[SIGIOINT
] = "I/O intervention required";
2934 sys_siglist
[SIGIOT
] = "IOT trap";
2937 sys_siglist
[SIGKILL
] = "Killed";
2940 sys_siglist
[SIGLOST
] = "Resource lost";
2943 sys_siglist
[SIGLWP
] = "SIGLWP";
2946 sys_siglist
[SIGMSG
] = "Monitor mode data available";
2949 sys_siglist
[SIGWIND
] = "SIGPHONE";
2952 sys_siglist
[SIGPIPE
] = "Broken pipe";
2955 sys_siglist
[SIGPOLL
] = "Pollable event occurred";
2958 sys_siglist
[SIGPROF
] = "Profiling timer expired";
2961 sys_siglist
[SIGPTY
] = "PTY I/O interrupt";
2964 sys_siglist
[SIGPWR
] = "Power-fail restart";
2967 sys_siglist
[SIGQUIT
] = "Quit";
2970 sys_siglist
[SIGRETRACT
] = "Need to relinguish monitor mode";
2973 sys_siglist
[SIGSAK
] = "Secure attention";
2976 sys_siglist
[SIGSEGV
] = "Segmentation violation";
2979 sys_siglist
[SIGSOUND
] = "Sound completed";
2982 sys_siglist
[SIGSTOP
] = "Stopped (signal)";
2985 sys_siglist
[SIGSTP
] = "Stopped (user)";
2988 sys_siglist
[SIGSYS
] = "Bad argument to system call";
2991 sys_siglist
[SIGTERM
] = "Terminated";
2994 sys_siglist
[SIGTHAW
] = "SIGTHAW";
2997 sys_siglist
[SIGTRAP
] = "Trace/breakpoint trap";
3000 sys_siglist
[SIGTSTP
] = "Stopped (user)";
3003 sys_siglist
[SIGTTIN
] = "Stopped (tty input)";
3006 sys_siglist
[SIGTTOU
] = "Stopped (tty output)";
3009 sys_siglist
[SIGURG
] = "Urgent I/O condition";
3012 sys_siglist
[SIGUSR1
] = "User defined signal 1";
3015 sys_siglist
[SIGUSR2
] = "User defined signal 2";
3018 sys_siglist
[SIGVTALRM
] = "Virtual timer expired";
3021 sys_siglist
[SIGWAITING
] = "Process's LWPs are blocked";
3024 sys_siglist
[SIGWINCH
] = "Window size changed";
3027 sys_siglist
[SIGWIND
] = "SIGWIND";
3030 sys_siglist
[SIGXCPU
] = "CPU time limit exceeded";
3033 sys_siglist
[SIGXFSZ
] = "File size limit exceeded";
3036 #endif /* !defined HAVE_STRSIGNAL && !defined SYS_SIGLIST_DECLARED */
3045 /* Figure out how many bits the system's random number generator uses.
3046 `random' and `lrand48' are assumed to return 31 usable bits.
3047 BSD `rand' returns a 31 bit value but the low order bits are unusable;
3048 so we'll shift it and treat it like the 15-bit USG `rand'. */
3052 # define RAND_BITS 31
3053 # else /* !HAVE_RANDOM */
3054 # ifdef HAVE_LRAND48
3055 # define RAND_BITS 31
3056 # define random lrand48
3057 # else /* !HAVE_LRAND48 */
3058 # define RAND_BITS 15
3059 # if RAND_MAX == 32767
3060 # define random rand
3061 # else /* RAND_MAX != 32767 */
3062 # if RAND_MAX == 2147483647
3063 # define random() (rand () >> 16)
3064 # else /* RAND_MAX != 2147483647 */
3066 # define random rand
3068 # define random() (rand () >> 16)
3070 # endif /* RAND_MAX != 2147483647 */
3071 # endif /* RAND_MAX != 32767 */
3072 # endif /* !HAVE_LRAND48 */
3073 # endif /* !HAVE_RANDOM */
3074 #endif /* !RAND_BITS */
3081 srandom ((unsigned int)arg
);
3083 # ifdef HAVE_LRAND48
3086 srand ((unsigned int)arg
);
3092 * Build a full Emacs-sized word out of whatever we've got.
3093 * This suffices even for a 64-bit architecture with a 15-bit rand.
3098 long val
= random ();
3099 #if VALBITS > RAND_BITS
3100 val
= (val
<< RAND_BITS
) ^ random ();
3101 #if VALBITS > 2*RAND_BITS
3102 val
= (val
<< RAND_BITS
) ^ random ();
3103 #if VALBITS > 3*RAND_BITS
3104 val
= (val
<< RAND_BITS
) ^ random ();
3105 #if VALBITS > 4*RAND_BITS
3106 val
= (val
<< RAND_BITS
) ^ random ();
3107 #endif /* need at least 5 */
3108 #endif /* need at least 4 */
3109 #endif /* need at least 3 */
3110 #endif /* need at least 2 */
3111 return val
& ((1L << VALBITS
) - 1);
3114 #ifdef WRONG_NAME_INSQUE
3127 /* If any place else asks for the TERM variable,
3128 allow it to be overridden with the EMACS_TERM variable
3129 before attempting to translate the logical name TERM. As a last
3130 resort, ask for VAX C's special idea of the TERM variable. */
3137 static char buf
[256];
3138 static struct dsc$descriptor_s equiv
3139 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
3140 static struct dsc$descriptor_s d_name
3141 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
3144 if (!strcmp (name
, "TERM"))
3146 val
= (char *) getenv ("EMACS_TERM");
3151 d_name
.dsc$w_length
= strlen (name
);
3152 d_name
.dsc$a_pointer
= name
;
3153 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
3155 char *str
= (char *) xmalloc (eqlen
+ 1);
3156 bcopy (buf
, str
, eqlen
);
3158 /* This is a storage leak, but a pain to fix. With luck,
3159 no one will ever notice. */
3162 return (char *) getenv (name
);
3167 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
3168 to force a call on the debugger from within the image. */
3173 LIB$
SIGNAL (SS$_DEBUG
);
3179 #ifdef LINK_CRTL_SHARE
3180 #ifdef SHARABLE_LIB_BUG
3181 /* Variables declared noshare and initialized in sharable libraries
3182 cannot be shared. The VMS linker incorrectly forces you to use a private
3183 version which is uninitialized... If not for this "feature", we
3184 could use the C library definition of sys_nerr and sys_errlist. */
3186 char *sys_errlist
[] =
3190 "no such file or directory",
3192 "interrupted system call",
3194 "no such device or address",
3195 "argument list too long",
3196 "exec format error",
3199 "no more processes",
3200 "not enough memory",
3201 "permission denied",
3203 "block device required",
3204 "mount devices busy",
3206 "cross-device link",
3211 "file table overflow",
3212 "too many open files",
3216 "no space left on device",
3218 "read-only file system",
3224 "vax/vms specific error code nontranslatable error"
3226 #endif /* SHARABLE_LIB_BUG */
3227 #endif /* LINK_CRTL_SHARE */
3230 #ifndef HAVE_STRERROR
3236 extern char *sys_errlist
[];
3237 extern int sys_nerr
;
3239 if (errnum
>= 0 && errnum
< sys_nerr
)
3240 return sys_errlist
[errnum
];
3241 return (char *) "Unknown error";
3243 #endif /* not WINDOWSNT */
3244 #endif /* ! HAVE_STRERROR */
3247 emacs_open (path
, oflag
, mode
)
3251 register int rtnval
;
3254 if (oflag
& O_CREAT
)
3255 return creat (path
, mode
);
3258 while ((rtnval
= open (path
, oflag
, mode
)) == -1
3259 && (errno
== EINTR
));
3268 register int rtnval
;
3270 while ((rtnval
= close (fd
)) == -1
3271 && (errno
== EINTR
))
3274 /* If close is interrupted SunOS 4.1 may or may not have closed the
3275 file descriptor. If it did the second close will fail with
3276 errno = EBADF. That means we have succeeded. */
3277 if (rtnval
== -1 && did_retry
&& errno
== EBADF
)
3284 emacs_read (fildes
, buf
, nbyte
)
3289 register int rtnval
;
3291 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
3292 && (errno
== EINTR
));
3297 emacs_write (fildes
, buf
, nbyte
)
3302 register int rtnval
, bytes_written
;
3308 rtnval
= write (fildes
, buf
, nbyte
);
3315 return (bytes_written
? bytes_written
: -1);
3320 bytes_written
+= rtnval
;
3322 return (bytes_written
);
3327 * All of the following are for USG.
3329 * On USG systems the system calls are INTERRUPTIBLE by signals
3330 * that the user program has elected to catch. Thus the system call
3331 * must be retried in these cases. To handle this without massive
3332 * changes in the source code, we remap the standard system call names
3333 * to names for our own functions in sysdep.c that do the system call
3334 * with retries. Actually, for portability reasons, it is good
3335 * programming practice, as this example shows, to limit all actual
3336 * system calls to a single occurrence in the source. Sure, this
3337 * adds an extra level of function call overhead but it is almost
3338 * always negligible. Fred Fish, Unisoft Systems Inc.
3342 * Warning, this function may not duplicate 4.2 action properly
3343 * under error conditions.
3347 /* In 4.1, param.h fails to define this. */
3348 #define MAXPATHLEN 1024
3357 char *npath
, *spath
;
3358 extern char *getcwd ();
3360 BLOCK_INPUT
; /* getcwd uses malloc */
3361 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
3367 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3368 up to first slash. Should be harmless on other systems. */
3369 while (*npath
&& *npath
!= '/')
3371 strcpy (pathname
, npath
);
3372 free (spath
); /* getcwd uses malloc */
3377 #endif /* HAVE_GETWD */
3380 * Emulate rename using unlink/link. Note that this is
3381 * only partially correct. Also, doesn't enforce restriction
3382 * that files be of same type (regular->regular, dir->dir, etc).
3391 if (access (from
, 0) == 0)
3394 if (link (from
, to
) == 0)
3395 if (unlink (from
) == 0)
3407 /* HPUX curses library references perror, but as far as we know
3408 it won't be called. Anyway this definition will do for now. */
3414 #endif /* not HAVE_PERROR */
3420 * Emulate BSD dup2. First close newd if it already exists.
3421 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3422 * until we are, then close the unsuccessful ones.
3429 register int fd
, ret
;
3434 return fcntl (oldd
, F_DUPFD
, newd
);
3441 ret
= dup2 (old
,new);
3447 #endif /* not HAVE_DUP2 */
3450 * Gettimeofday. Simulate as much as possible. Only accurate
3451 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3452 * Only needed when subprocesses are defined.
3457 #ifndef HAVE_GETTIMEOFDAY
3462 gettimeofday (tp
, tzp
)
3464 struct timezone
*tzp
;
3466 extern long time ();
3468 tp
->tv_sec
= time ((long *)0);
3471 tzp
->tz_minuteswest
= -1;
3478 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3481 * This function will go away as soon as all the stubs fixed. (fnf)
3488 printf ("%s not yet implemented\r\n", badfunc
);
3495 /* Directory routines for systems that don't have them. */
3497 #ifdef SYSV_SYSTEM_DIR
3501 #if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
3505 register DIR *dirp
; /* stream from opendir */
3509 rtnval
= emacs_close (dirp
->dd_fd
);
3511 /* Some systems (like Solaris) allocate the buffer and the DIR all
3512 in one block. Why in the world are we freeing this ourselves
3514 #if ! (defined (sun) && defined (USG5_4))
3515 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
3517 xfree ((char *) dirp
);
3521 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3522 #endif /* SYSV_SYSTEM_DIR */
3524 #ifdef NONSYSTEM_DIR_LIBRARY
3528 char *filename
; /* name of directory */
3530 register DIR *dirp
; /* -> malloc'ed storage */
3531 register int fd
; /* file descriptor for read */
3532 struct stat sbuf
; /* result of fstat */
3534 fd
= emacs_open (filename
, O_RDONLY
, 0);
3539 if (fstat (fd
, &sbuf
) < 0
3540 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
3541 || (dirp
= (DIR *) xmalloc (sizeof (DIR))) == 0)
3545 return 0; /* bad luck today */
3550 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
3557 register DIR *dirp
; /* stream from opendir */
3559 emacs_close (dirp
->dd_fd
);
3560 xfree ((char *) dirp
);
3568 ino_t od_ino
; /* inode */
3569 char od_name
[DIRSIZ
]; /* filename */
3571 #endif /* not VMS */
3573 struct direct dir_static
; /* simulated directory contents */
3578 register DIR *dirp
; /* stream from opendir */
3581 register struct olddir
*dp
; /* -> directory data */
3583 register struct dir$_name
*dp
; /* -> directory data */
3584 register struct dir$_version
*dv
; /* -> version data */
3589 if (dirp
->dd_loc
>= dirp
->dd_size
)
3590 dirp
->dd_loc
= dirp
->dd_size
= 0;
3592 if (dirp
->dd_size
== 0 /* refill buffer */
3593 && (dirp
->dd_size
= emacs_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3597 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3598 dirp
->dd_loc
+= sizeof (struct olddir
);
3600 if (dp
->od_ino
!= 0) /* not deleted entry */
3602 dir_static
.d_ino
= dp
->od_ino
;
3603 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3604 dir_static
.d_name
[DIRSIZ
] = '\0';
3605 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3606 dir_static
.d_reclen
= sizeof (struct direct
)
3608 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3609 return &dir_static
; /* -> simulated structure */
3612 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3613 if (dirp
->dd_loc
== 0)
3614 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3615 : dp
->dir$b_namecount
;
3616 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3617 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3618 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3619 dir_static
.d_reclen
= sizeof (struct direct
)
3621 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3622 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3623 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3624 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3631 /* readdirver is just like readdir except it returns all versions of a file
3632 as separate entries. */
3637 register DIR *dirp
; /* stream from opendir */
3639 register struct dir$_name
*dp
; /* -> directory data */
3640 register struct dir$_version
*dv
; /* -> version data */
3642 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3643 dirp
->dd_loc
= dirp
->dd_size
= 0;
3645 if (dirp
->dd_size
== 0 /* refill buffer */
3646 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3649 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3650 if (dirp
->dd_loc
== 0)
3651 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3652 : dp
->dir$b_namecount
;
3653 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3654 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3655 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3656 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3657 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3658 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3659 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3660 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3666 #endif /* NONSYSTEM_DIR_LIBRARY */
3670 set_file_times (filename
, atime
, mtime
)
3672 EMACS_TIME atime
, mtime
;
3675 struct timeval tv
[2];
3678 return utimes (filename
, tv
);
3679 #else /* not HAVE_UTIMES */
3681 utb
.actime
= EMACS_SECS (atime
);
3682 utb
.modtime
= EMACS_SECS (mtime
);
3683 return utime (filename
, &utb
);
3684 #endif /* not HAVE_UTIMES */
3687 /* mkdir and rmdir functions, for systems which don't have them. */
3691 * Written by Robert Rother, Mariah Corporation, August 1985.
3693 * If you want it, it's yours. All I ask in return is that if you
3694 * figure out how to do this in a Bourne Shell script you send me
3696 * sdcsvax!rmr or rmr@uscd
3698 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3699 * subroutine. 11Mar86; hoptoad!gnu
3701 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3702 * subroutine didn't return EEXIST. It does now.
3708 #ifdef MKDIR_PROTOTYPE
3712 mkdir (dpath
, dmode
)
3717 int cpid
, status
, fd
;
3718 struct stat statbuf
;
3720 if (stat (dpath
, &statbuf
) == 0)
3722 errno
= EEXIST
; /* Stat worked, so it already exists */
3726 /* If stat fails for a reason other than non-existence, return error */
3727 if (errno
!= ENOENT
)
3730 synch_process_alive
= 1;
3731 switch (cpid
= fork ())
3734 case -1: /* Error in fork */
3735 return (-1); /* Errno is set already */
3737 case 0: /* Child process */
3739 * Cheap hack to set mode of new directory. Since this
3740 * child process is going away anyway, we zap its umask.
3741 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3742 * directory. Does anybody care?
3744 status
= umask (0); /* Get current umask */
3745 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3746 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3753 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3754 _exit (-1); /* Can't exec /bin/mkdir */
3756 default: /* Parent process */
3757 wait_for_termination (cpid
);
3760 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3762 errno
= EIO
; /* We don't know why, but */
3763 return -1; /* /bin/mkdir failed */
3768 #endif /* not HAVE_MKDIR */
3775 int cpid
, status
, fd
;
3776 struct stat statbuf
;
3778 if (stat (dpath
, &statbuf
) != 0)
3780 /* Stat just set errno. We don't have to */
3784 synch_process_alive
= 1;
3785 switch (cpid
= fork ())
3788 case -1: /* Error in fork */
3789 return (-1); /* Errno is set already */
3791 case 0: /* Child process */
3792 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
3799 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
3800 _exit (-1); /* Can't exec /bin/rmdir */
3802 default: /* Parent process */
3803 wait_for_termination (cpid
);
3806 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3808 errno
= EIO
; /* We don't know why, but */
3809 return -1; /* /bin/rmdir failed */
3814 #endif /* !HAVE_RMDIR */
3818 /* Functions for VMS */
3820 #include "vms-pwd.h"
3825 /* Return as a string the VMS error string pertaining to STATUS.
3826 Reuses the same static buffer each time it is called. */
3830 int status
; /* VMS status code */
3834 static char buf
[257];
3836 bufadr
[0] = sizeof buf
- 1;
3837 bufadr
[1] = (int) buf
;
3838 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3839 return "untranslatable VMS error status";
3847 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3848 * not work correctly. (It also doesn't work well in version 2.3.)
3853 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3854 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3858 unsigned short s_buflen
;
3859 unsigned short s_code
;
3861 unsigned short *s_retlenadr
;
3865 #define buflen s.s_buflen
3866 #define code s.s_code
3867 #define bufadr s.s_bufadr
3868 #define retlenadr s.s_retlenadr
3870 #define R_OK 4 /* test for read permission */
3871 #define W_OK 2 /* test for write permission */
3872 #define X_OK 1 /* test for execute (search) permission */
3873 #define F_OK 0 /* test for presence of file */
3876 sys_access (path
, mode
)
3880 static char *user
= NULL
;
3883 /* translate possible directory spec into .DIR file name, so brain-dead
3884 * access can treat the directory like a file. */
3885 if (directory_file_name (path
, dir_fn
))
3889 return access (path
, mode
);
3890 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3896 unsigned short int dummy
;
3898 static int constant
= ACL$C_FILE
;
3899 DESCRIPTOR (path_desc
, path
);
3900 DESCRIPTOR (user_desc
, user
);
3904 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3907 acces
|= CHP$M_READ
;
3909 acces
|= CHP$M_WRITE
;
3910 itemlst
[0].buflen
= sizeof (int);
3911 itemlst
[0].code
= CHP$_FLAGS
;
3912 itemlst
[0].bufadr
= (char *) &flags
;
3913 itemlst
[0].retlenadr
= &dummy
;
3914 itemlst
[1].buflen
= sizeof (int);
3915 itemlst
[1].code
= CHP$_ACCESS
;
3916 itemlst
[1].bufadr
= (char *) &acces
;
3917 itemlst
[1].retlenadr
= &dummy
;
3918 itemlst
[2].end
= CHP$_END
;
3919 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3920 return stat
== SS$_NORMAL
? 0 : -1;
3924 #else /* not VMS4_4 */
3927 #define ACE$M_WRITE 2
3928 #define ACE$C_KEYID 1
3930 static unsigned short memid
, grpid
;
3931 static unsigned int uic
;
3933 /* Called from init_sys_modes, so it happens not very often
3934 but at least each time Emacs is loaded. */
3936 sys_access_reinit ()
3942 sys_access (filename
, type
)
3948 int status
, size
, i
, typecode
, acl_controlled
;
3949 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3950 union prvdef prvmask
;
3952 /* Get UIC and GRP values for protection checking. */
3955 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3958 memid
= uic
& 0xFFFF;
3962 if (type
!= 2) /* not checking write access */
3963 return access (filename
, type
);
3965 /* Check write protection. */
3967 #define CHECKPRIV(bit) (prvmask.bit)
3968 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3970 /* Find privilege bits */
3971 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3973 error ("Unable to find privileges: %s", vmserrstr (status
));
3974 if (CHECKPRIV (PRV$V_BYPASS
))
3975 return 0; /* BYPASS enabled */
3977 fab
.fab$b_fac
= FAB$M_GET
;
3978 fab
.fab$l_fna
= filename
;
3979 fab
.fab$b_fns
= strlen (filename
);
3980 fab
.fab$l_xab
= &xab
;
3981 xab
= cc$rms_xabpro
;
3982 xab
.xab$l_aclbuf
= aclbuf
;
3983 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3984 status
= SYS$
OPEN (&fab
, 0, 0);
3987 SYS$
CLOSE (&fab
, 0, 0);
3988 /* Check system access */
3989 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITABLE (XAB$V_SYS
))
3991 /* Check ACL entries, if any */
3993 if (xab
.xab$w_acllen
> 0)
3996 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3997 while (*aclptr
&& aclptr
< aclend
)
3999 size
= (*aclptr
& 0xff) / 4;
4000 typecode
= (*aclptr
>> 8) & 0xff;
4001 if (typecode
== ACE$C_KEYID
)
4002 for (i
= size
- 1; i
> 1; i
--)
4003 if (aclptr
[i
] == uic
)
4006 if (aclptr
[1] & ACE$M_WRITE
)
4007 return 0; /* Write access through ACL */
4009 aclptr
= &aclptr
[size
];
4011 if (acl_controlled
) /* ACL specified, prohibits write access */
4014 /* No ACL entries specified, check normal protection */
4015 if (WRITABLE (XAB$V_WLD
)) /* World writable */
4017 if (WRITABLE (XAB$V_GRP
) &&
4018 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
4019 return 0; /* Group writable */
4020 if (WRITABLE (XAB$V_OWN
) &&
4021 (xab
.xab$l_uic
& 0xFFFF) == memid
)
4022 return 0; /* Owner writable */
4024 return -1; /* Not writable */
4026 #endif /* not VMS4_4 */
4029 static char vtbuf
[NAM$C_MAXRSS
+1];
4031 /* translate a vms file spec to a unix path */
4033 sys_translate_vms (vfile
)
4044 /* leading device or logical name is a root directory */
4045 if (p
= strchr (vfile
, ':'))
4054 if (*p
== '[' || *p
== '<')
4056 while (*++vfile
!= *p
+ 2)
4060 if (vfile
[-1] == *p
)
4083 static char utbuf
[NAM$C_MAXRSS
+1];
4085 /* translate a unix path to a VMS file spec */
4087 sys_translate_unix (ufile
)
4110 if (index (&ufile
[1], '/'))
4117 if (index (&ufile
[1], '/'))
4124 if (strncmp (ufile
, "./", 2) == 0)
4131 ufile
++; /* skip the dot */
4132 if (index (&ufile
[1], '/'))
4137 else if (strncmp (ufile
, "../", 3) == 0)
4145 ufile
+= 2; /* skip the dots */
4146 if (index (&ufile
[1], '/'))
4171 extern char *getcwd ();
4173 #define MAXPATHLEN 1024
4175 ptr
= xmalloc (MAXPATHLEN
);
4176 val
= getcwd (ptr
, MAXPATHLEN
);
4182 strcpy (pathname
, ptr
);
4191 long item_code
= JPI$_OWNER
;
4192 unsigned long parent_id
;
4195 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
4198 vaxc$errno
= status
;
4208 return (getgid () << 16) | getuid ();
4213 sys_read (fildes
, buf
, nbyte
)
4218 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
4223 sys_write (fildes
, buf
, nbyte
)
4228 register int nwrote
, rtnval
= 0;
4230 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
4236 return rtnval
? rtnval
: -1;
4237 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
4238 return rtnval
? rtnval
: -1;
4239 return (rtnval
+ nwrote
);
4244 * VAX/VMS VAX C RTL really loses. It insists that records
4245 * end with a newline (carriage return) character, and if they
4246 * don't it adds one (nice of it isn't it!)
4248 * Thus we do this stupidity below.
4253 sys_write (fildes
, buf
, nbytes
)
4256 unsigned int nbytes
;
4263 fstat (fildes
, &st
);
4269 /* Handle fixed-length files with carriage control. */
4270 if (st
.st_fab_rfm
== FAB$C_FIX
4271 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
4273 len
= st
.st_fab_mrs
;
4274 retval
= write (fildes
, p
, min (len
, nbytes
));
4277 retval
++; /* This skips the implied carriage control */
4281 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4282 while (*e
!= '\n' && e
> p
) e
--;
4283 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
4284 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
4286 retval
= write (fildes
, p
, len
);
4297 /* Create file NEW copying its attributes from file OLD. If
4298 OLD is 0 or does not exist, create based on the value of
4301 /* Protection value the file should ultimately have.
4302 Set by create_copy_attrs, and use by rename_sansversions. */
4303 static unsigned short int fab_final_pro
;
4306 creat_copy_attrs (old
, new)
4309 struct FAB fab
= cc$rms_fab
;
4310 struct XABPRO xabpro
;
4311 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
4312 extern int vms_stmlf_recfm
;
4316 fab
.fab$b_fac
= FAB$M_GET
;
4317 fab
.fab$l_fna
= old
;
4318 fab
.fab$b_fns
= strlen (old
);
4319 fab
.fab$l_xab
= (char *) &xabpro
;
4320 xabpro
= cc$rms_xabpro
;
4321 xabpro
.xab$l_aclbuf
= aclbuf
;
4322 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
4323 /* Call $OPEN to fill in the fab & xabpro fields. */
4324 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4326 SYS$
CLOSE (&fab
, 0, 0);
4327 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
4328 if (xabpro
.xab$w_acllen
> 0)
4330 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
4331 /* If the acl buffer was too short, redo open with longer one.
4332 Wouldn't need to do this if there were some system imposed
4333 limit on the size of an ACL, but I can't find any such. */
4335 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
4336 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
4337 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4338 SYS$
CLOSE (&fab
, 0, 0);
4344 xabpro
.xab$l_aclbuf
= 0;
4349 fab
.fab$l_fna
= new;
4350 fab
.fab$b_fns
= strlen (new);
4354 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
4355 fab
.fab$b_rat
= FAB$M_CR
;
4358 /* Set the file protections such that we will be able to manipulate
4359 this file. Once we are done writing and renaming it, we will set
4360 the protections back. */
4362 fab_final_pro
= xabpro
.xab$w_pro
;
4364 SYS$
SETDFPROT (0, &fab_final_pro
);
4365 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
4367 /* Create the new file with either default attrs or attrs copied
4369 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
4371 SYS$
CLOSE (&fab
, 0, 0);
4372 /* As this is a "replacement" for creat, return a file descriptor
4373 opened for writing. */
4374 return open (new, O_WRONLY
);
4379 #include <varargs.h>
4382 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4387 sys_creat (va_alist
)
4390 va_list list_incrementer
;
4393 int rfd
; /* related file descriptor */
4394 int fd
; /* Our new file descriptor */
4401 extern int vms_stmlf_recfm
;
4404 va_start (list_incrementer
);
4405 name
= va_arg (list_incrementer
, char *);
4406 mode
= va_arg (list_incrementer
, int);
4408 rfd
= va_arg (list_incrementer
, int);
4409 va_end (list_incrementer
);
4412 /* Use information from the related file descriptor to set record
4413 format of the newly created file. */
4414 fstat (rfd
, &st_buf
);
4415 switch (st_buf
.st_fab_rfm
)
4418 strcpy (rfm
, "rfm = fix");
4419 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
4420 strcpy (rat
, "rat = ");
4421 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4423 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4424 strcat (rat
, "ftn");
4425 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4426 strcat (rat
, "prn");
4427 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4428 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4429 strcat (rat
, ", blk");
4431 strcat (rat
, "blk");
4432 return creat (name
, 0, rfm
, rat
, mrs
);
4435 strcpy (rfm
, "rfm = vfc");
4436 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
4437 strcpy (rat
, "rat = ");
4438 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4440 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4441 strcat (rat
, "ftn");
4442 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4443 strcat (rat
, "prn");
4444 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4445 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4446 strcat (rat
, ", blk");
4448 strcat (rat
, "blk");
4449 return creat (name
, 0, rfm
, rat
, fsz
);
4452 strcpy (rfm
, "rfm = stm");
4456 strcpy (rfm
, "rfm = stmcr");
4460 strcpy (rfm
, "rfm = stmlf");
4464 strcpy (rfm
, "rfm = udf");
4468 strcpy (rfm
, "rfm = var");
4471 strcpy (rat
, "rat = ");
4472 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4474 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4475 strcat (rat
, "ftn");
4476 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4477 strcat (rat
, "prn");
4478 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4479 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4480 strcat (rat
, ", blk");
4482 strcat (rat
, "blk");
4486 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
4487 strcpy (rat
, "rat=cr");
4489 /* Until the VAX C RTL fixes the many bugs with modes, always use
4490 mode 0 to get the user's default protection. */
4491 fd
= creat (name
, 0, rfm
, rat
);
4492 if (fd
< 0 && errno
== EEXIST
)
4494 if (unlink (name
) < 0)
4495 report_file_error ("delete", build_string (name
));
4496 fd
= creat (name
, 0, rfm
, rat
);
4502 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4504 sys_fwrite (ptr
, size
, num
, fp
)
4505 register char * ptr
;
4508 register int tot
= num
* size
;
4516 * The VMS C library routine creat actually creates a new version of an
4517 * existing file rather than truncating the old version. There are times
4518 * when this is not the desired behavior, for instance, when writing an
4519 * auto save file (you only want one version), or when you don't have
4520 * write permission in the directory containing the file (but the file
4521 * itself is writable). Hence this routine, which is equivalent to
4522 * "close (creat (fn, 0));" on Unix if fn already exists.
4528 struct FAB xfab
= cc$rms_fab
;
4529 struct RAB xrab
= cc$rms_rab
;
4532 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
4533 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
4534 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
4535 xfab
.fab$l_fna
= fn
;
4536 xfab
.fab$b_fns
= strlen (fn
);
4537 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
4539 xrab
.rab$l_fab
= &xfab
;
4541 /* This gibberish opens the file, positions to the first record, and
4542 deletes all records from there until the end of file. */
4543 if ((SYS$
OPEN (&xfab
) & 01) == 01)
4545 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
4546 (SYS$
FIND (&xrab
) & 01) == 01 &&
4547 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
4558 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4559 SYSPRV or a readable SYSUAF.DAT. */
4565 * Routine to read the VMS User Authorization File and return
4566 * a specific user's record.
4569 static struct UAF retuaf
;
4572 get_uaf_name (uname
)
4579 uaf_fab
= cc$rms_fab
;
4580 uaf_rab
= cc$rms_rab
;
4581 /* initialize fab fields */
4582 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4583 uaf_fab
.fab$b_fns
= 21;
4584 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4585 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4586 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4587 /* initialize rab fields */
4588 uaf_rab
.rab$l_fab
= &uaf_fab
;
4589 /* open the User Authorization File */
4590 status
= SYS$
OPEN (&uaf_fab
);
4594 vaxc$errno
= status
;
4597 status
= SYS$
CONNECT (&uaf_rab
);
4601 vaxc$errno
= status
;
4604 /* read the requested record - index is in uname */
4605 uaf_rab
.rab$l_kbf
= uname
;
4606 uaf_rab
.rab$b_ksz
= strlen (uname
);
4607 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4608 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4609 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4610 status
= SYS$
GET (&uaf_rab
);
4614 vaxc$errno
= status
;
4617 /* close the User Authorization File */
4618 status
= SYS$
DISCONNECT (&uaf_rab
);
4622 vaxc$errno
= status
;
4625 status
= SYS$
CLOSE (&uaf_fab
);
4629 vaxc$errno
= status
;
4643 uaf_fab
= cc$rms_fab
;
4644 uaf_rab
= cc$rms_rab
;
4645 /* initialize fab fields */
4646 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4647 uaf_fab
.fab$b_fns
= 21;
4648 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4649 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4650 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4651 /* initialize rab fields */
4652 uaf_rab
.rab$l_fab
= &uaf_fab
;
4653 /* open the User Authorization File */
4654 status
= SYS$
OPEN (&uaf_fab
);
4658 vaxc$errno
= status
;
4661 status
= SYS$
CONNECT (&uaf_rab
);
4665 vaxc$errno
= status
;
4668 /* read the requested record - index is in uic */
4669 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4670 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4671 uaf_rab
.rab$b_ksz
= sizeof uic
;
4672 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4673 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4674 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4675 status
= SYS$
GET (&uaf_rab
);
4679 vaxc$errno
= status
;
4682 /* close the User Authorization File */
4683 status
= SYS$
DISCONNECT (&uaf_rab
);
4687 vaxc$errno
= status
;
4690 status
= SYS$
CLOSE (&uaf_fab
);
4694 vaxc$errno
= status
;
4700 static struct passwd retpw
;
4708 /* copy these out first because if the username is 32 chars, the next
4709 section will overwrite the first byte of the UIC */
4710 retpw
.pw_uid
= up
->uaf$w_mem
;
4711 retpw
.pw_gid
= up
->uaf$w_grp
;
4713 /* I suppose this is not the best style, to possibly overwrite one
4714 byte beyond the end of the field, but what the heck... */
4715 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4716 while (ptr
[-1] == ' ')
4719 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4721 /* the rest of these are counted ascii strings */
4722 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4723 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4724 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4725 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4726 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4727 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4728 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4729 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4733 #else /* not READ_SYSUAF */
4734 static struct passwd retpw
;
4735 #endif /* not READ_SYSUAF */
4746 unsigned char * full
;
4747 #endif /* READ_SYSUAF */
4752 if ('a' <= *ptr
&& *ptr
<= 'z')
4757 if (!(up
= get_uaf_name (name
)))
4759 return cnv_uaf_pw (up
);
4761 if (strcmp (name
, getenv ("USER")) == 0)
4763 retpw
.pw_uid
= getuid ();
4764 retpw
.pw_gid
= getgid ();
4765 strcpy (retpw
.pw_name
, name
);
4766 if (full
= egetenv ("FULLNAME"))
4767 strcpy (retpw
.pw_gecos
, full
);
4769 *retpw
.pw_gecos
= '\0';
4770 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4771 *retpw
.pw_shell
= '\0';
4776 #endif /* not READ_SYSUAF */
4786 if (!(up
= get_uaf_uic (uid
)))
4788 return cnv_uaf_pw (up
);
4790 if (uid
== sys_getuid ())
4791 return getpwnam (egetenv ("USER"));
4794 #endif /* not READ_SYSUAF */
4797 /* return total address space available to the current process. This is
4798 the sum of the current p0 size, p1 size and free page table entries
4804 unsigned long free_pages
;
4805 unsigned long frep0va
;
4806 unsigned long frep1va
;
4809 item_code
= JPI$_FREPTECNT
;
4810 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4813 vaxc$errno
= status
;
4818 item_code
= JPI$_FREP0VA
;
4819 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4822 vaxc$errno
= status
;
4825 item_code
= JPI$_FREP1VA
;
4826 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4829 vaxc$errno
= status
;
4833 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4837 define_logical_name (varname
, string
)
4841 struct dsc$descriptor_s strdsc
=
4842 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4843 struct dsc$descriptor_s envdsc
=
4844 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4845 struct dsc$descriptor_s lnmdsc
=
4846 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4848 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4852 delete_logical_name (varname
)
4855 struct dsc$descriptor_s envdsc
=
4856 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4857 struct dsc$descriptor_s lnmdsc
=
4858 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4860 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4878 error ("execvp system call not implemented");
4887 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4888 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4889 char from_esn
[NAM$C_MAXRSS
];
4890 char to_esn
[NAM$C_MAXRSS
];
4892 from_fab
.fab$l_fna
= from
;
4893 from_fab
.fab$b_fns
= strlen (from
);
4894 from_fab
.fab$l_nam
= &from_nam
;
4895 from_fab
.fab$l_fop
= FAB$M_NAM
;
4897 from_nam
.nam$l_esa
= from_esn
;
4898 from_nam
.nam$b_ess
= sizeof from_esn
;
4900 to_fab
.fab$l_fna
= to
;
4901 to_fab
.fab$b_fns
= strlen (to
);
4902 to_fab
.fab$l_nam
= &to_nam
;
4903 to_fab
.fab$l_fop
= FAB$M_NAM
;
4905 to_nam
.nam$l_esa
= to_esn
;
4906 to_nam
.nam$b_ess
= sizeof to_esn
;
4908 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4914 if (status
== RMS$_DEV
)
4918 vaxc$errno
= status
;
4923 /* This function renames a file like `rename', but it strips
4924 the version number from the "to" filename, such that the "to" file is
4925 will always be a new version. It also sets the file protection once it is
4926 finished. The protection that we will use is stored in fab_final_pro,
4927 and was set when we did a creat_copy_attrs to create the file that we
4930 We could use the chmod function, but Eunichs uses 3 bits per user category
4931 to describe the protection, and VMS uses 4 (write and delete are separate
4932 bits). To maintain portability, the VMS implementation of `chmod' wires
4933 the W and D bits together. */
4936 static struct fibdef fib
; /* We need this initialized to zero */
4937 char vms_file_written
[NAM$C_MAXRSS
];
4940 rename_sans_version (from
,to
)
4947 struct FAB to_fab
= cc$rms_fab
;
4948 struct NAM to_nam
= cc$rms_nam
;
4949 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4950 struct dsc$descriptor fib_attr
[2]
4951 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4952 char to_esn
[NAM$C_MAXRSS
];
4954 $
DESCRIPTOR (disk
,to_esn
);
4956 to_fab
.fab$l_fna
= to
;
4957 to_fab
.fab$b_fns
= strlen (to
);
4958 to_fab
.fab$l_nam
= &to_nam
;
4959 to_fab
.fab$l_fop
= FAB$M_NAM
;
4961 to_nam
.nam$l_esa
= to_esn
;
4962 to_nam
.nam$b_ess
= sizeof to_esn
;
4964 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4966 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4967 *(to_nam
.nam$l_ver
) = '\0';
4969 stat
= rename (from
, to_esn
);
4973 strcpy (vms_file_written
, to_esn
);
4975 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4976 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4978 /* Now set the file protection to the correct value */
4979 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4981 /* Copy these fields into the fib */
4982 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4983 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4984 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4986 SYS$
CLOSE (&to_fab
, 0, 0);
4988 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4991 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4992 0, 0, 0, &fib_attr
, 0);
4995 stat
= SYS$
DASSGN (chan
);
4998 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
5009 unsigned short fid
[3];
5010 char esa
[NAM$C_MAXRSS
];
5013 fab
.fab$l_fop
= FAB$M_OFP
;
5014 fab
.fab$l_fna
= file
;
5015 fab
.fab$b_fns
= strlen (file
);
5016 fab
.fab$l_nam
= &nam
;
5019 nam
.nam$l_esa
= esa
;
5020 nam
.nam$b_ess
= NAM$C_MAXRSS
;
5022 status
= SYS$
PARSE (&fab
);
5023 if ((status
& 1) == 0)
5026 vaxc$errno
= status
;
5029 status
= SYS$
SEARCH (&fab
);
5030 if ((status
& 1) == 0)
5033 vaxc$errno
= status
;
5037 fid
[0] = nam
.nam$w_fid
[0];
5038 fid
[1] = nam
.nam$w_fid
[1];
5039 fid
[2] = nam
.nam$w_fid
[2];
5041 fab
.fab$l_fna
= new;
5042 fab
.fab$b_fns
= strlen (new);
5044 status
= SYS$
PARSE (&fab
);
5045 if ((status
& 1) == 0)
5048 vaxc$errno
= status
;
5052 nam
.nam$w_fid
[0] = fid
[0];
5053 nam
.nam$w_fid
[1] = fid
[1];
5054 nam
.nam$w_fid
[2] = fid
[2];
5056 nam
.nam$l_esa
= nam
.nam$l_name
;
5057 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
5059 status
= SYS$
ENTER (&fab
);
5060 if ((status
& 1) == 0)
5063 vaxc$errno
= status
;
5074 printf ("%s not yet implemented\r\n", badfunc
);
5082 /* Arrange to return a range centered on zero. */
5083 return rand () - (1 << 30);
5095 /* Called from init_sys_modes. */
5101 /* If we're not on an HFT we shouldn't do any of this. We determine
5102 if we are on an HFT by trying to get an HFT error code. If this
5103 call fails, we're not on an HFT. */
5105 if (ioctl (0, HFQERROR
, &junk
) < 0)
5107 #else /* not IBMR2AIX */
5108 if (ioctl (0, HFQEIO
, 0) < 0)
5110 #endif /* not IBMR2AIX */
5112 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5113 as the rubout key's ASCII code. Here this is changed. The bug is that
5114 there's no way to determine the old mapping, so in reset_sys_modes
5115 we need to assume that the normal map had been present. Of course, this
5116 code also doesn't help if on a terminal emulator which doesn't understand
5120 struct hfkeymap keymap
;
5122 buf
.hf_bufp
= (char *)&keymap
;
5123 buf
.hf_buflen
= sizeof (keymap
);
5124 keymap
.hf_nkeys
= 2;
5125 keymap
.hfkey
[0].hf_kpos
= 15;
5126 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5128 keymap
.hfkey
[0].hf_keyidh
= '<';
5129 #else /* not IBMR2AIX */
5130 keymap
.hfkey
[0].hf_page
= '<';
5131 #endif /* not IBMR2AIX */
5132 keymap
.hfkey
[0].hf_char
= 127;
5133 keymap
.hfkey
[1].hf_kpos
= 15;
5134 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5136 keymap
.hfkey
[1].hf_keyidh
= '<';
5137 #else /* not IBMR2AIX */
5138 keymap
.hfkey
[1].hf_page
= '<';
5139 #endif /* not IBMR2AIX */
5140 keymap
.hfkey
[1].hf_char
= 127;
5141 hftctl (0, HFSKBD
, &buf
);
5143 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
5145 line_ins_del_ok
= char_ins_del_ok
= 0;
5148 /* Reset the rubout key to backspace. */
5154 struct hfkeymap keymap
;
5158 if (ioctl (0, HFQERROR
, &junk
) < 0)
5160 #else /* not IBMR2AIX */
5161 if (ioctl (0, HFQEIO
, 0) < 0)
5163 #endif /* not IBMR2AIX */
5165 buf
.hf_bufp
= (char *)&keymap
;
5166 buf
.hf_buflen
= sizeof (keymap
);
5167 keymap
.hf_nkeys
= 2;
5168 keymap
.hfkey
[0].hf_kpos
= 15;
5169 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
5171 keymap
.hfkey
[0].hf_keyidh
= '<';
5172 #else /* not IBMR2AIX */
5173 keymap
.hfkey
[0].hf_page
= '<';
5174 #endif /* not IBMR2AIX */
5175 keymap
.hfkey
[0].hf_char
= 8;
5176 keymap
.hfkey
[1].hf_kpos
= 15;
5177 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
5179 keymap
.hfkey
[1].hf_keyidh
= '<';
5180 #else /* not IBMR2AIX */
5181 keymap
.hfkey
[1].hf_page
= '<';
5182 #endif /* not IBMR2AIX */
5183 keymap
.hfkey
[1].hf_char
= 8;
5184 hftctl (0, HFSKBD
, &buf
);
5191 /* These are included on Sunos 4.1 when we do not use shared libraries.
5192 X11 libraries may refer to these functions but (we hope) do not
5193 actually call them. */
5213 #endif /* USE_DL_STUBS */
5222 register int length
;
5226 long max_str
= 65535;
5228 while (length
> max_str
) {
5229 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5234 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
5236 while (length
-- > 0)
5238 #endif /* not VMS */
5241 #endif /* no bzero */
5242 #endif /* BSTRING */
5244 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5247 /* Saying `void' requires a declaration, above, where bcopy is used
5248 and that declaration causes pain for systems where bcopy is a macro. */
5249 bcopy (b1
, b2
, length
)
5252 register int length
;
5255 long max_str
= 65535;
5257 while (length
> max_str
) {
5258 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
5264 (void) LIB$
MOVC3 (&length
, b1
, b2
);
5266 while (length
-- > 0)
5268 #endif /* not VMS */
5270 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5275 bcmp (b1
, b2
, length
) /* This could be a macro! */
5278 register int length
;
5281 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
5282 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
5284 return STR$
COMPARE (&src1
, &src2
);
5286 while (length
-- > 0)
5291 #endif /* not VMS */
5293 #endif /* no bcmp */
5294 #endif /* not BSTRING */
5296 #ifndef HAVE_STRSIGNAL
5303 if (0 <= code
&& code
< NSIG
)
5306 signame
= sys_errlist
[code
];
5308 /* Cast to suppress warning if the table has const char *. */
5309 signame
= (char *) sys_siglist
[code
];
5315 #endif /* HAVE_STRSIGNAL */