1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include "blockinput.h"
29 #define min(x,y) ((x) > (y) ? (y) : (x))
31 /* In this file, open, read and write refer to the system calls,
32 not our sugared interfaces sys_open, sys_read and sys_write.
33 Contrariwise, for systems where we use the system calls directly,
34 define sys_read, etc. here as aliases for them. */
37 #define sys_write write
38 #endif /* `read' is not a macro */
44 #define sys_close close
51 #else /* `open' is a macro */
53 #endif /* `open' is a macro */
55 /* Does anyone other than VMS need this? */
57 #define sys_fwrite fwrite
63 #include <sys/types.h>
69 extern char *sys_errlist
[];
92 #define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */
96 #ifdef BSD /* this is done this way to avoid defined (BSD) || defined (USG)
97 because the vms compiler doesn't grok `defined' */
105 #endif /* not 4.1 bsd */
107 /* Get DGUX definition for FASYNC - DJB */
109 #include <sys/file.h>
112 #include <sys/ioctl.h>
119 #include <sys/wait.h>
123 #ifdef BROKEN_TIOCGWINSZ
128 #include <sys/utsname.h>
130 #ifndef MEMORY_IN_STRING_H
135 #include <sys/sioctl.h>
138 #include <sys/stream.h>
139 #include <sys/ptem.h>
141 #endif /* TIOCGWINSZ */
144 extern int quit_char
;
148 #include "termhooks.h"
149 #include "termchar.h"
150 #include "termopts.h"
151 #include "dispextern.h"
154 #ifdef NONSYSTEM_DIR_LIBRARY
156 #endif /* NONSYSTEM_DIR_LIBRARY */
158 #include "syssignal.h"
161 static int baud_convert
[] =
166 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
167 1800, 2400, 4800, 9600, 19200, 38400
173 /* The file descriptor for Emacs's input terminal.
174 Under Unix, this is always left zero;
175 under VMS, we place the input channel number here.
176 This allows us to write more code that works for both VMS and Unix. */
181 struct emacs_tty buf
;
186 /* Discarding input is not safe when the input could contain
187 replies from the X server. So don't do it. */
188 if (read_socket_hook
)
193 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
194 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
200 ioctl (0, TIOCFLUSH
, &zero
);
202 #else /* not Apollo */
203 EMACS_GET_TTY (input_fd
, &buf
);
204 EMACS_SET_TTY (input_fd
, &buf
, 0);
205 #endif /* not Apollo */
214 /* Should perhaps error if in batch mode */
216 ioctl (0, TIOCSTI
, &c
);
217 #else /* no TIOCSTI */
218 error ("Cannot stuff terminal input characters in this version of Unix.");
219 #endif /* no TIOCSTI */
233 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
234 &sg
.class, 12, 0, 0, 0, 0 );
235 ospeed
= sg
.xmit_baud
;
240 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
242 ospeed
= sg
.c_cflag
& CBAUD
;
243 #else /* neither VMS nor TERMIOS */
247 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
251 ioctl (input_fd
, TCGETA
, &sg
);
253 ospeed
= sg
.c_cflag
& CBAUD
;
254 #else /* neither VMS nor TERMIOS nor TERMIO */
257 sg
.sg_ospeed
= B9600
;
258 ioctl (0, TIOCGETP
, &sg
);
259 ospeed
= sg
.sg_ospeed
;
260 #endif /* not HAVE_TERMIO */
261 #endif /* not HAVE_TERMIOS */
265 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
266 ? baud_convert
[ospeed
] : 9600);
272 set_exclusive_use (fd
)
276 ioctl (fd
, FIOCLEX
, 0);
278 /* Ok to do nothing if this feature does not exist */
283 wait_without_blocking ()
286 wait3 (0, WNOHANG
| WUNTRACED
, 0);
288 croak ("wait_without_blocking");
290 synch_process_alive
= 0;
293 #endif /* not subprocesses */
295 int wait_debugging
; /* Set nonzero to make following function work under dbx
296 (at least for bsd). */
299 wait_for_termination_signal ()
302 /* Wait for subprocess with process id `pid' to terminate and
303 make sure it will get eliminated (not remain forever as a zombie) */
305 wait_for_termination (pid
)
314 status
= SYS$
FORCEX (&pid
, 0, 0);
317 #if (defined (BSD) && !defined (LINUX)) || (defined (HPUX) && !defined (HPUX_5))
318 /* Note that kill returns -1 even if the process is just a zombie now.
319 But inevitably a SIGCHLD interrupt should be generated
320 and child_sig will do wait3 and make the process go away. */
321 /* There is some indication that there is a bug involved with
322 termination of subprocesses, perhaps involving a kernel bug too,
323 but no idea what it is. Just as a hunch we signal SIGCHLD to see
324 if that causes the problem to go away or get worse. */
325 sigsetmask (sigmask (SIGCHLD
));
326 if (0 > kill (pid
, 0))
328 sigsetmask (SIGEMPTYMASK
);
329 kill (getpid (), SIGCHLD
);
335 sigpause (SIGEMPTYMASK
);
336 #else /* not BSD, not LINUX, and not HPUX version >= 6 */
337 #if defined (UNIPLUS) || defined (LINUX)
338 if (0 > kill (pid
, 0))
341 #else /* neither BSD nor UNIPLUS nor LINUX: random sysV */
342 #ifdef HAVE_SYSV_SIGPAUSE
344 if (0 > kill (pid
, 0))
350 #else /* not HAVE_SYSV_SIGPAUSE */
351 if (0 > kill (pid
, 0))
353 /* Using sleep instead of pause avoids timing error.
354 If the inferior dies just before the sleep,
355 we lose just one second. */
357 #endif /* not HAVE_SYSV_SIGPAUSE */
358 #endif /* not UNIPLUS */
359 #endif /* not BSD, and not HPUX version >= 6 */
361 #else /* not subprocesses */
363 if (kill (pid
, 0) < 0)
369 if (status
== pid
|| status
== -1)
372 #endif /* not subprocesses */
379 * flush any pending output
380 * (may flush input as well; it does not matter the way we use it)
383 flush_pending_output (channel
)
387 /* If we try this, we get hit with SIGTTIN, because
388 the child's tty belongs to the child's pgrp. */
391 ioctl (channel
, TCFLSH
, 1);
395 /* 3rd arg should be ignored
396 but some 4.2 kernels actually want the address of an int
397 and nonzero means something different. */
398 ioctl (channel
, TIOCFLUSH
, &zero
);
405 /* Set up the terminal at the other end of a pseudo-terminal that
406 we will be controlling an inferior through.
407 It should not echo or do line-editing, since that is done
408 in Emacs. No padding needed for insertion into an Emacs buffer. */
410 child_setup_tty (out
)
415 EMACS_GET_TTY (out
, &s
);
417 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
418 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
419 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
420 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
421 /* No output delays */
422 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
423 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
424 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
426 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
429 /* Said to be unnecesary: */
430 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
431 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
434 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
435 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
436 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
437 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
440 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
444 /* AIX enhanced edit loses NULs, so disable it */
447 s
.main
.c_iflag
&= ~ASCEDIT
;
449 /* Also, PTY overloads NUL and BREAK.
450 don't ignore break, but don't signal either, so it looks like NUL. */
451 s
.main
.c_iflag
&= ~IGNBRK
;
452 s
.main
.c_iflag
&= ~BRKINT
;
453 /* QUIT and INTR work better as signals, so disable character forms */
454 s
.main
.c_cc
[VQUIT
] = 0377;
455 s
.main
.c_cc
[VINTR
] = 0377;
456 s
.main
.c_cc
[VEOL
] = 0377;
457 s
.main
.c_lflag
&= ~ISIG
;
458 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
461 #else /* not HAVE_TERMIO */
463 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
465 s
.main
.sg_erase
= 0377;
466 s
.main
.sg_kill
= 0377;
468 #endif /* not HAVE_TERMIO */
470 EMACS_SET_TTY (out
, &s
, 0);
479 ioctl (out
, FIOASYNC
, &zero
);
485 #endif /* subprocesses */
491 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
494 /* Record a signal code and the handler for it. */
498 SIGTYPE (*handler
) ();
501 /* Suspend the Emacs process; give terminal to its superior. */
506 /* "Foster" parentage allows emacs to return to a subprocess that attached
507 to the current emacs as a cheaper than starting a whole new process. This
508 is set up by KEPTEDITOR.COM. */
509 unsigned long parent_id
, foster_parent_id
;
512 fpid_string
= getenv ("EMACS_PARENT_PID");
513 if (fpid_string
!= NULL
)
515 sscanf (fpid_string
, "%x", &foster_parent_id
);
516 if (foster_parent_id
!= 0)
517 parent_id
= foster_parent_id
;
519 parent_id
= getppid ();
522 parent_id
= getppid ();
524 xfree (fpid_string
); /* On VMS, this was malloc'd */
526 if (parent_id
&& parent_id
!= 0xffffffff)
528 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
529 int status
= LIB$
ATTACH (&parent_id
) & 1;
530 signal (SIGINT
, oldsig
);
539 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
540 d_prompt
.a
= "Emacs: "; /* Just a reminder */
541 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
548 EMACS_KILLPG (getpgrp (0), SIGTSTP
);
550 #else /* No SIGTSTP */
551 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
552 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
553 kill (getpid (), SIGQUIT
);
555 #else /* No SIGTSTP or USG_JOBCTRL */
557 /* On a system where suspending is not implemented,
558 instead fork a subshell and let it talk directly to the terminal
561 struct save_signal saved_handlers
[5];
563 saved_handlers
[0].code
= SIGINT
;
564 saved_handlers
[1].code
= SIGQUIT
;
565 saved_handlers
[2].code
= SIGTERM
;
567 saved_handlers
[3].code
= SIGIO
;
568 saved_handlers
[4].code
= 0;
570 saved_handlers
[3].code
= 0;
574 error ("Can't spawn subshell");
579 sh
= (char *) egetenv ("SHELL");
582 /* Use our buffer's default directory for the subshell. */
588 /* mentioning current_buffer->buffer would mean including buffer.h,
589 which somehow wedges the hp compiler. So instead... */
591 dir
= intern ("default-directory");
593 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
595 dir
= Fsymbol_value (dir
);
596 if (XTYPE (dir
) != Lisp_String
)
599 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
600 len
= XSTRING (dir
)->size
;
601 bcopy (XSTRING (dir
)->data
, str
, len
);
602 if (str
[len
- 1] != '/') str
[len
++] = '/';
608 close_process_descs (); /* Close Emacs's pipes/ptys */
613 extern int emacs_priority
;
616 nice (-emacs_priority
);
621 write (1, "Can't execute subshell", 22);
625 save_signal_handlers (saved_handlers
);
626 synch_process_alive
= 1;
627 wait_for_termination (pid
);
628 restore_signal_handlers (saved_handlers
);
630 #endif /* no USG_JOBCTRL */
631 #endif /* no SIGTSTP */
635 save_signal_handlers (saved_handlers
)
636 struct save_signal
*saved_handlers
;
638 while (saved_handlers
->code
)
640 saved_handlers
->handler
641 = (SIGTYPE (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
646 restore_signal_handlers (saved_handlers
)
647 struct save_signal
*saved_handlers
;
649 while (saved_handlers
->code
)
651 signal (saved_handlers
->code
, saved_handlers
->handler
);
663 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
673 #ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
678 sigunblock (sigmask (SIGWINCH
));
680 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
682 interrupts_deferred
= 0;
688 sigblock (sigmask (SIGWINCH
));
690 fcntl (0, F_SETFL
, old_fcntl_flags
);
691 interrupts_deferred
= 1;
694 #else /* no FASYNC */
695 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
700 ioctl (0, FIOASYNC
, &on
);
701 interrupts_deferred
= 0;
708 ioctl (0, FIOASYNC
, &off
);
709 interrupts_deferred
= 1;
712 #else /* not FASYNC, not STRIDE */
716 croak ("request_sigio");
721 croak ("unrequest_sigio");
728 /* Getting and setting emacs_tty structures. */
730 /* Set *TC to the parameters associated with the terminal FD.
731 Return zero if all's well, or -1 if we ran into an error we
732 couldn't deal with. */
734 emacs_get_tty (fd
, settings
)
736 struct emacs_tty
*settings
;
738 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
740 /* We have those nifty POSIX tcmumbleattr functions. */
741 if (tcgetattr (fd
, &settings
->main
) < 0)
746 /* The SYSV-style interface? */
747 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
752 /* Vehemently Monstrous System? :-) */
753 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
754 &settings
->main
.class, 12, 0, 0, 0, 0)
759 /* I give up - I hope you have the BSD ioctls. */
760 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
767 /* Suivant - Do we have to get struct ltchars data? */
769 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
773 /* How about a struct tchars and a wordful of lmode bits? */
775 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
776 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
780 /* We have survived the tempest. */
785 /* Set the parameters of the tty on FD according to the contents of
786 *SETTINGS. If WAITP is non-zero, we wait for all queued output to
787 be written before making the change; otherwise, we forget any
788 queued input and make the change immediately.
789 Return 0 if all went well, and -1 if anything failed. */
791 emacs_set_tty (fd
, settings
, waitp
)
793 struct emacs_tty
*settings
;
796 /* Set the primary parameters - baud rate, character size, etcetera. */
798 /* We have those nifty POSIX tcmumbleattr functions.
799 William J. Smith <wjs@wiis.wang.com> writes:
800 "POSIX 1003.1 defines tcsetattr() to return success if it was
801 able to perform any of the requested actions, even if some
802 of the requested actions could not be performed.
803 We must read settings back to ensure tty setup properly.
804 AIX requires this to keep tty from hanging occasionally." */
806 if (tcsetattr (fd
, waitp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
817 /* Get the current settings, and see if they're what we asked for. */
818 tcgetattr (fd
, &new);
819 if (memcmp (&new, &settings
->main
, sizeof (new)))
827 /* The SYSV-style interface? */
828 if (ioctl (fd
, waitp
? TCSETAW
: TCSETAF
, &settings
->main
) < 0)
833 /* Vehemently Monstrous System? :-) */
834 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
835 &settings
->main
.class, 12, 0, 0, 0, 0)
840 /* I give up - I hope you have the BSD ioctls. */
841 if (ioctl (fd
, (waitp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
848 /* Suivant - Do we have to get struct ltchars data? */
850 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
854 /* How about a struct tchars and a wordful of lmode bits? */
856 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
857 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
861 /* We have survived the tempest. */
866 /* The initial tty mode bits */
867 struct emacs_tty old_tty
;
869 int term_initted
; /* 1 if outer tty status has been recorded */
872 /* BSD 4.1 needs to keep track of the lmode bits in order to start
879 #endif /* F_SETOWN */
881 /* This may also be defined in stdio,
882 but if so, this does no harm,
883 and using the same name avoids wasting the other one's space. */
885 #if defined (USG) || defined (DGUX)
886 unsigned char _sobuf
[BUFSIZ
+8];
892 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
895 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
900 struct emacs_tty tty
;
904 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
905 extern int (*interrupt_signal
) ();
914 input_ef
= get_kbd_event_flag ();
915 /* LIB$GET_EF (&input_ef); */
916 SYS$
CLREF (input_ef
);
919 timer_ef
= get_timer_event_flag ();
920 /* LIB$GET_EF (&timer_ef); */
921 SYS$
CLREF (timer_ef
);
925 LIB$
GET_EF (&process_ef
);
926 SYS$
CLREF (process_ef
);
928 if (input_ef
/ 32 != process_ef
/ 32)
929 croak ("Input and process event flags in different clusters.");
931 if (input_ef
/ 32 != timer_ef
/ 32)
932 croak ("Input and timer event flags in different clusters.");
934 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
935 ((unsigned) 1 << (process_ef
% 32));
937 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
938 ((unsigned) 1 << (timer_ef
% 32));
940 sys_access_reinit ();
944 EMACS_GET_TTY (input_fd
, &old_tty
);
946 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
950 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
951 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
952 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
954 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
956 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
957 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
959 tty
.main
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
961 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
964 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
966 tty
.main
.c_iflag
&= ~IXANY
;
970 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
971 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
973 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
977 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
978 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
981 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
982 /* Set up C-g for both SIGQUIT and SIGINT.
983 We don't know which we will get, but we handle both alike
984 so which one it really gives us does not matter. */
985 tty
.main
.c_cc
[VQUIT
] = quit_char
;
986 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
987 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
989 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
992 #if defined (mips) || defined (HAVE_TCATTR)
994 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
997 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
999 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1000 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1002 #endif /* mips or HAVE_TCATTR */
1005 /* AIX enhanced edit loses NULs, so disable it */
1006 tty
.main
.c_line
= 0;
1007 tty
.main
.c_iflag
&= ~ASCEDIT
;
1009 tty
.main
.c_cc
[VSTRT
] = 255;
1010 tty
.main
.c_cc
[VSTOP
] = 255;
1011 tty
.main
.c_cc
[VSUSP
] = 255;
1012 tty
.main
.c_cc
[VDSUSP
] = 255;
1013 #endif /* IBMR2AIX */
1014 /* Also, PTY overloads NUL and BREAK.
1015 don't ignore break, but don't signal either, so it looks like NUL.
1016 This really serves a purpose only if running in an XTERM window
1017 or via TELNET or the like, but does no harm elsewhere. */
1018 tty
.main
.c_iflag
&= ~IGNBRK
;
1019 tty
.main
.c_iflag
&= ~BRKINT
;
1021 #else /* if not HAVE_TERMIO */
1023 tty
.main
.tt_char
|= TT$M_NOECHO
;
1025 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1027 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1029 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1030 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1031 #else /* not VMS (BSD, that is) */
1032 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1034 tty
.main
.sg_flags
|= ANYP
;
1035 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1036 #endif /* not VMS (BSD, that is) */
1037 #endif /* not HAVE_TERMIO */
1039 /* If going to use CBREAK mode, we must request C-g to interrupt
1040 and turn off start and stop chars, etc. If not going to use
1041 CBREAK mode, do this anyway so as to turn off local flow
1042 control for user coming over network on 4.2; in this case,
1043 only t_stopc and t_startc really matter. */
1046 /* Note: if not using CBREAK mode, it makes no difference how we
1048 tty
.tchars
= new_tchars
;
1049 tty
.tchars
.t_intrc
= quit_char
;
1052 tty
.tchars
.t_startc
= '\021';
1053 tty
.tchars
.t_stopc
= '\023';
1056 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
1062 #define LNOFLSH 0100000
1065 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1071 #endif /* HAVE_TCHARS */
1072 #endif /* not HAVE_TERMIO */
1075 tty
.ltchars
= new_ltchars
;
1076 #endif /* HAVE_LTCHARS */
1078 EMACS_SET_TTY (input_fd
, &tty
, 0);
1080 /* This code added to insure that, if flow-control is not to be used,
1081 we have an unlocked terminal at the start. */
1084 if (!flow_control
) ioctl (0, TCXONC
, 1);
1088 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
1096 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1097 to be only LF. This is the way that is done. */
1100 if (ioctl (1, HFTGETID
, &tty
) != -1)
1101 write (1, "\033[20l", 5);
1107 /* Appears to do nothing when in PASTHRU mode.
1108 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1109 interrupt_signal, oob_chars, 0, 0, 0, 0);
1111 queue_kbd_input (0);
1116 #ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
1117 if (interrupt_input
)
1119 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
1120 fcntl (0, F_SETOWN
, getpid ());
1123 #endif /* F_GETOWN */
1124 #endif /* F_SETFL */
1127 if (interrupt_input
)
1131 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1135 /* This symbol is defined on recent USG systems.
1136 Someone says without this call USG won't really buffer the file
1137 even with a call to setbuf. */
1138 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1140 setbuf (stdout
, _sobuf
);
1142 set_terminal_modes ();
1143 if (term_initted
&& no_redraw_on_reenter
)
1145 if (display_completed
)
1146 direct_output_forward_char (0);
1152 if (FRAMEP (Vterminal_frame
))
1153 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1160 /* Return nonzero if safe to use tabs in output.
1161 At the time this is called, init_sys_modes has not been done yet. */
1165 struct emacs_tty tty
;
1167 EMACS_GET_TTY (input_fd
, &tty
);
1168 return EMACS_TTY_TABS_OK (&tty
);
1171 /* Get terminal size from system.
1172 Store number of lines into *heightp and width into *widthp.
1173 If zero or a negative number is stored, the value is not valid. */
1175 get_frame_size (widthp
, heightp
)
1176 int *widthp
, *heightp
;
1182 struct winsize size
;
1184 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1185 *widthp
= *heightp
= 0;
1188 *widthp
= size
.ws_col
;
1189 *heightp
= size
.ws_row
;
1195 /* SunOS - style. */
1196 struct ttysize size
;
1198 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1199 *widthp
= *heightp
= 0;
1202 *widthp
= size
.ts_cols
;
1203 *heightp
= size
.ts_lines
;
1209 struct sensemode tty
;
1211 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1212 &tty
.class, 12, 0, 0, 0, 0);
1213 *widthp
= tty
.scr_wid
;
1214 *heightp
= tty
.scr_len
;
1216 #else /* system doesn't know size */
1221 #endif /* not VMS */
1222 #endif /* not SunOS-style */
1223 #endif /* not BSD-style */
1227 /* Prepare the terminal for exiting Emacs; move the cursor to the
1228 bottom of the frame, turn off interrupt-driven I/O, etc. */
1238 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1240 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1241 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1242 /* clear_end_of_line may move the cursor */
1243 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1246 /* HFT devices normally use ^J as a LF/CR. We forced it to
1247 do the LF only. Now, we need to reset it. */
1250 if (ioctl (1, HFTGETID
, &tty
) != -1)
1251 write (1, "\033[20h", 5);
1255 reset_terminal_modes ();
1259 /* Avoid possible loss of output when changing terminal modes. */
1260 fsync (fileno (stdout
));
1265 #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */
1266 if (interrupt_input
)
1269 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1271 #endif /* F_SETOWN */
1272 #endif /* F_SETFL */
1274 if (interrupt_input
)
1278 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1288 /* Set up the proper status flags for use of a pty. */
1293 /* I'm told that TOICREMOTE does not mean control chars
1294 "can't be sent" but rather that they don't have
1295 input-editing or signaling effects.
1296 That should be good, because we have other ways
1297 to do those things in Emacs.
1298 However, telnet mode seems not to work on 4.2.
1299 So TIOCREMOTE is turned off now. */
1301 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1302 will hang. In particular, the "timeout" feature (which
1303 causes a read to return if there is no data available)
1304 does this. Also it is known that telnet mode will hang
1305 in such a way that Emacs must be stopped (perhaps this
1306 is the same problem).
1308 If TIOCREMOTE is turned off, then there is a bug in
1309 hp-ux which sometimes loses data. Apparently the
1310 code which blocks the master process when the internal
1311 buffer fills up does not work. Other than this,
1312 though, everything else seems to work fine.
1314 Since the latter lossage is more benign, we may as well
1315 lose that way. -- cph */
1320 ioctl (fd
, FIONBIO
, &on
);
1325 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1326 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1327 /* cause EMACS not to die when it should, i.e., when its own controlling */
1328 /* tty goes away. I've complained to the AIX developers, and they may */
1329 /* change this behavior, but I'm not going to hold my breath. */
1330 signal (SIGHUP
, SIG_IGN
);
1333 #endif /* HAVE_PTYS */
1337 /* Assigning an input channel is done at the start of Emacs execution.
1338 This is called each time Emacs is resumed, also, but does nothing
1339 because input_chain is no longer zero. */
1347 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1353 /* Deassigning the input channel is done before exiting. */
1357 return SYS$
DASSGN (input_fd
);
1362 /* Request reading one character into the keyboard buffer.
1363 This is done as soon as the buffer becomes empty. */
1368 extern kbd_input_ast ();
1370 waiting_for_ast
= 0;
1372 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1373 &input_iosb
, kbd_input_ast
, 1,
1374 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1379 /* Ast routine that is called when keyboard input comes in
1380 in accord with the SYS$QIO above. */
1384 register int c
= -1;
1385 int old_errno
= errno
;
1386 extern EMACS_TIME
*input_available_clear_time
;
1388 if (waiting_for_ast
)
1389 SYS$
SETEF (input_ef
);
1390 waiting_for_ast
= 0;
1393 if (input_count
== 25)
1395 printf ("Ast # %d,", input_count
);
1396 printf (" iosb = %x, %x, %x, %x",
1397 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1400 if (input_iosb
.offset
)
1404 printf (", char = 0%o", c
);
1416 struct input_event e
;
1417 e
.kind
= ascii_keystroke
;
1418 XSET (e
.code
, Lisp_Int
, c
);
1420 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1422 e
.frame_or_window
= Qnil
;
1424 kbd_buffer_store_event (&e
);
1426 if (input_available_clear_time
)
1427 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1431 /* Wait until there is something in kbd_buffer. */
1433 wait_for_kbd_input ()
1435 extern int have_process_input
, process_exited
;
1437 /* If already something, avoid doing system calls. */
1438 if (detect_input_pending ())
1442 /* Clear a flag, and tell ast routine above to set it. */
1443 SYS$
CLREF (input_ef
);
1444 waiting_for_ast
= 1;
1445 /* Check for timing error: ast happened while we were doing that. */
1446 if (!detect_input_pending ())
1448 /* No timing error: wait for flag to be set. */
1449 set_waiting_for_input (0);
1450 SYS$
WFLOR (input_ef
, input_eflist
);
1451 clear_waiting_for_input (0);
1452 if (!detect_input_pending ())
1453 /* Check for subprocess input availability */
1455 int dsp
= have_process_input
|| process_exited
;
1457 SYS$
CLREF (process_ef
);
1458 if (have_process_input
)
1459 process_command_input ();
1464 update_mode_lines
++;
1465 redisplay_preserve_echo_area ();
1469 waiting_for_ast
= 0;
1472 /* Get rid of any pending QIO, when we are about to suspend
1473 or when we want to throw away pending input.
1474 We wait for a positive sign that the AST routine has run
1475 and therefore there is no I/O request queued when we return.
1476 SYS$SETAST is used to avoid a timing error. */
1481 printf ("At end_kbd_input.\n");
1485 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1487 SYS$
CANCEL (input_fd
);
1492 /* Clear a flag, and tell ast routine above to set it. */
1493 SYS$
CLREF (input_ef
);
1494 waiting_for_ast
= 1;
1496 SYS$
CANCEL (input_fd
);
1498 SYS$
WAITFR (input_ef
);
1499 waiting_for_ast
= 0;
1502 /* Wait for either input available or time interval expiry. */
1504 input_wait_timeout (timeval
)
1505 int timeval
; /* Time to wait, in seconds */
1508 static int zero
= 0;
1509 static int large
= -10000000;
1511 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1513 /* If already something, avoid doing system calls. */
1514 if (detect_input_pending ())
1518 /* Clear a flag, and tell ast routine above to set it. */
1519 SYS$
CLREF (input_ef
);
1520 waiting_for_ast
= 1;
1521 /* Check for timing error: ast happened while we were doing that. */
1522 if (!detect_input_pending ())
1524 /* No timing error: wait for flag to be set. */
1526 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1527 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1529 waiting_for_ast
= 0;
1532 /* The standard `sleep' routine works some other way
1533 and it stops working if you have ever quit out of it.
1534 This one continues to work. */
1540 static int zero
= 0;
1541 static int large
= -10000000;
1543 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1546 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1547 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1562 croak ("request sigio");
1567 croak ("unrequest sigio");
1572 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1577 #ifndef SYSTEM_MALLOC
1584 /* Some systems that cannot dump also cannot implement these. */
1587 * Return the address of the start of the text segment prior to
1588 * doing an unexec. After unexec the return value is undefined.
1589 * See crt0.c for further explanation and _start.
1593 #ifndef CANNOT_UNEXEC
1598 return ((char *) TEXT_START
);
1602 return ((char *) csrt
);
1603 #else /* not GOULD */
1604 extern int _start ();
1605 return ((char *) _start
);
1607 #endif /* TEXT_START */
1609 #endif /* not CANNOT_UNEXEC */
1612 * Return the address of the start of the data segment prior to
1613 * doing an unexec. After unexec the return value is undefined.
1614 * See crt0.c for further information and definition of data_start.
1616 * Apparently, on BSD systems this is etext at startup. On
1617 * USG systems (swapping) this is highly mmu dependent and
1618 * is also dependent on whether or not the program is running
1619 * with shared text. Generally there is a (possibly large)
1620 * gap between end of text and start of data with shared text.
1622 * On Uniplus+ systems with shared text, data starts at a
1623 * fixed address. Each port (from a given oem) is generally
1624 * different, and the specific value of the start of data can
1625 * be obtained via the UniPlus+ specific "uvar" system call,
1626 * however the method outlined in crt0.c seems to be more portable.
1628 * Probably what will have to happen when a USG unexec is available,
1629 * at least on UniPlus, is temacs will have to be made unshared so
1630 * that text and data are contiguous. Then once loadup is complete,
1631 * unexec will produce a shared executable where the data can be
1632 * at the normal shared text boundry and the startofdata variable
1633 * will be patched by unexec to the correct value.
1641 return ((char *) DATA_START
);
1643 #ifdef ORDINARY_LINK
1645 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1646 * data_start isn't defined. We take the address of environ, which
1647 * is known to live at or near the start of the system crt0.c, and
1648 * we don't sweat the handful of bytes that might lose.
1650 extern char **environ
;
1652 return((char *) &environ
);
1654 extern int data_start
;
1655 return ((char *) &data_start
);
1656 #endif /* ORDINARY_LINK */
1657 #endif /* DATA_START */
1659 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1662 /* Some systems that cannot dump also cannot implement these. */
1665 * Return the address of the end of the text segment prior to
1666 * doing an unexec. After unexec the return value is undefined.
1673 return ((char *) TEXT_END
);
1676 return ((char *) &etext
);
1681 * Return the address of the end of the data segment prior to
1682 * doing an unexec. After unexec the return value is undefined.
1689 return ((char *) DATA_END
);
1692 return ((char *) &edata
);
1696 #endif /* not CANNOT_DUMP */
1698 /* Get_system_name returns as its value
1699 a string for the Lisp function system-name to return. */
1705 /* Can't have this within the function since `static' is #defined to
1706 nothing for some USG systems. */
1708 #ifdef HAVE_GETHOSTNAME
1709 static char get_system_name_name
[256];
1710 #else /* not HAVE_GETHOSTNAME */
1711 static struct utsname get_system_name_name
;
1712 #endif /* not HAVE_GETHOSTNAME */
1719 #include <sys/socket.h>
1721 #endif /* HAVE_SOCKETS */
1722 #endif /* not VMS */
1723 #endif /* not USG */
1724 #endif /* not BSD4_1 */
1730 #ifdef HAVE_GETHOSTNAME
1731 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1732 return get_system_name_name
;
1733 #else /* not HAVE_GETHOSTNAME */
1734 uname (&get_system_name_name
);
1735 return (get_system_name_name
.nodename
);
1736 #endif /* not HAVE_GETHOSTNAME */
1740 #else /* not USG, not 4.1 */
1741 static char system_name_saved
[32];
1744 if ((sp
= egetenv ("SYS$NODE")) == 0)
1750 if ((end
= index (sp
, ':')) != 0)
1753 strcpy (system_name_saved
, sp
);
1755 gethostname (system_name_saved
, sizeof (system_name_saved
));
1757 /* Turn the hostname into the official, fully-qualified hostname.
1758 Don't do this if we're going to dump; this can confuse system
1759 libraries on some machines and make the dumped emacs core dump. */
1762 #endif /* not CANNOT_DUMP */
1765 hp
= gethostbyname (system_name_saved
);
1766 if (hp
&& strlen (hp
->h_name
) < sizeof(system_name_saved
))
1767 strcpy (system_name_saved
, hp
->h_name
);
1769 #endif /* HAVE_SOCKETS */
1770 #endif /* not VMS */
1771 return system_name_saved
;
1772 #endif /* not USG, not 4.1 */
1773 #endif /* not USG */
1777 #ifndef HAVE_GETHOSTNAME
1778 void gethostname(buf
, len
)
1783 s
= getenv ("SYS$NODE");
1787 strncpy (buf
, s
, len
- 2);
1788 buf
[len
- 1] = '\0';
1790 } /* static void gethostname */
1791 #endif /* ! HAVE_GETHOSTNAME */
1798 #ifdef HAVE_X_WINDOWS
1799 /* Cause explanatory error message at compile time,
1800 since the select emulation is not good enough for X. */
1801 int *x
= &x_windows_lose_if_no_select_system_call
;
1804 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1805 * Only checks read descriptors.
1807 /* How long to wait between checking fds in select */
1808 #define SELECT_PAUSE 1
1811 /* For longjmp'ing back to read_input_waiting. */
1813 jmp_buf read_alarm_throw
;
1815 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1816 The read_socket_hook function sets this to 1 while it is waiting. */
1818 int read_alarm_should_throw
;
1826 #else /* not BSD4_1 */
1827 signal (SIGALRM
, SIG_IGN
);
1828 #endif /* not BSD4_1 */
1829 if (read_alarm_should_throw
)
1830 longjmp (read_alarm_throw
, 1);
1833 /* Only rfds are checked. */
1835 select (nfds
, rfds
, wfds
, efds
, timeout
)
1837 int *rfds
, *wfds
, *efds
, *timeout
;
1839 int ravail
= 0, orfds
= 0, old_alarm
;
1840 int timeoutval
= timeout
? *timeout
: 100000;
1841 int *local_timeout
= &timeoutval
;
1842 extern int proc_buffered_char
[];
1843 #ifndef subprocesses
1844 int process_tick
= 0, update_tick
= 0;
1846 extern int process_tick
, update_tick
;
1848 SIGTYPE (*old_trap
) ();
1861 /* If we are looking only for the terminal, with no timeout,
1862 just read it and wait -- that's more efficient. */
1863 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1865 if (! detect_input_pending ())
1866 read_input_waiting ();
1871 /* Once a second, till the timer expires, check all the flagged read
1872 * descriptors to see if any input is available. If there is some then
1873 * set the corresponding bit in the return copy of rfds.
1877 register int to_check
, bit
, fd
;
1881 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1885 int avail
= 0, status
= 0;
1888 avail
= detect_input_pending (); /* Special keyboard handler */
1892 status
= ioctl (fd
, FIONREAD
, &avail
);
1893 #else /* no FIONREAD */
1894 /* Hoping it will return -1 if nothing available
1895 or 0 if all 0 chars requested are read. */
1896 if (proc_buffered_char
[fd
] >= 0)
1900 avail
= read (fd
, &buf
, 1);
1902 proc_buffered_char
[fd
] = buf
;
1904 #endif /* no FIONREAD */
1906 if (status
>= 0 && avail
> 0)
1914 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
1916 old_alarm
= alarm (0);
1917 old_trap
= signal (SIGALRM
, select_alarm
);
1919 alarm (SELECT_PAUSE
);
1920 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1921 while (select_alarmed
== 0 && *local_timeout
!= 0
1922 && process_tick
== update_tick
)
1924 /* If we are interested in terminal input,
1925 wait by reading the terminal.
1926 That makes instant wakeup for terminal input at least. */
1929 read_input_waiting ();
1930 if (detect_input_pending ())
1936 (*local_timeout
) -= SELECT_PAUSE
;
1937 /* Reset the old alarm if there was one */
1939 signal (SIGALRM
, old_trap
);
1942 /* Reset or forge an interrupt for the original handler. */
1943 old_alarm
-= SELECT_PAUSE
;
1945 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
1949 if (*local_timeout
== 0) /* Stop on timer being cleared */
1955 /* Read keyboard input into the standard buffer,
1956 waiting for at least one character. */
1958 /* Make all keyboard buffers much bigger when using X windows. */
1959 #ifdef HAVE_X_WINDOWS
1960 #define BUFFER_SIZE_FACTOR 16
1962 #define BUFFER_SIZE_FACTOR 1
1965 read_input_waiting ()
1967 char buf
[256 * BUFFER_SIZE_FACTOR
];
1968 struct input_event e
;
1970 extern int quit_char
;
1972 if (read_socket_hook
)
1974 read_alarm_should_throw
= 0;
1975 if (! setjmp (read_alarm_throw
))
1976 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
1981 nread
= read (fileno (stdin
), buf
, 1);
1983 /* Scan the chars for C-g and store them in kbd_buffer. */
1984 e
.kind
= ascii_keystroke
;
1985 e
.frame_or_window
= selected_frame
;
1987 for (i
= 0; i
< nread
; i
++)
1989 XSET (e
.code
, Lisp_Int
, buf
[i
]);
1990 kbd_buffer_store_event (&e
);
1991 /* Don't look at input that follows a C-g too closely.
1992 This reduces lossage due to autorepeat on C-g. */
1993 if (buf
[i
] == quit_char
)
1998 #endif /* not HAVE_SELECT */
1999 #endif /* not VMS */
2003 * Partially emulate 4.2 open call.
2004 * open is defined as this in 4.1.
2006 * - added by Michael Bloom @ Citicorp/TTI
2011 sys_open (path
, oflag
, mode
)
2015 if (oflag
& O_CREAT
)
2016 return creat (path
, mode
);
2018 return open (path
, oflag
);
2025 lmode
= LINTRUP
| lmode
;
2026 ioctl (0, TIOCLSET
, &lmode
);
2033 lmode
= ~LINTRUP
& lmode
;
2034 ioctl (0, TIOCLSET
, &lmode
);
2041 interrupts_deferred
= 0;
2048 interrupts_deferred
= 1;
2051 /* still inside #ifdef BSD4_1 */
2054 int sigheld
; /* Mask of held signals */
2059 sigheld
|= sigbit (signum
);
2066 sigheld
|= sigbit (signum
);
2072 sigheld
&= ~sigbit (signum
);
2076 sigfree () /* Free all held signals */
2079 for (i
= 0; i
< NSIG
; i
++)
2080 if (sigheld
& sigbit (i
))
2087 return 1 << (i
- 1);
2089 #endif /* subprocesses */
2092 /* POSIX signals support - DJB */
2093 /* Anyone with POSIX signals should have ANSI C declarations */
2095 #ifdef POSIX_SIGNALS
2097 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
2098 static struct sigaction new_action
, old_action
;
2102 sigemptyset (&empty_mask
);
2103 sigfillset (&full_mask
);
2107 sys_signal (int signal_number
, signal_handler_t action
)
2110 /* This gets us restartable system calls for efficiency.
2111 The "else" code will works as well. */
2112 return (berk_signal (signal_number
, action
));
2114 sigemptyset (&new_action
.sa_mask
);
2115 new_action
.sa_handler
= action
;
2116 new_action
.sa_flags
= 0;
2117 sigaction (signal_number
, &new_action
, &old_action
);
2118 return (old_action
.sa_handler
);
2123 /* If we're compiling with GCC, we don't need this function, since it
2124 can be written as a macro. */
2126 sys_sigmask (int sig
)
2129 sigemptyset (&mask
);
2130 sigaddset (&mask
, sig
);
2136 sys_sigpause (sigset_t new_mask
)
2138 /* pause emulating berk sigpause... */
2139 sigsuspend (&new_mask
);
2143 /* I'd like to have these guys return pointers to the mask storage in here,
2144 but there'd be trouble if the code was saving multiple masks. I'll be
2145 safe and pass the structure. It normally won't be more than 2 bytes
2149 sys_sigblock (sigset_t new_mask
)
2152 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2157 sys_sigunblock (sigset_t new_mask
)
2160 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2165 sys_sigsetmask (sigset_t new_mask
)
2168 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2172 #endif /* POSIX_SIGNALS */
2179 register int length
;
2183 long max_str
= 65535;
2185 while (length
> max_str
) {
2186 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2191 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2193 while (length
-- > 0)
2195 #endif /* not VMS */
2198 /* Saying `void' requires a declaration, above, where bcopy is used
2199 and that declaration causes pain for systems where bcopy is a macro. */
2200 bcopy (b1
, b2
, length
)
2203 register int length
;
2206 long max_str
= 65535;
2208 while (length
> max_str
) {
2209 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2215 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2217 while (length
-- > 0)
2219 #endif /* not VMS */
2223 bcmp (b1
, b2
, length
) /* This could be a macro! */
2226 register int length
;
2229 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2230 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2232 return STR$
COMPARE (&src1
, &src2
);
2234 while (length
-- > 0)
2239 #endif /* not VMS */
2241 #endif /* not BSTRING */
2246 * The BSD random returns numbers in the range of
2247 * 0 to 2e31 - 1. The USG rand returns numbers in the
2248 * range of 0 to 2e15 - 1. This is probably not significant
2255 /* Arrange to return a range centered on zero. */
2256 return (rand () << 15) + rand () - (1 << 29);
2270 /* Arrange to return a range centered on zero. */
2271 return (rand () << 15) + rand () - (1 << 29);
2282 #ifdef WRONG_NAME_INSQUE
2295 /* If any place else asks for the TERM variable,
2296 allow it to be overridden with the EMACS_TERM variable
2297 before attempting to translate the logical name TERM. As a last
2298 resort, ask for VAX C's special idea of the TERM variable. */
2305 static char buf
[256];
2306 static struct dsc$descriptor_s equiv
2307 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2308 static struct dsc$descriptor_s d_name
2309 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2312 if (!strcmp (name
, "TERM"))
2314 val
= (char *) getenv ("EMACS_TERM");
2319 d_name
.dsc$w_length
= strlen (name
);
2320 d_name
.dsc$a_pointer
= name
;
2321 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2323 char *str
= (char *) xmalloc (eqlen
+ 1);
2324 bcopy (buf
, str
, eqlen
);
2326 /* This is a storage leak, but a pain to fix. With luck,
2327 no one will ever notice. */
2330 return (char *) getenv (name
);
2335 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2336 to force a call on the debugger from within the image. */
2341 LIB$
SIGNAL (SS$_DEBUG
);
2347 #ifdef LINK_CRTL_SHARE
2348 #ifdef SHAREABLE_LIB_BUG
2349 /* Variables declared noshare and initialized in shareable libraries
2350 cannot be shared. The VMS linker incorrectly forces you to use a private
2351 version which is uninitialized... If not for this "feature", we
2352 could use the C library definition of sys_nerr and sys_errlist. */
2354 char *sys_errlist
[] =
2358 "no such file or directory",
2360 "interrupted system call",
2362 "no such device or address",
2363 "argument list too long",
2364 "exec format error",
2367 "no more processes",
2368 "not enough memory",
2369 "permission denied",
2371 "block device required",
2372 "mount devices busy",
2374 "cross-device link",
2379 "file table overflow",
2380 "too many open files",
2384 "no space left on device",
2386 "read-only file system",
2392 "vax/vms specific error code nontranslatable error"
2394 #endif /* SHAREABLE_LIB_BUG */
2395 #endif /* LINK_CRTL_SHARE */
2398 #ifdef INTERRUPTIBLE_OPEN
2402 sys_open (path
, oflag
, mode
)
2406 register int rtnval
;
2408 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2409 && (errno
== EINTR
));
2413 #endif /* INTERRUPTIBLE_OPEN */
2415 #ifdef INTERRUPTIBLE_CLOSE
2420 register int rtnval
;
2422 while ((rtnval
= close (fd
)) == -1
2423 && (errno
== EINTR
));
2427 #endif /* INTERRUPTIBLE_CLOSE */
2429 #ifdef INTERRUPTIBLE_IO
2432 sys_read (fildes
, buf
, nbyte
)
2437 register int rtnval
;
2439 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2440 && (errno
== EINTR
));
2445 sys_write (fildes
, buf
, nbyte
)
2450 register int rtnval
;
2452 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2453 && (errno
== EINTR
));
2457 #endif /* INTERRUPTIBLE_IO */
2461 * All of the following are for USG.
2463 * On USG systems the system calls are INTERRUPTIBLE by signals
2464 * that the user program has elected to catch. Thus the system call
2465 * must be retried in these cases. To handle this without massive
2466 * changes in the source code, we remap the standard system call names
2467 * to names for our own functions in sysdep.c that do the system call
2468 * with retries. Actually, for portability reasons, it is good
2469 * programming practice, as this example shows, to limit all actual
2470 * system calls to a single occurance in the source. Sure, this
2471 * adds an extra level of function call overhead but it is almost
2472 * always negligible. Fred Fish, Unisoft Systems Inc.
2475 #ifndef HAVE_SYS_SIGLIST
2476 char *sys_siglist
[NSIG
+ 1] =
2479 /* AIX has changed the signals a bit */
2480 "bogus signal", /* 0 */
2481 "hangup", /* 1 SIGHUP */
2482 "interrupt", /* 2 SIGINT */
2483 "quit", /* 3 SIGQUIT */
2484 "illegal instruction", /* 4 SIGILL */
2485 "trace trap", /* 5 SIGTRAP */
2486 "IOT instruction", /* 6 SIGIOT */
2487 "crash likely", /* 7 SIGDANGER */
2488 "floating point exception", /* 8 SIGFPE */
2489 "kill", /* 9 SIGKILL */
2490 "bus error", /* 10 SIGBUS */
2491 "segmentation violation", /* 11 SIGSEGV */
2492 "bad argument to system call", /* 12 SIGSYS */
2493 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2494 "alarm clock", /* 14 SIGALRM */
2495 "software termination signum", /* 15 SIGTERM */
2496 "user defined signal 1", /* 16 SIGUSR1 */
2497 "user defined signal 2", /* 17 SIGUSR2 */
2498 "death of a child", /* 18 SIGCLD */
2499 "power-fail restart", /* 19 SIGPWR */
2500 "bogus signal", /* 20 */
2501 "bogus signal", /* 21 */
2502 "bogus signal", /* 22 */
2503 "bogus signal", /* 23 */
2504 "bogus signal", /* 24 */
2505 "LAN I/O interrupt", /* 25 SIGAIO */
2506 "PTY I/O interrupt", /* 26 SIGPTY */
2507 "I/O intervention required", /* 27 SIGIOINT */
2508 "HFT grant", /* 28 SIGGRANT */
2509 "HFT retract", /* 29 SIGRETRACT */
2510 "HFT sound done", /* 30 SIGSOUND */
2511 "HFT input ready", /* 31 SIGMSG */
2513 "bogus signal", /* 0 */
2514 "hangup", /* 1 SIGHUP */
2515 "interrupt", /* 2 SIGINT */
2516 "quit", /* 3 SIGQUIT */
2517 "illegal instruction", /* 4 SIGILL */
2518 "trace trap", /* 5 SIGTRAP */
2519 "IOT instruction", /* 6 SIGIOT */
2520 "EMT instruction", /* 7 SIGEMT */
2521 "floating point exception", /* 8 SIGFPE */
2522 "kill", /* 9 SIGKILL */
2523 "bus error", /* 10 SIGBUS */
2524 "segmentation violation", /* 11 SIGSEGV */
2525 "bad argument to system call", /* 12 SIGSYS */
2526 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2527 "alarm clock", /* 14 SIGALRM */
2528 "software termination signum", /* 15 SIGTERM */
2529 "user defined signal 1", /* 16 SIGUSR1 */
2530 "user defined signal 2", /* 17 SIGUSR2 */
2531 "death of a child", /* 18 SIGCLD */
2532 "power-fail restart", /* 19 SIGPWR */
2533 #endif /* not AIX */
2536 #endif /* HAVE_SYS_SIGLIST */
2539 * Warning, this function may not duplicate 4.2 action properly
2540 * under error conditions.
2544 /* In 4.1, param.h fails to define this. */
2545 #define MAXPATHLEN 1024
2554 char *npath
, *spath
;
2555 extern char *getcwd ();
2557 BLOCK_INPUT
; /* getcwd uses malloc */
2558 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2559 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2560 up to first slash. Should be harmless on other systems. */
2561 while (*npath
&& *npath
!= '/')
2563 strcpy (pathname
, npath
);
2564 free (spath
); /* getcwd uses malloc */
2569 #endif /* HAVE_GETWD */
2572 * Emulate rename using unlink/link. Note that this is
2573 * only partially correct. Also, doesn't enforce restriction
2574 * that files be of same type (regular->regular, dir->dir, etc).
2583 if (access (from
, 0) == 0)
2586 if (link (from
, to
) == 0)
2587 if (unlink (from
) == 0)
2598 * Substitute fork for vfork on USG flavors.
2606 #endif /* not HAVE_VFORK */
2608 #ifdef MISSING_UTIMES
2610 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2619 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2620 utimbuf structure defined anywhere but in the man page. */
2630 struct timeval tvp
[];
2633 utb
.actime
= tvp
[0].tv_sec
;
2634 utb
.modtime
= tvp
[1].tv_sec
;
2637 #endif /* IRIS_UTIME */
2643 /* HPUX curses library references perror, but as far as we know
2644 it won't be called. Anyway this definition will do for now. */
2650 #endif /* not HAVE_PERROR */
2656 * Emulate BSD dup2. First close newd if it already exists.
2657 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2658 * until we are, then close the unsuccessful ones.
2665 register int fd
, ret
;
2670 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2672 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2679 ret
= dup2 (old
,new);
2685 #endif /* not HAVE_DUP2 */
2688 * Gettimeofday. Simulate as much as possible. Only accurate
2689 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2690 * Only needed when subprocesses are defined.
2695 #ifndef HAVE_GETTIMEOFDAY
2699 gettimeofday (tp
, tzp
)
2701 struct timezone
*tzp
;
2703 extern long time ();
2705 tp
->tv_sec
= time ((long *)0);
2708 tzp
->tz_minuteswest
= -1;
2714 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2717 * This function will go away as soon as all the stubs fixed. (fnf)
2723 printf ("%s not yet implemented\r\n", badfunc
);
2732 char *sys_siglist
[NSIG
+ 1] =
2734 "null signal", /* 0 SIGNULL */
2735 "hangup", /* 1 SIGHUP */
2736 "interrupt", /* 2 SIGINT */
2737 "quit", /* 3 SIGQUIT */
2738 "illegal instruction", /* 4 SIGILL */
2739 "trace trap", /* 5 SIGTRAP */
2740 "abort termination", /* 6 SIGABRT */
2741 "SIGEMT", /* 7 SIGEMT */
2742 "floating point exception", /* 8 SIGFPE */
2743 "kill", /* 9 SIGKILL */
2744 "bus error", /* 10 SIGBUS */
2745 "segmentation violation", /* 11 SIGSEGV */
2746 "bad argument to system call", /* 12 SIGSYS */
2747 "write on a pipe with no reader", /* 13 SIGPIPE */
2748 "alarm clock", /* 14 SIGALRM */
2749 "software termination signal", /* 15 SIGTERM */
2750 "user defined signal 1", /* 16 SIGUSR1 */
2751 "user defined signal 2", /* 17 SIGUSR2 */
2752 "child stopped or terminated", /* 18 SIGCLD */
2753 "power-fail restart", /* 19 SIGPWR */
2754 "window size changed", /* 20 SIGWINCH */
2755 "undefined", /* 21 */
2756 "pollable event occured", /* 22 SIGPOLL */
2757 "sendable stop signal not from tty", /* 23 SIGSTOP */
2758 "stop signal from tty", /* 24 SIGSTP */
2759 "continue a stopped process", /* 25 SIGCONT */
2760 "attempted background tty read", /* 26 SIGTTIN */
2761 "attempted background tty write", /* 27 SIGTTOU */
2762 "undefined", /* 28 */
2763 "undefined", /* 29 */
2764 "undefined", /* 30 */
2765 "undefined", /* 31 */
2766 "undefined", /* 32 */
2767 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2768 "I/O is possible", /* 34 SIGIO */
2769 "exceeded cpu time limit", /* 35 SIGXCPU */
2770 "exceeded file size limit", /* 36 SIGXFSZ */
2771 "virtual time alarm", /* 37 SIGVTALRM */
2772 "profiling time alarm", /* 38 SIGPROF */
2773 "undefined", /* 39 */
2774 "file record locks revoked", /* 40 SIGLOST */
2775 "undefined", /* 41 */
2776 "undefined", /* 42 */
2777 "undefined", /* 43 */
2778 "undefined", /* 44 */
2779 "undefined", /* 45 */
2780 "undefined", /* 46 */
2781 "undefined", /* 47 */
2782 "undefined", /* 48 */
2783 "undefined", /* 49 */
2784 "undefined", /* 50 */
2785 "undefined", /* 51 */
2786 "undefined", /* 52 */
2787 "undefined", /* 53 */
2788 "undefined", /* 54 */
2789 "undefined", /* 55 */
2790 "undefined", /* 56 */
2791 "undefined", /* 57 */
2792 "undefined", /* 58 */
2793 "undefined", /* 59 */
2794 "undefined", /* 60 */
2795 "undefined", /* 61 */
2796 "undefined", /* 62 */
2797 "undefined", /* 63 */
2798 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2804 /* Directory routines for systems that don't have them. */
2806 #ifdef SYSV_SYSTEM_DIR
2813 register DIR *dirp
; /* stream from opendir */
2815 sys_close (dirp
->dd_fd
);
2816 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2817 xfree ((char *) dirp
);
2819 #endif /* not AIX */
2820 #endif /* SYSV_SYSTEM_DIR */
2822 #ifdef NONSYSTEM_DIR_LIBRARY
2826 char *filename
; /* name of directory */
2828 register DIR *dirp
; /* -> malloc'ed storage */
2829 register int fd
; /* file descriptor for read */
2830 struct stat sbuf
; /* result of fstat */
2832 fd
= sys_open (filename
, 0);
2837 if (fstat (fd
, &sbuf
) < 0
2838 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2839 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2843 return 0; /* bad luck today */
2848 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2855 register DIR *dirp
; /* stream from opendir */
2857 sys_close (dirp
->dd_fd
);
2858 xfree ((char *) dirp
);
2866 ino_t od_ino
; /* inode */
2867 char od_name
[DIRSIZ
]; /* filename */
2869 #endif /* not VMS */
2871 struct direct dir_static
; /* simulated directory contents */
2876 register DIR *dirp
; /* stream from opendir */
2879 register struct olddir
*dp
; /* -> directory data */
2881 register struct dir$_name
*dp
; /* -> directory data */
2882 register struct dir$_version
*dv
; /* -> version data */
2887 if (dirp
->dd_loc
>= dirp
->dd_size
)
2888 dirp
->dd_loc
= dirp
->dd_size
= 0;
2890 if (dirp
->dd_size
== 0 /* refill buffer */
2891 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2895 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
2896 dirp
->dd_loc
+= sizeof (struct olddir
);
2898 if (dp
->od_ino
!= 0) /* not deleted entry */
2900 dir_static
.d_ino
= dp
->od_ino
;
2901 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
2902 dir_static
.d_name
[DIRSIZ
] = '\0';
2903 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2904 dir_static
.d_reclen
= sizeof (struct direct
)
2906 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2907 return &dir_static
; /* -> simulated structure */
2910 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2911 if (dirp
->dd_loc
== 0)
2912 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
2913 : dp
->dir$b_namecount
;
2914 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
2915 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2916 dir_static
.d_namlen
= dp
->dir$b_namecount
;
2917 dir_static
.d_reclen
= sizeof (struct direct
)
2919 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2920 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2921 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
2922 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
2929 /* readdirver is just like readdir except it returns all versions of a file
2930 as separate entries. */
2935 register DIR *dirp
; /* stream from opendir */
2937 register struct dir$_name
*dp
; /* -> directory data */
2938 register struct dir$_version
*dv
; /* -> version data */
2940 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
2941 dirp
->dd_loc
= dirp
->dd_size
= 0;
2943 if (dirp
->dd_size
== 0 /* refill buffer */
2944 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2947 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2948 if (dirp
->dd_loc
== 0)
2949 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
2950 : dp
->dir$b_namecount
;
2951 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
2952 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2953 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
2954 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2955 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2956 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
2957 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2958 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
2964 #endif /* NONSYSTEM_DIR_LIBRARY */
2966 /* Functions for VMS */
2968 #include "vms-pwd.h"
2973 /* Return as a string the VMS error string pertaining to STATUS.
2974 Reuses the same static buffer each time it is called. */
2978 int status
; /* VMS status code */
2982 static char buf
[257];
2984 bufadr
[0] = sizeof buf
- 1;
2985 bufadr
[1] = (int) buf
;
2986 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
2987 return "untranslatable VMS error status";
2995 /* The following is necessary because 'access' emulation by VMS C (2.0) does
2996 * not work correctly. (It also doesn't work well in version 2.3.)
3001 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3002 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3006 unsigned short s_buflen
;
3007 unsigned short s_code
;
3009 unsigned short *s_retlenadr
;
3013 #define buflen s.s_buflen
3014 #define code s.s_code
3015 #define bufadr s.s_bufadr
3016 #define retlenadr s.s_retlenadr
3018 #define R_OK 4 /* test for read permission */
3019 #define W_OK 2 /* test for write permission */
3020 #define X_OK 1 /* test for execute (search) permission */
3021 #define F_OK 0 /* test for presence of file */
3024 sys_access (path
, mode
)
3028 static char *user
= NULL
;
3031 /* translate possible directory spec into .DIR file name, so brain-dead
3032 * access can treat the directory like a file. */
3033 if (directory_file_name (path
, dir_fn
))
3037 return access (path
, mode
);
3038 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3044 unsigned short int dummy
;
3046 static int constant
= ACL$C_FILE
;
3047 DESCRIPTOR (path_desc
, path
);
3048 DESCRIPTOR (user_desc
, user
);
3052 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3055 acces
|= CHP$M_READ
;
3057 acces
|= CHP$M_WRITE
;
3058 itemlst
[0].buflen
= sizeof (int);
3059 itemlst
[0].code
= CHP$_FLAGS
;
3060 itemlst
[0].bufadr
= (char *) &flags
;
3061 itemlst
[0].retlenadr
= &dummy
;
3062 itemlst
[1].buflen
= sizeof (int);
3063 itemlst
[1].code
= CHP$_ACCESS
;
3064 itemlst
[1].bufadr
= (char *) &acces
;
3065 itemlst
[1].retlenadr
= &dummy
;
3066 itemlst
[2].end
= CHP$_END
;
3067 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3068 return stat
== SS$_NORMAL
? 0 : -1;
3072 #else /* not VMS4_4 */
3075 #define ACE$M_WRITE 2
3076 #define ACE$C_KEYID 1
3078 static unsigned short memid
, grpid
;
3079 static unsigned int uic
;
3081 /* Called from init_sys_modes, so it happens not very often
3082 but at least each time Emacs is loaded. */
3083 sys_access_reinit ()
3089 sys_access (filename
, type
)
3095 int status
, size
, i
, typecode
, acl_controlled
;
3096 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3097 union prvdef prvmask
;
3099 /* Get UIC and GRP values for protection checking. */
3102 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3105 memid
= uic
& 0xFFFF;
3109 if (type
!= 2) /* not checking write access */
3110 return access (filename
, type
);
3112 /* Check write protection. */
3114 #define CHECKPRIV(bit) (prvmask.bit)
3115 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3117 /* Find privilege bits */
3118 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3120 error ("Unable to find privileges: %s", vmserrstr (status
));
3121 if (CHECKPRIV (PRV$V_BYPASS
))
3122 return 0; /* BYPASS enabled */
3124 fab
.fab$b_fac
= FAB$M_GET
;
3125 fab
.fab$l_fna
= filename
;
3126 fab
.fab$b_fns
= strlen (filename
);
3127 fab
.fab$l_xab
= &xab
;
3128 xab
= cc$rms_xabpro
;
3129 xab
.xab$l_aclbuf
= aclbuf
;
3130 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3131 status
= SYS$
OPEN (&fab
, 0, 0);
3134 SYS$
CLOSE (&fab
, 0, 0);
3135 /* Check system access */
3136 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
3138 /* Check ACL entries, if any */
3140 if (xab
.xab$w_acllen
> 0)
3143 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3144 while (*aclptr
&& aclptr
< aclend
)
3146 size
= (*aclptr
& 0xff) / 4;
3147 typecode
= (*aclptr
>> 8) & 0xff;
3148 if (typecode
== ACE$C_KEYID
)
3149 for (i
= size
- 1; i
> 1; i
--)
3150 if (aclptr
[i
] == uic
)
3153 if (aclptr
[1] & ACE$M_WRITE
)
3154 return 0; /* Write access through ACL */
3156 aclptr
= &aclptr
[size
];
3158 if (acl_controlled
) /* ACL specified, prohibits write access */
3161 /* No ACL entries specified, check normal protection */
3162 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3164 if (WRITEABLE (XAB$V_GRP
) &&
3165 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3166 return 0; /* Group writeable */
3167 if (WRITEABLE (XAB$V_OWN
) &&
3168 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3169 return 0; /* Owner writeable */
3171 return -1; /* Not writeable */
3173 #endif /* not VMS4_4 */
3176 static char vtbuf
[NAM$C_MAXRSS
+1];
3178 /* translate a vms file spec to a unix path */
3180 sys_translate_vms (vfile
)
3191 /* leading device or logical name is a root directory */
3192 if (p
= strchr (vfile
, ':'))
3201 if (*p
== '[' || *p
== '<')
3203 while (*++vfile
!= *p
+ 2)
3207 if (vfile
[-1] == *p
)
3230 static char utbuf
[NAM$C_MAXRSS
+1];
3232 /* translate a unix path to a VMS file spec */
3234 sys_translate_unix (ufile
)
3257 if (index (&ufile
[1], '/'))
3264 if (index (&ufile
[1], '/'))
3271 if (strncmp (ufile
, "./", 2) == 0)
3278 ufile
++; /* skip the dot */
3279 if (index (&ufile
[1], '/'))
3284 else if (strncmp (ufile
, "../", 3) == 0)
3292 ufile
+= 2; /* skip the dots */
3293 if (index (&ufile
[1], '/'))
3318 extern char *getcwd ();
3320 #define MAXPATHLEN 1024
3322 ptr
= xmalloc (MAXPATHLEN
);
3323 getcwd (ptr
, MAXPATHLEN
);
3324 strcpy (pathname
, ptr
);
3332 long item_code
= JPI$_OWNER
;
3333 unsigned long parent_id
;
3336 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3339 vaxc$errno
= status
;
3349 return (getgid () << 16) | getuid ();
3353 sys_read (fildes
, buf
, nbyte
)
3358 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3363 sys_write (fildes
, buf
, nbyte
)
3368 register int nwrote
, rtnval
= 0;
3370 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3376 return rtnval
? rtnval
: -1;
3377 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3378 return rtnval
? rtnval
: -1;
3379 return (rtnval
+ nwrote
);
3384 * VAX/VMS VAX C RTL really loses. It insists that records
3385 * end with a newline (carriage return) character, and if they
3386 * don't it adds one (nice of it isn't it!)
3388 * Thus we do this stupidity below.
3392 sys_write (fildes
, buf
, nbytes
)
3395 unsigned int nbytes
;
3402 fstat (fildes
, &st
);
3408 /* Handle fixed-length files with carriage control. */
3409 if (st
.st_fab_rfm
== FAB$C_FIX
3410 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3412 len
= st
.st_fab_mrs
;
3413 retval
= write (fildes
, p
, min (len
, nbytes
));
3416 retval
++; /* This skips the implied carriage control */
3420 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3421 while (*e
!= '\n' && e
> p
) e
--;
3422 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3423 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3425 retval
= write (fildes
, p
, len
);
3436 /* Create file NEW copying its attributes from file OLD. If
3437 OLD is 0 or does not exist, create based on the value of
3440 /* Protection value the file should ultimately have.
3441 Set by create_copy_attrs, and use by rename_sansversions. */
3442 static unsigned short int fab_final_pro
;
3445 creat_copy_attrs (old
, new)
3448 struct FAB fab
= cc$rms_fab
;
3449 struct XABPRO xabpro
;
3450 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3451 extern int vms_stmlf_recfm
;
3455 fab
.fab$b_fac
= FAB$M_GET
;
3456 fab
.fab$l_fna
= old
;
3457 fab
.fab$b_fns
= strlen (old
);
3458 fab
.fab$l_xab
= (char *) &xabpro
;
3459 xabpro
= cc$rms_xabpro
;
3460 xabpro
.xab$l_aclbuf
= aclbuf
;
3461 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3462 /* Call $OPEN to fill in the fab & xabpro fields. */
3463 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3465 SYS$
CLOSE (&fab
, 0, 0);
3466 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3467 if (xabpro
.xab$w_acllen
> 0)
3469 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3470 /* If the acl buffer was too short, redo open with longer one.
3471 Wouldn't need to do this if there were some system imposed
3472 limit on the size of an ACL, but I can't find any such. */
3474 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3475 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3476 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3477 SYS$
CLOSE (&fab
, 0, 0);
3483 xabpro
.xab$l_aclbuf
= 0;
3488 fab
.fab$l_fna
= new;
3489 fab
.fab$b_fns
= strlen (new);
3493 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3494 fab
.fab$b_rat
= FAB$M_CR
;
3497 /* Set the file protections such that we will be able to manipulate
3498 this file. Once we are done writing and renaming it, we will set
3499 the protections back. */
3501 fab_final_pro
= xabpro
.xab$w_pro
;
3503 SYS$
SETDFPROT (0, &fab_final_pro
);
3504 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3506 /* Create the new file with either default attrs or attrs copied
3508 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3510 SYS$
CLOSE (&fab
, 0, 0);
3511 /* As this is a "replacement" for creat, return a file descriptor
3512 opened for writing. */
3513 return open (new, O_WRONLY
);
3518 #include <varargs.h>
3521 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3525 sys_creat (va_alist
)
3528 va_list list_incrementor
;
3531 int rfd
; /* related file descriptor */
3532 int fd
; /* Our new file descriptor */
3539 extern int vms_stmlf_recfm
;
3542 va_start (list_incrementor
);
3543 name
= va_arg (list_incrementor
, char *);
3544 mode
= va_arg (list_incrementor
, int);
3546 rfd
= va_arg (list_incrementor
, int);
3547 va_end (list_incrementor
);
3550 /* Use information from the related file descriptor to set record
3551 format of the newly created file. */
3552 fstat (rfd
, &st_buf
);
3553 switch (st_buf
.st_fab_rfm
)
3556 strcpy (rfm
, "rfm = fix");
3557 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3558 strcpy (rat
, "rat = ");
3559 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3561 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3562 strcat (rat
, "ftn");
3563 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3564 strcat (rat
, "prn");
3565 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3566 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3567 strcat (rat
, ", blk");
3569 strcat (rat
, "blk");
3570 return creat (name
, 0, rfm
, rat
, mrs
);
3573 strcpy (rfm
, "rfm = vfc");
3574 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3575 strcpy (rat
, "rat = ");
3576 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3578 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3579 strcat (rat
, "ftn");
3580 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3581 strcat (rat
, "prn");
3582 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3583 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3584 strcat (rat
, ", blk");
3586 strcat (rat
, "blk");
3587 return creat (name
, 0, rfm
, rat
, fsz
);
3590 strcpy (rfm
, "rfm = stm");
3594 strcpy (rfm
, "rfm = stmcr");
3598 strcpy (rfm
, "rfm = stmlf");
3602 strcpy (rfm
, "rfm = udf");
3606 strcpy (rfm
, "rfm = var");
3609 strcpy (rat
, "rat = ");
3610 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3612 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3613 strcat (rat
, "ftn");
3614 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3615 strcat (rat
, "prn");
3616 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3617 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3618 strcat (rat
, ", blk");
3620 strcat (rat
, "blk");
3624 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3625 strcpy (rat
, "rat=cr");
3627 /* Until the VAX C RTL fixes the many bugs with modes, always use
3628 mode 0 to get the user's default protection. */
3629 fd
= creat (name
, 0, rfm
, rat
);
3630 if (fd
< 0 && errno
== EEXIST
)
3632 if (unlink (name
) < 0)
3633 report_file_error ("delete", build_string (name
));
3634 fd
= creat (name
, 0, rfm
, rat
);
3640 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3641 sys_fwrite (ptr
, size
, num
, fp
)
3642 register char * ptr
;
3645 register int tot
= num
* size
;
3652 * The VMS C library routine creat actually creates a new version of an
3653 * existing file rather than truncating the old version. There are times
3654 * when this is not the desired behavior, for instance, when writing an
3655 * auto save file (you only want one version), or when you don't have
3656 * write permission in the directory containing the file (but the file
3657 * itself is writable). Hence this routine, which is equivalent to
3658 * "close (creat (fn, 0));" on Unix if fn already exists.
3664 struct FAB xfab
= cc$rms_fab
;
3665 struct RAB xrab
= cc$rms_rab
;
3668 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3669 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3670 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3671 xfab
.fab$l_fna
= fn
;
3672 xfab
.fab$b_fns
= strlen (fn
);
3673 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3675 xrab
.rab$l_fab
= &xfab
;
3677 /* This gibberish opens the file, positions to the first record, and
3678 deletes all records from there until the end of file. */
3679 if ((SYS$
OPEN (&xfab
) & 01) == 01)
3681 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
3682 (SYS$
FIND (&xrab
) & 01) == 01 &&
3683 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
3694 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3695 SYSPRV or a readable SYSUAF.DAT. */
3701 * Routine to read the VMS User Authorization File and return
3702 * a specific user's record.
3705 static struct UAF retuaf
;
3708 get_uaf_name (uname
)
3715 uaf_fab
= cc$rms_fab
;
3716 uaf_rab
= cc$rms_rab
;
3717 /* initialize fab fields */
3718 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3719 uaf_fab
.fab$b_fns
= 21;
3720 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3721 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3722 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3723 /* initialize rab fields */
3724 uaf_rab
.rab$l_fab
= &uaf_fab
;
3725 /* open the User Authorization File */
3726 status
= SYS$
OPEN (&uaf_fab
);
3730 vaxc$errno
= status
;
3733 status
= SYS$
CONNECT (&uaf_rab
);
3737 vaxc$errno
= status
;
3740 /* read the requested record - index is in uname */
3741 uaf_rab
.rab$l_kbf
= uname
;
3742 uaf_rab
.rab$b_ksz
= strlen (uname
);
3743 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3744 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3745 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3746 status
= SYS$
GET (&uaf_rab
);
3750 vaxc$errno
= status
;
3753 /* close the User Authorization File */
3754 status
= SYS$
DISCONNECT (&uaf_rab
);
3758 vaxc$errno
= status
;
3761 status
= SYS$
CLOSE (&uaf_fab
);
3765 vaxc$errno
= status
;
3779 uaf_fab
= cc$rms_fab
;
3780 uaf_rab
= cc$rms_rab
;
3781 /* initialize fab fields */
3782 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3783 uaf_fab
.fab$b_fns
= 21;
3784 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3785 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3786 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3787 /* initialize rab fields */
3788 uaf_rab
.rab$l_fab
= &uaf_fab
;
3789 /* open the User Authorization File */
3790 status
= SYS$
OPEN (&uaf_fab
);
3794 vaxc$errno
= status
;
3797 status
= SYS$
CONNECT (&uaf_rab
);
3801 vaxc$errno
= status
;
3804 /* read the requested record - index is in uic */
3805 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3806 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3807 uaf_rab
.rab$b_ksz
= sizeof uic
;
3808 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3809 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3810 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3811 status
= SYS$
GET (&uaf_rab
);
3815 vaxc$errno
= status
;
3818 /* close the User Authorization File */
3819 status
= SYS$
DISCONNECT (&uaf_rab
);
3823 vaxc$errno
= status
;
3826 status
= SYS$
CLOSE (&uaf_fab
);
3830 vaxc$errno
= status
;
3836 static struct passwd retpw
;
3844 /* copy these out first because if the username is 32 chars, the next
3845 section will overwrite the first byte of the UIC */
3846 retpw
.pw_uid
= up
->uaf$w_mem
;
3847 retpw
.pw_gid
= up
->uaf$w_grp
;
3849 /* I suppose this is not the best sytle, to possibly overwrite one
3850 byte beyond the end of the field, but what the heck... */
3851 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3852 while (ptr
[-1] == ' ')
3855 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3857 /* the rest of these are counted ascii strings */
3858 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3859 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3860 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3861 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3862 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3863 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3864 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3865 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3869 #else /* not READ_SYSUAF */
3870 static struct passwd retpw
;
3871 #endif /* not READ_SYSUAF */
3882 unsigned char * full
;
3883 #endif /* READ_SYSUAF */
3888 if ('a' <= *ptr
&& *ptr
<= 'z')
3893 if (!(up
= get_uaf_name (name
)))
3895 return cnv_uaf_pw (up
);
3897 if (strcmp (name
, getenv ("USER")) == 0)
3899 retpw
.pw_uid
= getuid ();
3900 retpw
.pw_gid
= getgid ();
3901 strcpy (retpw
.pw_name
, name
);
3902 if (full
= egetenv ("FULLNAME"))
3903 strcpy (retpw
.pw_gecos
, full
);
3905 *retpw
.pw_gecos
= '\0';
3906 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
3907 *retpw
.pw_shell
= '\0';
3912 #endif /* not READ_SYSUAF */
3922 if (!(up
= get_uaf_uic (uid
)))
3924 return cnv_uaf_pw (up
);
3926 if (uid
== sys_getuid ())
3927 return getpwnam (egetenv ("USER"));
3930 #endif /* not READ_SYSUAF */
3933 /* return total address space available to the current process. This is
3934 the sum of the current p0 size, p1 size and free page table entries
3939 unsigned long free_pages
;
3940 unsigned long frep0va
;
3941 unsigned long frep1va
;
3944 item_code
= JPI$_FREPTECNT
;
3945 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
3948 vaxc$errno
= status
;
3953 item_code
= JPI$_FREP0VA
;
3954 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
3957 vaxc$errno
= status
;
3960 item_code
= JPI$_FREP1VA
;
3961 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
3964 vaxc$errno
= status
;
3968 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
3971 define_logical_name (varname
, string
)
3975 struct dsc$descriptor_s strdsc
=
3976 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
3977 struct dsc$descriptor_s envdsc
=
3978 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3979 struct dsc$descriptor_s lnmdsc
=
3980 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3982 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
3985 delete_logical_name (varname
)
3988 struct dsc$descriptor_s envdsc
=
3989 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3990 struct dsc$descriptor_s lnmdsc
=
3991 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3993 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4004 error ("execvp system call not implemented");
4012 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4013 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4014 char from_esn
[NAM$C_MAXRSS
];
4015 char to_esn
[NAM$C_MAXRSS
];
4017 from_fab
.fab$l_fna
= from
;
4018 from_fab
.fab$b_fns
= strlen (from
);
4019 from_fab
.fab$l_nam
= &from_nam
;
4020 from_fab
.fab$l_fop
= FAB$M_NAM
;
4022 from_nam
.nam$l_esa
= from_esn
;
4023 from_nam
.nam$b_ess
= sizeof from_esn
;
4025 to_fab
.fab$l_fna
= to
;
4026 to_fab
.fab$b_fns
= strlen (to
);
4027 to_fab
.fab$l_nam
= &to_nam
;
4028 to_fab
.fab$l_fop
= FAB$M_NAM
;
4030 to_nam
.nam$l_esa
= to_esn
;
4031 to_nam
.nam$b_ess
= sizeof to_esn
;
4033 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4039 if (status
== RMS$_DEV
)
4043 vaxc$errno
= status
;
4048 /* This function renames a file like `rename', but it strips
4049 the version number from the "to" filename, such that the "to" file is
4050 will always be a new version. It also sets the file protection once it is
4051 finished. The protection that we will use is stored in fab_final_pro,
4052 and was set when we did a creat_copy_attrs to create the file that we
4055 We could use the chmod function, but Eunichs uses 3 bits per user category
4056 to describe the protection, and VMS uses 4 (write and delete are seperate
4057 bits). To maintain portability, the VMS implementation of `chmod' wires
4058 the W and D bits together. */
4061 static struct fibdef fib
; /* We need this initialized to zero */
4062 char vms_file_written
[NAM$C_MAXRSS
];
4065 rename_sans_version (from
,to
)
4072 struct FAB to_fab
= cc$rms_fab
;
4073 struct NAM to_nam
= cc$rms_nam
;
4074 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4075 struct dsc$descriptor fib_attr
[2]
4076 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4077 char to_esn
[NAM$C_MAXRSS
];
4079 $
DESCRIPTOR (disk
,to_esn
);
4081 to_fab
.fab$l_fna
= to
;
4082 to_fab
.fab$b_fns
= strlen (to
);
4083 to_fab
.fab$l_nam
= &to_nam
;
4084 to_fab
.fab$l_fop
= FAB$M_NAM
;
4086 to_nam
.nam$l_esa
= to_esn
;
4087 to_nam
.nam$b_ess
= sizeof to_esn
;
4089 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4091 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4092 *(to_nam
.nam$l_ver
) = '\0';
4094 stat
= rename (from
, to_esn
);
4098 strcpy (vms_file_written
, to_esn
);
4100 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4101 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4103 /* Now set the file protection to the correct value */
4104 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4106 /* Copy these fields into the fib */
4107 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4108 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4109 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4111 SYS$
CLOSE (&to_fab
, 0, 0);
4113 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4116 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4117 0, 0, 0, &fib_attr
, 0);
4120 stat
= SYS$
DASSGN (chan
);
4123 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4133 unsigned short fid
[3];
4134 char esa
[NAM$C_MAXRSS
];
4137 fab
.fab$l_fop
= FAB$M_OFP
;
4138 fab
.fab$l_fna
= file
;
4139 fab
.fab$b_fns
= strlen (file
);
4140 fab
.fab$l_nam
= &nam
;
4143 nam
.nam$l_esa
= esa
;
4144 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4146 status
= SYS$
PARSE (&fab
);
4147 if ((status
& 1) == 0)
4150 vaxc$errno
= status
;
4153 status
= SYS$
SEARCH (&fab
);
4154 if ((status
& 1) == 0)
4157 vaxc$errno
= status
;
4161 fid
[0] = nam
.nam$w_fid
[0];
4162 fid
[1] = nam
.nam$w_fid
[1];
4163 fid
[2] = nam
.nam$w_fid
[2];
4165 fab
.fab$l_fna
= new;
4166 fab
.fab$b_fns
= strlen (new);
4168 status
= SYS$
PARSE (&fab
);
4169 if ((status
& 1) == 0)
4172 vaxc$errno
= status
;
4176 nam
.nam$w_fid
[0] = fid
[0];
4177 nam
.nam$w_fid
[1] = fid
[1];
4178 nam
.nam$w_fid
[2] = fid
[2];
4180 nam
.nam$l_esa
= nam
.nam$l_name
;
4181 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4183 status
= SYS$
ENTER (&fab
);
4184 if ((status
& 1) == 0)
4187 vaxc$errno
= status
;
4197 printf ("%s not yet implemented\r\n", badfunc
);
4205 /* Arrange to return a range centered on zero. */
4206 return rand () - (1 << 30);
4217 /* Called from init_sys_modes. */
4222 /* If we're not on an HFT we shouldn't do any of this. We determine
4223 if we are on an HFT by trying to get an HFT error code. If this
4224 call fails, we're not on an HFT. */
4226 if (ioctl (0, HFQERROR
, &junk
) < 0)
4228 #else /* not IBMR2AIX */
4229 if (ioctl (0, HFQEIO
, 0) < 0)
4231 #endif /* not IBMR2AIX */
4233 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4234 as the rubout key's ASCII code. Here this is changed. The bug is that
4235 there's no way to determine the old mapping, so in reset_sys_modes
4236 we need to assume that the normal map had been present. Of course, this
4237 code also doesn't help if on a terminal emulator which doesn't understand
4241 struct hfkeymap keymap
;
4243 buf
.hf_bufp
= (char *)&keymap
;
4244 buf
.hf_buflen
= sizeof (keymap
);
4245 keymap
.hf_nkeys
= 2;
4246 keymap
.hfkey
[0].hf_kpos
= 15;
4247 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4249 keymap
.hfkey
[0].hf_keyidh
= '<';
4250 #else /* not IBMR2AIX */
4251 keymap
.hfkey
[0].hf_page
= '<';
4252 #endif /* not IBMR2AIX */
4253 keymap
.hfkey
[0].hf_char
= 127;
4254 keymap
.hfkey
[1].hf_kpos
= 15;
4255 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4257 keymap
.hfkey
[1].hf_keyidh
= '<';
4258 #else /* not IBMR2AIX */
4259 keymap
.hfkey
[1].hf_page
= '<';
4260 #endif /* not IBMR2AIX */
4261 keymap
.hfkey
[1].hf_char
= 127;
4262 hftctl (0, HFSKBD
, &buf
);
4264 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4266 line_ins_del_ok
= char_ins_del_ok
= 0;
4269 /* Reset the rubout key to backspace. */
4274 struct hfkeymap keymap
;
4278 if (ioctl (0, HFQERROR
, &junk
) < 0)
4280 #else /* not IBMR2AIX */
4281 if (ioctl (0, HFQEIO
, 0) < 0)
4283 #endif /* not IBMR2AIX */
4285 buf
.hf_bufp
= (char *)&keymap
;
4286 buf
.hf_buflen
= sizeof (keymap
);
4287 keymap
.hf_nkeys
= 2;
4288 keymap
.hfkey
[0].hf_kpos
= 15;
4289 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4291 keymap
.hfkey
[0].hf_keyidh
= '<';
4292 #else /* not IBMR2AIX */
4293 keymap
.hfkey
[0].hf_page
= '<';
4294 #endif /* not IBMR2AIX */
4295 keymap
.hfkey
[0].hf_char
= 8;
4296 keymap
.hfkey
[1].hf_kpos
= 15;
4297 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4299 keymap
.hfkey
[1].hf_keyidh
= '<';
4300 #else /* not IBMR2AIX */
4301 keymap
.hfkey
[1].hf_page
= '<';
4302 #endif /* not IBMR2AIX */
4303 keymap
.hfkey
[1].hf_char
= 8;
4304 hftctl (0, HFSKBD
, &buf
);