1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 1986, 1987, 1988, 1992 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);
318 /* Exit if the process has terminated. */
319 if (!synch_process_alive
)
321 /* Otherwise wait 1 second or until a signal comes in. */
322 signal (SIGALRM
, wait_for_termination_signal
);
326 signal (SIGALRM
, SIG_IGN
);
328 #else /* not subprocesses */
330 if (kill (pid
, 0) < 0)
336 if (status
== pid
|| status
== -1)
339 #endif /* not subprocesses */
346 * flush any pending output
347 * (may flush input as well; it does not matter the way we use it)
350 flush_pending_output (channel
)
354 /* If we try this, we get hit with SIGTTIN, because
355 the child's tty belongs to the child's pgrp. */
358 ioctl (channel
, TCFLSH
, 1);
362 /* 3rd arg should be ignored
363 but some 4.2 kernels actually want the address of an int
364 and nonzero means something different. */
365 ioctl (channel
, TIOCFLUSH
, &zero
);
372 /* Set up the terminal at the other end of a pseudo-terminal that
373 we will be controlling an inferior through.
374 It should not echo or do line-editing, since that is done
375 in Emacs. No padding needed for insertion into an Emacs buffer. */
377 child_setup_tty (out
)
382 EMACS_GET_TTY (out
, &s
);
384 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
385 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
386 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
387 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
388 /* No output delays */
389 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
390 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
391 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
393 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
396 /* Said to be unnecesary: */
397 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
398 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
401 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
402 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
403 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
404 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
407 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
411 /* AIX enhanced edit loses NULs, so disable it */
414 s
.main
.c_iflag
&= ~ASCEDIT
;
416 /* Also, PTY overloads NUL and BREAK.
417 don't ignore break, but don't signal either, so it looks like NUL. */
418 s
.main
.c_iflag
&= ~IGNBRK
;
419 s
.main
.c_iflag
&= ~BRKINT
;
420 /* QUIT and INTR work better as signals, so disable character forms */
421 s
.main
.c_cc
[VQUIT
] = 0377;
422 s
.main
.c_cc
[VINTR
] = 0377;
423 s
.main
.c_cc
[VEOL
] = 0377;
424 s
.main
.c_lflag
&= ~ISIG
;
425 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
428 #else /* not HAVE_TERMIO */
430 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
432 s
.main
.sg_erase
= 0377;
433 s
.main
.sg_kill
= 0377;
435 #endif /* not HAVE_TERMIO */
437 EMACS_SET_TTY (out
, &s
, 0);
446 ioctl (out
, FIOASYNC
, &zero
);
452 #endif /* subprocesses */
458 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
461 /* Record a signal code and the handler for it. */
465 SIGTYPE (*handler
) ();
468 /* Suspend the Emacs process; give terminal to its superior. */
473 /* "Foster" parentage allows emacs to return to a subprocess that attached
474 to the current emacs as a cheaper than starting a whole new process. This
475 is set up by KEPTEDITOR.COM. */
476 unsigned long parent_id
, foster_parent_id
;
479 fpid_string
= getenv ("EMACS_PARENT_PID");
480 if (fpid_string
!= NULL
)
482 sscanf (fpid_string
, "%x", &foster_parent_id
);
483 if (foster_parent_id
!= 0)
484 parent_id
= foster_parent_id
;
486 parent_id
= getppid ();
489 parent_id
= getppid ();
491 xfree (fpid_string
); /* On VMS, this was malloc'd */
493 if (parent_id
&& parent_id
!= 0xffffffff)
495 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
496 int status
= LIB$
ATTACH (&parent_id
) & 1;
497 signal (SIGINT
, oldsig
);
506 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
507 d_prompt
.a
= "Emacs: "; /* Just a reminder */
508 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
515 EMACS_KILLPG (getpgrp (0), SIGTSTP
);
517 #else /* No SIGTSTP */
518 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
519 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
520 kill (getpid (), SIGQUIT
);
522 #else /* No SIGTSTP or USG_JOBCTRL */
524 /* On a system where suspending is not implemented,
525 instead fork a subshell and let it talk directly to the terminal
528 struct save_signal saved_handlers
[5];
530 saved_handlers
[0].code
= SIGINT
;
531 saved_handlers
[1].code
= SIGQUIT
;
532 saved_handlers
[2].code
= SIGTERM
;
534 saved_handlers
[3].code
= SIGIO
;
535 saved_handlers
[4].code
= 0;
537 saved_handlers
[3].code
= 0;
541 error ("Can't spawn subshell");
546 sh
= (char *) egetenv ("SHELL");
549 /* Use our buffer's default directory for the subshell. */
555 /* mentioning current_buffer->buffer would mean including buffer.h,
556 which somehow wedges the hp compiler. So instead... */
558 dir
= intern ("default-directory");
560 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
562 dir
= Fsymbol_value (dir
);
563 if (XTYPE (dir
) != Lisp_String
)
566 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
567 len
= XSTRING (dir
)->size
;
568 bcopy (XSTRING (dir
)->data
, str
, len
);
569 if (str
[len
- 1] != '/') str
[len
++] = '/';
575 close_process_descs (); /* Close Emacs's pipes/ptys */
580 extern int emacs_priority
;
583 nice (-emacs_priority
);
588 write (1, "Can't execute subshell", 22);
592 save_signal_handlers (saved_handlers
);
593 wait_for_termination (pid
);
594 restore_signal_handlers (saved_handlers
);
596 #endif /* no USG_JOBCTRL */
597 #endif /* no SIGTSTP */
601 save_signal_handlers (saved_handlers
)
602 struct save_signal
*saved_handlers
;
604 while (saved_handlers
->code
)
606 saved_handlers
->handler
607 = (SIGTYPE (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
612 restore_signal_handlers (saved_handlers
)
613 struct save_signal
*saved_handlers
;
615 while (saved_handlers
->code
)
617 signal (saved_handlers
->code
, saved_handlers
->handler
);
629 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
639 #ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
644 sigunblock (sigmask (SIGWINCH
));
646 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
648 interrupts_deferred
= 0;
654 sigblock (sigmask (SIGWINCH
));
656 fcntl (0, F_SETFL
, old_fcntl_flags
);
657 interrupts_deferred
= 1;
660 #else /* no FASYNC */
661 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
666 ioctl (0, FIOASYNC
, &on
);
667 interrupts_deferred
= 0;
674 ioctl (0, FIOASYNC
, &off
);
675 interrupts_deferred
= 1;
678 #else /* not FASYNC, not STRIDE */
682 croak ("request_sigio");
687 croak ("unrequest_sigio");
694 /* The initial tty mode bits */
695 struct emacs_tty old_tty
;
697 int term_initted
; /* 1 if outer tty status has been recorded */
700 /* BSD 4.1 needs to keep track of the lmode bits in order to start
707 #endif /* F_SETOWN */
709 /* This may also be defined in stdio,
710 but if so, this does no harm,
711 and using the same name avoids wasting the other one's space. */
713 #if defined (USG) || defined (DGUX)
714 unsigned char _sobuf
[BUFSIZ
+8];
720 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
723 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
728 struct emacs_tty tty
;
732 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
733 extern int (*interrupt_signal
) ();
742 input_ef
= get_kbd_event_flag ();
743 /* LIB$GET_EF (&input_ef); */
744 SYS$
CLREF (input_ef
);
747 timer_ef
= get_timer_event_flag ();
748 /* LIB$GET_EF (&timer_ef); */
749 SYS$
CLREF (timer_ef
);
753 LIB$
GET_EF (&process_ef
);
754 SYS$
CLREF (process_ef
);
756 if (input_ef
/ 32 != process_ef
/ 32)
757 croak ("Input and process event flags in different clusters.");
759 if (input_ef
/ 32 != timer_ef
/ 32)
760 croak ("Input and timer event flags in different clusters.");
762 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
763 ((unsigned) 1 << (process_ef
% 32));
765 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
766 ((unsigned) 1 << (timer_ef
% 32));
768 sys_access_reinit ();
772 EMACS_GET_TTY (input_fd
, &old_tty
);
774 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
778 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
779 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
780 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
782 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
784 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
785 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
787 tty
.main
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
789 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
792 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
794 tty
.main
.c_iflag
&= ~IXANY
;
798 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
799 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
801 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
805 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
806 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
809 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
810 /* Set up C-g for both SIGQUIT and SIGINT.
811 We don't know which we will get, but we handle both alike
812 so which one it really gives us does not matter. */
813 tty
.main
.c_cc
[VQUIT
] = quit_char
;
814 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
815 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
817 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
820 #if defined (mips) || defined (HAVE_TCATTR)
822 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
825 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
827 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
828 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
830 #endif /* mips or HAVE_TCATTR */
833 /* AIX enhanced edit loses NULs, so disable it */
835 tty
.main
.c_iflag
&= ~ASCEDIT
;
837 tty
.main
.c_cc
[VSTRT
] = 255;
838 tty
.main
.c_cc
[VSTOP
] = 255;
839 tty
.main
.c_cc
[VSUSP
] = 255;
840 tty
.main
.c_cc
[VDSUSP
] = 255;
841 #endif /* IBMR2AIX */
842 /* Also, PTY overloads NUL and BREAK.
843 don't ignore break, but don't signal either, so it looks like NUL.
844 This really serves a purpose only if running in an XTERM window
845 or via TELNET or the like, but does no harm elsewhere. */
846 tty
.main
.c_iflag
&= ~IGNBRK
;
847 tty
.main
.c_iflag
&= ~BRKINT
;
849 #else /* if not HAVE_TERMIO */
851 tty
.main
.tt_char
|= TT$M_NOECHO
;
853 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
855 tty
.main
.tt_char
|= TT$M_TTSYNC
;
857 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
858 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
859 #else /* not VMS (BSD, that is) */
860 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
862 tty
.main
.sg_flags
|= ANYP
;
863 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
864 #endif /* not VMS (BSD, that is) */
865 #endif /* not HAVE_TERMIO */
867 /* If going to use CBREAK mode, we must request C-g to interrupt
868 and turn off start and stop chars, etc. If not going to use
869 CBREAK mode, do this anyway so as to turn off local flow
870 control for user coming over network on 4.2; in this case,
871 only t_stopc and t_startc really matter. */
874 /* Note: if not using CBREAK mode, it makes no difference how we
876 tty
.tchars
= new_tchars
;
877 tty
.tchars
.t_intrc
= quit_char
;
880 tty
.tchars
.t_startc
= '\021';
881 tty
.tchars
.t_stopc
= '\023';
884 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
890 #define LNOFLSH 0100000
893 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
899 #endif /* TIOCGETC */
900 #endif /* not HAVE_TERMIO */
903 tty
.ltchars
= new_ltchars
;
904 #endif /* TIOCGLTC */
906 EMACS_SET_TTY (input_fd
, &tty
, 0);
908 /* This code added to insure that, if flow-control is not to be used,
909 we have an unlocked terminal at the start. */
912 if (!flow_control
) ioctl (0, TCXONC
, 1);
916 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
924 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
925 to be only LF. This is the way that is done. */
928 if (ioctl (1, HFTGETID
, &tty
) != -1)
929 write (1, "\033[20l", 5);
935 /* Appears to do nothing when in PASTHRU mode.
936 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
937 interrupt_signal, oob_chars, 0, 0, 0, 0);
944 #ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
947 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
948 fcntl (0, F_SETOWN
, getpid ());
951 #endif /* F_GETOWN */
959 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
963 /* This symbol is defined on recent USG systems.
964 Someone says without this call USG won't really buffer the file
965 even with a call to setbuf. */
966 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
968 setbuf (stdout
, _sobuf
);
970 set_terminal_modes ();
971 if (term_initted
&& no_redraw_on_reenter
)
973 if (display_completed
)
974 direct_output_forward_char (0);
980 if (FRAMEP (Vterminal_frame
))
981 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
988 /* Return nonzero if safe to use tabs in output.
989 At the time this is called, init_sys_modes has not been done yet. */
993 struct emacs_tty tty
;
995 EMACS_GET_TTY (input_fd
, &tty
);
996 return EMACS_TTY_TABS_OK (&tty
);
999 /* Get terminal size from system.
1000 Store number of lines into *heightp and width into *widthp.
1001 If zero or a negative number is stored, the value is not valid. */
1003 get_frame_size (widthp
, heightp
)
1004 int *widthp
, *heightp
;
1010 struct winsize size
;
1012 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1013 *widthp
= *heightp
= 0;
1016 *widthp
= size
.ws_col
;
1017 *heightp
= size
.ws_row
;
1023 /* SunOS - style. */
1024 struct ttysize size
;
1026 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1027 *widthp
= *heightp
= 0;
1030 *widthp
= size
.ts_cols
;
1031 *heightp
= size
.ts_lines
;
1037 struct sensemode tty
;
1039 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1040 &tty
.class, 12, 0, 0, 0, 0);
1041 *widthp
= tty
.scr_wid
;
1042 *heightp
= tty
.scr_len
;
1044 #else /* system doesn't know size */
1049 #endif /* not VMS */
1050 #endif /* not SunOS-style */
1051 #endif /* not BSD-style */
1055 /* Prepare the terminal for exiting Emacs; move the cursor to the
1056 bottom of the frame, turn off interrupt-driven I/O, etc. */
1066 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1068 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1069 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1070 /* clear_end_of_line may move the cursor */
1071 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1074 /* HFT devices normally use ^J as a LF/CR. We forced it to
1075 do the LF only. Now, we need to reset it. */
1078 if (ioctl (1, HFTGETID
, &tty
) != -1)
1079 write (1, "\033[20h", 5);
1083 reset_terminal_modes ();
1087 /* Avoid possible loss of output when changing terminal modes. */
1088 fsync (fileno (stdout
));
1093 #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */
1094 if (interrupt_input
)
1097 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1099 #endif /* F_SETOWN */
1100 #endif /* F_SETFL */
1102 if (interrupt_input
)
1106 while (! EMACS_SET_TTY (input_fd
, &old_tty
, 0) && errno
== EINTR
)
1116 /* Set up the proper status flags for use of a pty. */
1121 /* I'm told that TOICREMOTE does not mean control chars
1122 "can't be sent" but rather that they don't have
1123 input-editing or signaling effects.
1124 That should be good, because we have other ways
1125 to do those things in Emacs.
1126 However, telnet mode seems not to work on 4.2.
1127 So TIOCREMOTE is turned off now. */
1129 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1130 will hang. In particular, the "timeout" feature (which
1131 causes a read to return if there is no data available)
1132 does this. Also it is known that telnet mode will hang
1133 in such a way that Emacs must be stopped (perhaps this
1134 is the same problem).
1136 If TIOCREMOTE is turned off, then there is a bug in
1137 hp-ux which sometimes loses data. Apparently the
1138 code which blocks the master process when the internal
1139 buffer fills up does not work. Other than this,
1140 though, everything else seems to work fine.
1142 Since the latter lossage is more benign, we may as well
1143 lose that way. -- cph */
1148 ioctl (fd
, FIONBIO
, &on
);
1153 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1154 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1155 /* cause EMACS not to die when it should, i.e., when its own controlling */
1156 /* tty goes away. I've complained to the AIX developers, and they may */
1157 /* change this behavior, but I'm not going to hold my breath. */
1158 signal (SIGHUP
, SIG_IGN
);
1161 #endif /* HAVE_PTYS */
1165 /* Assigning an input channel is done at the start of Emacs execution.
1166 This is called each time Emacs is resumed, also, but does nothing
1167 because input_chain is no longer zero. */
1175 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1181 /* Deassigning the input channel is done before exiting. */
1185 return SYS$
DASSGN (input_fd
);
1190 /* Request reading one character into the keyboard buffer.
1191 This is done as soon as the buffer becomes empty. */
1196 extern kbd_input_ast ();
1198 waiting_for_ast
= 0;
1200 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1201 &input_iosb
, kbd_input_ast
, 1,
1202 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1207 /* Ast routine that is called when keyboard input comes in
1208 in accord with the SYS$QIO above. */
1212 register int c
= -1;
1213 int old_errno
= errno
;
1214 extern EMACS_TIME
*input_available_clear_time
;
1216 if (waiting_for_ast
)
1217 SYS$
SETEF (input_ef
);
1218 waiting_for_ast
= 0;
1221 if (input_count
== 25)
1223 printf ("Ast # %d,", input_count
);
1224 printf (" iosb = %x, %x, %x, %x",
1225 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1228 if (input_iosb
.offset
)
1232 printf (", char = 0%o", c
);
1244 struct input_event e
;
1245 e
.kind
= ascii_keystroke
;
1246 XSET (e
.code
, Lisp_Int
, c
);
1248 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1250 e
.frame_or_window
= Qnil
;
1252 kbd_buffer_store_event (&e
);
1254 if (input_available_clear_time
)
1255 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1259 /* Wait until there is something in kbd_buffer. */
1261 wait_for_kbd_input ()
1263 extern int have_process_input
, process_exited
;
1265 /* If already something, avoid doing system calls. */
1266 if (detect_input_pending ())
1270 /* Clear a flag, and tell ast routine above to set it. */
1271 SYS$
CLREF (input_ef
);
1272 waiting_for_ast
= 1;
1273 /* Check for timing error: ast happened while we were doing that. */
1274 if (!detect_input_pending ())
1276 /* No timing error: wait for flag to be set. */
1277 set_waiting_for_input (0);
1278 SYS$
WFLOR (input_ef
, input_eflist
);
1279 clear_waiting_for_input (0);
1280 if (!detect_input_pending ())
1281 /* Check for subprocess input availability */
1283 int dsp
= have_process_input
|| process_exited
;
1285 SYS$
CLREF (process_ef
);
1286 if (have_process_input
)
1287 process_command_input ();
1292 update_mode_lines
++;
1293 redisplay_preserve_echo_area ();
1297 waiting_for_ast
= 0;
1300 /* Get rid of any pending QIO, when we are about to suspend
1301 or when we want to throw away pending input.
1302 We wait for a positive sign that the AST routine has run
1303 and therefore there is no I/O request queued when we return.
1304 SYS$SETAST is used to avoid a timing error. */
1309 printf ("At end_kbd_input.\n");
1313 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1315 SYS$
CANCEL (input_fd
);
1320 /* Clear a flag, and tell ast routine above to set it. */
1321 SYS$
CLREF (input_ef
);
1322 waiting_for_ast
= 1;
1324 SYS$
CANCEL (input_fd
);
1326 SYS$
WAITFR (input_ef
);
1327 waiting_for_ast
= 0;
1330 /* Wait for either input available or time interval expiry. */
1332 input_wait_timeout (timeval
)
1333 int timeval
; /* Time to wait, in seconds */
1336 static int zero
= 0;
1337 static int large
= -10000000;
1339 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1341 /* If already something, avoid doing system calls. */
1342 if (detect_input_pending ())
1346 /* Clear a flag, and tell ast routine above to set it. */
1347 SYS$
CLREF (input_ef
);
1348 waiting_for_ast
= 1;
1349 /* Check for timing error: ast happened while we were doing that. */
1350 if (!detect_input_pending ())
1352 /* No timing error: wait for flag to be set. */
1354 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1355 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1357 waiting_for_ast
= 0;
1360 /* The standard `sleep' routine works some other way
1361 and it stops working if you have ever quit out of it.
1362 This one continues to work. */
1368 static int zero
= 0;
1369 static int large
= -10000000;
1371 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1374 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1375 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1390 croak ("request sigio");
1395 croak ("unrequest sigio");
1400 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1405 #ifndef SYSTEM_MALLOC
1412 /* Some systems that cannot dump also cannot implement these. */
1415 * Return the address of the start of the text segment prior to
1416 * doing an unexec. After unexec the return value is undefined.
1417 * See crt0.c for further explanation and _start.
1421 #ifndef CANNOT_UNEXEC
1426 return ((char *) TEXT_START
);
1430 return ((char *) csrt
);
1431 #else /* not GOULD */
1432 extern int _start ();
1433 return ((char *) _start
);
1435 #endif /* TEXT_START */
1437 #endif /* not CANNOT_UNEXEC */
1440 * Return the address of the start of the data segment prior to
1441 * doing an unexec. After unexec the return value is undefined.
1442 * See crt0.c for further information and definition of data_start.
1444 * Apparently, on BSD systems this is etext at startup. On
1445 * USG systems (swapping) this is highly mmu dependent and
1446 * is also dependent on whether or not the program is running
1447 * with shared text. Generally there is a (possibly large)
1448 * gap between end of text and start of data with shared text.
1450 * On Uniplus+ systems with shared text, data starts at a
1451 * fixed address. Each port (from a given oem) is generally
1452 * different, and the specific value of the start of data can
1453 * be obtained via the UniPlus+ specific "uvar" system call,
1454 * however the method outlined in crt0.c seems to be more portable.
1456 * Probably what will have to happen when a USG unexec is available,
1457 * at least on UniPlus, is temacs will have to be made unshared so
1458 * that text and data are contiguous. Then once loadup is complete,
1459 * unexec will produce a shared executable where the data can be
1460 * at the normal shared text boundry and the startofdata variable
1461 * will be patched by unexec to the correct value.
1469 return ((char *) DATA_START
);
1471 #ifdef ORDINARY_LINK
1473 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1474 * data_start isn't defined. We take the address of environ, which
1475 * is known to live at or near the start of the system crt0.c, and
1476 * we don't sweat the handful of bytes that might lose.
1478 extern char **environ
;
1480 return((char *) &environ
);
1482 extern int data_start
;
1483 return ((char *) &data_start
);
1484 #endif /* ORDINARY_LINK */
1485 #endif /* DATA_START */
1487 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1490 /* Some systems that cannot dump also cannot implement these. */
1493 * Return the address of the end of the text segment prior to
1494 * doing an unexec. After unexec the return value is undefined.
1501 return ((char *) TEXT_END
);
1504 return ((char *) &etext
);
1509 * Return the address of the end of the data segment prior to
1510 * doing an unexec. After unexec the return value is undefined.
1517 return ((char *) DATA_END
);
1520 return ((char *) &edata
);
1524 #endif /* not CANNOT_DUMP */
1526 /* Get_system_name returns as its value
1527 a string for the Lisp function system-name to return. */
1533 /* Can't have this within the function since `static' is #defined to
1534 nothing for some USG systems. */
1536 #ifdef HAVE_GETHOSTNAME
1537 static char get_system_name_name
[256];
1538 #else /* not HAVE_GETHOSTNAME */
1539 static struct utsname get_system_name_name
;
1540 #endif /* not HAVE_GETHOSTNAME */
1547 #ifdef HAVE_GETHOSTNAME
1548 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1549 return get_system_name_name
;
1550 #else /* not HAVE_GETHOSTNAME */
1551 uname (&get_system_name_name
);
1552 return (get_system_name_name
.nodename
);
1553 #endif /* not HAVE_GETHOSTNAME */
1557 #else /* not USG, not 4.1 */
1558 static char system_name_saved
[32];
1561 if ((sp
= egetenv ("SYS$NODE")) == 0)
1567 if ((end
= index (sp
, ':')) != 0)
1570 strcpy (system_name_saved
, sp
);
1572 gethostname (system_name_saved
, sizeof (system_name_saved
));
1573 #endif /* not VMS */
1574 return system_name_saved
;
1575 #endif /* not USG, not 4.1 */
1576 #endif /* not USG */
1580 #ifndef HAVE_GETHOSTNAME
1581 void gethostname(buf
, len
)
1586 s
= getenv ("SYS$NODE");
1590 strncpy (buf
, s
, len
- 2);
1591 buf
[len
- 1] = '\0';
1593 } /* static void gethostname */
1594 #endif /* ! HAVE_GETHOSTNAME */
1601 #ifdef HAVE_X_WINDOWS
1602 /* Cause explanatory error message at compile time,
1603 since the select emulation is not good enough for X. */
1604 int *x
= &x_windows_lose_if_no_select_system_call
;
1607 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1608 * Only checks read descriptors.
1610 /* How long to wait between checking fds in select */
1611 #define SELECT_PAUSE 1
1614 /* For longjmp'ing back to read_input_waiting. */
1616 jmp_buf read_alarm_throw
;
1618 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1619 The read_socket_hook function sets this to 1 while it is waiting. */
1621 int read_alarm_should_throw
;
1629 #else /* not BSD4_1 */
1630 signal (SIGALRM
, SIG_IGN
);
1631 #endif /* not BSD4_1 */
1632 if (read_alarm_should_throw
)
1633 longjmp (read_alarm_throw
, 1);
1636 /* Only rfds are checked. */
1638 select (nfds
, rfds
, wfds
, efds
, timeout
)
1640 int *rfds
, *wfds
, *efds
, *timeout
;
1642 int ravail
= 0, orfds
= 0, old_alarm
;
1643 int timeoutval
= timeout
? *timeout
: 100000;
1644 int *local_timeout
= &timeoutval
;
1645 extern int proc_buffered_char
[];
1646 #ifndef subprocesses
1647 int process_tick
= 0, update_tick
= 0;
1649 extern int process_tick
, update_tick
;
1651 SIGTYPE (*old_trap
) ();
1664 /* If we are looking only for the terminal, with no timeout,
1665 just read it and wait -- that's more efficient. */
1666 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1668 if (! detect_input_pending ())
1669 read_input_waiting ();
1674 /* Once a second, till the timer expires, check all the flagged read
1675 * descriptors to see if any input is available. If there is some then
1676 * set the corresponding bit in the return copy of rfds.
1680 register int to_check
, bit
, fd
;
1684 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1688 int avail
= 0, status
= 0;
1691 avail
= detect_input_pending (); /* Special keyboard handler */
1695 status
= ioctl (fd
, FIONREAD
, &avail
);
1696 #else /* no FIONREAD */
1697 /* Hoping it will return -1 if nothing available
1698 or 0 if all 0 chars requested are read. */
1699 if (proc_buffered_char
[fd
] >= 0)
1703 avail
= read (fd
, &buf
, 1);
1705 proc_buffered_char
[fd
] = buf
;
1707 #endif /* no FIONREAD */
1709 if (status
>= 0 && avail
> 0)
1717 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
1719 old_alarm
= alarm (0);
1720 old_trap
= signal (SIGALRM
, select_alarm
);
1722 alarm (SELECT_PAUSE
);
1723 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1724 while (select_alarmed
== 0 && *local_timeout
!= 0
1725 && process_tick
== update_tick
)
1727 /* If we are interested in terminal input,
1728 wait by reading the terminal.
1729 That makes instant wakeup for terminal input at least. */
1732 read_input_waiting ();
1733 if (detect_input_pending ())
1739 (*local_timeout
) -= SELECT_PAUSE
;
1740 /* Reset the old alarm if there was one */
1742 signal (SIGALRM
, old_trap
);
1745 /* Reset or forge an interrupt for the original handler. */
1746 old_alarm
-= SELECT_PAUSE
;
1748 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
1752 if (*local_timeout
== 0) /* Stop on timer being cleared */
1758 /* Read keyboard input into the standard buffer,
1759 waiting for at least one character. */
1761 /* Make all keyboard buffers much bigger when using X windows. */
1762 #ifdef HAVE_X_WINDOWS
1763 #define BUFFER_SIZE_FACTOR 16
1765 #define BUFFER_SIZE_FACTOR 1
1768 read_input_waiting ()
1770 char buf
[256 * BUFFER_SIZE_FACTOR
];
1771 struct input_event e
;
1773 extern int quit_char
;
1775 if (read_socket_hook
)
1777 read_alarm_should_throw
= 0;
1778 if (! setjmp (read_alarm_throw
))
1779 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
1784 nread
= read (fileno (stdin
), buf
, 1);
1786 /* Scan the chars for C-g and store them in kbd_buffer. */
1787 e
.kind
= ascii_keystroke
;
1788 e
.frame_or_window
= selected_frame
;
1789 for (i
= 0; i
< nread
; i
++)
1791 XSET (e
.code
, Lisp_Int
, buf
[i
]);
1792 kbd_buffer_store_event (&e
);
1793 /* Don't look at input that follows a C-g too closely.
1794 This reduces lossage due to autorepeat on C-g. */
1795 if (buf
[i
] == quit_char
)
1800 #endif /* not HAVE_SELECT */
1801 #endif /* not VMS */
1805 * Partially emulate 4.2 open call.
1806 * open is defined as this in 4.1.
1808 * - added by Michael Bloom @ Citicorp/TTI
1813 sys_open (path
, oflag
, mode
)
1817 if (oflag
& O_CREAT
)
1818 return creat (path
, mode
);
1820 return open (path
, oflag
);
1827 lmode
= LINTRUP
| lmode
;
1828 ioctl (0, TIOCLSET
, &lmode
);
1835 lmode
= ~LINTRUP
& lmode
;
1836 ioctl (0, TIOCLSET
, &lmode
);
1843 interrupts_deferred
= 0;
1850 interrupts_deferred
= 1;
1853 /* still inside #ifdef BSD4_1 */
1856 int sigheld
; /* Mask of held signals */
1861 sigheld
|= sigbit (signum
);
1868 sigheld
|= sigbit (signum
);
1874 sigheld
&= ~sigbit (signum
);
1878 sigfree () /* Free all held signals */
1881 for (i
= 0; i
< NSIG
; i
++)
1882 if (sigheld
& sigbit (i
))
1889 return 1 << (i
- 1);
1891 #endif /* subprocesses */
1894 /* POSIX signals support - DJB */
1895 /* Anyone with POSIX signals should have ANSI C declarations */
1897 #ifdef POSIX_SIGNALS
1899 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
1900 static struct sigaction new_action
, old_action
;
1904 #ifdef POSIX_SIGNALS
1905 sigemptyset (&signal_empty_mask
);
1906 sigfillset (&signal_full_mask
);
1910 int (*signal_handler_t
) ();
1913 sys_signal (int signal_number
, signal_handler_t action
)
1916 /* This gets us restartable system calls for efficiency.
1917 The "else" code will works as well. */
1918 return (berk_signal (signal_number
, action
));
1920 sigemptyset (&new_action
.sa_mask
);
1921 new_action
.sa_handler
= action
;
1922 new_action
.sa_flags
= NULL
;
1923 sigaction (signal_number
, &new_action
, &old_action
);
1924 return (old_action
.sa_handler
);
1929 /* If we're compiling with GCC, we don't need this function, since it
1930 can be written as a macro. */
1932 sys_sigmask (int sig
)
1935 sigemptyset (&mask
);
1936 sigaddset (&mask
, sig
);
1942 sys_sigpause (sigset_t new_mask
)
1944 /* pause emulating berk sigpause... */
1945 sigsuspend (&new_mask
);
1949 /* I'd like to have these guys return pointers to the mask storage in here,
1950 but there'd be trouble if the code was saving multiple masks. I'll be
1951 safe and pass the structure. It normally won't be more than 2 bytes
1955 sys_sigblock (sigset_t new_mask
)
1958 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
1963 sys_sigunblock (sigset_t new_mask
)
1966 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
1971 sys_sigsetmask (sigset_t new_mask
)
1974 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1978 #endif /* POSIX_SIGNALS */
1985 register int length
;
1989 long max_str
= 65535;
1991 while (length
> max_str
) {
1992 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1997 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1999 while (length
-- > 0)
2001 #endif /* not VMS */
2004 /* Saying `void' requires a declaration, above, where bcopy is used
2005 and that declaration causes pain for systems where bcopy is a macro. */
2006 bcopy (b1
, b2
, length
)
2009 register int length
;
2012 long max_str
= 65535;
2014 while (length
> max_str
) {
2015 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2021 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2023 while (length
-- > 0)
2025 #endif /* not VMS */
2029 bcmp (b1
, b2
, length
) /* This could be a macro! */
2032 register int length
;
2035 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2036 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2038 return STR$
COMPARE (&src1
, &src2
);
2040 while (length
-- > 0)
2045 #endif /* not VMS */
2047 #endif /* not BSTRING */
2052 * The BSD random returns numbers in the range of
2053 * 0 to 2e31 - 1. The USG rand returns numbers in the
2054 * range of 0 to 2e15 - 1. This is probably not significant
2061 /* Arrange to return a range centered on zero. */
2062 return (rand () << 15) + rand () - (1 << 29);
2076 /* Arrange to return a range centered on zero. */
2077 return (rand () << 15) + rand () - (1 << 29);
2088 #ifdef WRONG_NAME_INSQUE
2101 /* If any place else asks for the TERM variable,
2102 allow it to be overridden with the EMACS_TERM variable
2103 before attempting to translate the logical name TERM. As a last
2104 resort, ask for VAX C's special idea of the TERM variable. */
2111 static char buf
[256];
2112 static struct dsc$descriptor_s equiv
2113 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2114 static struct dsc$descriptor_s d_name
2115 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2118 if (!strcmp (name
, "TERM"))
2120 val
= (char *) getenv ("EMACS_TERM");
2125 d_name
.dsc$w_length
= strlen (name
);
2126 d_name
.dsc$a_pointer
= name
;
2127 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2129 char *str
= (char *) xmalloc (eqlen
+ 1);
2130 bcopy (buf
, str
, eqlen
);
2132 /* This is a storage leak, but a pain to fix. With luck,
2133 no one will ever notice. */
2136 return (char *) getenv (name
);
2141 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2142 to force a call on the debugger from within the image. */
2147 LIB$
SIGNAL (SS$_DEBUG
);
2153 #ifdef LINK_CRTL_SHARE
2154 #ifdef SHAREABLE_LIB_BUG
2155 /* Variables declared noshare and initialized in shareable libraries
2156 cannot be shared. The VMS linker incorrectly forces you to use a private
2157 version which is uninitialized... If not for this "feature", we
2158 could use the C library definition of sys_nerr and sys_errlist. */
2160 char *sys_errlist
[] =
2164 "no such file or directory",
2166 "interrupted system call",
2168 "no such device or address",
2169 "argument list too long",
2170 "exec format error",
2173 "no more processes",
2174 "not enough memory",
2175 "permission denied",
2177 "block device required",
2178 "mount devices busy",
2180 "cross-device link",
2185 "file table overflow",
2186 "too many open files",
2190 "no space left on device",
2192 "read-only file system",
2198 "vax/vms specific error code nontranslatable error"
2200 #endif /* SHAREABLE_LIB_BUG */
2201 #endif /* LINK_CRTL_SHARE */
2204 #ifdef INTERRUPTIBLE_OPEN
2208 sys_open (path
, oflag
, mode
)
2212 register int rtnval
;
2214 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2215 && (errno
== EINTR
));
2219 #endif /* INTERRUPTIBLE_OPEN */
2221 #ifdef INTERRUPTIBLE_CLOSE
2226 register int rtnval
;
2228 while ((rtnval
= close (fd
)) == -1
2229 && (errno
== EINTR
));
2233 #endif /* INTERRUPTIBLE_CLOSE */
2235 #ifdef INTERRUPTIBLE_IO
2238 sys_read (fildes
, buf
, nbyte
)
2243 register int rtnval
;
2245 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2246 && (errno
== EINTR
));
2251 sys_write (fildes
, buf
, nbyte
)
2256 register int rtnval
;
2258 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2259 && (errno
== EINTR
));
2263 #endif /* INTERRUPTIBLE_IO */
2267 * All of the following are for USG.
2269 * On USG systems the system calls are INTERRUPTIBLE by signals
2270 * that the user program has elected to catch. Thus the system call
2271 * must be retried in these cases. To handle this without massive
2272 * changes in the source code, we remap the standard system call names
2273 * to names for our own functions in sysdep.c that do the system call
2274 * with retries. Actually, for portability reasons, it is good
2275 * programming practice, as this example shows, to limit all actual
2276 * system calls to a single occurance in the source. Sure, this
2277 * adds an extra level of function call overhead but it is almost
2278 * always negligible. Fred Fish, Unisoft Systems Inc.
2281 char *sys_siglist
[NSIG
+ 1] =
2284 /* AIX has changed the signals a bit */
2285 "bogus signal", /* 0 */
2286 "hangup", /* 1 SIGHUP */
2287 "interrupt", /* 2 SIGINT */
2288 "quit", /* 3 SIGQUIT */
2289 "illegal instruction", /* 4 SIGILL */
2290 "trace trap", /* 5 SIGTRAP */
2291 "IOT instruction", /* 6 SIGIOT */
2292 "crash likely", /* 7 SIGDANGER */
2293 "floating point exception", /* 8 SIGFPE */
2294 "kill", /* 9 SIGKILL */
2295 "bus error", /* 10 SIGBUS */
2296 "segmentation violation", /* 11 SIGSEGV */
2297 "bad argument to system call", /* 12 SIGSYS */
2298 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2299 "alarm clock", /* 14 SIGALRM */
2300 "software termination signum", /* 15 SIGTERM */
2301 "user defined signal 1", /* 16 SIGUSR1 */
2302 "user defined signal 2", /* 17 SIGUSR2 */
2303 "death of a child", /* 18 SIGCLD */
2304 "power-fail restart", /* 19 SIGPWR */
2305 "bogus signal", /* 20 */
2306 "bogus signal", /* 21 */
2307 "bogus signal", /* 22 */
2308 "bogus signal", /* 23 */
2309 "bogus signal", /* 24 */
2310 "LAN I/O interrupt", /* 25 SIGAIO */
2311 "PTY I/O interrupt", /* 26 SIGPTY */
2312 "I/O intervention required", /* 27 SIGIOINT */
2313 "HFT grant", /* 28 SIGGRANT */
2314 "HFT retract", /* 29 SIGRETRACT */
2315 "HFT sound done", /* 30 SIGSOUND */
2316 "HFT input ready", /* 31 SIGMSG */
2318 "bogus signal", /* 0 */
2319 "hangup", /* 1 SIGHUP */
2320 "interrupt", /* 2 SIGINT */
2321 "quit", /* 3 SIGQUIT */
2322 "illegal instruction", /* 4 SIGILL */
2323 "trace trap", /* 5 SIGTRAP */
2324 "IOT instruction", /* 6 SIGIOT */
2325 "EMT instruction", /* 7 SIGEMT */
2326 "floating point exception", /* 8 SIGFPE */
2327 "kill", /* 9 SIGKILL */
2328 "bus error", /* 10 SIGBUS */
2329 "segmentation violation", /* 11 SIGSEGV */
2330 "bad argument to system call", /* 12 SIGSYS */
2331 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2332 "alarm clock", /* 14 SIGALRM */
2333 "software termination signum", /* 15 SIGTERM */
2334 "user defined signal 1", /* 16 SIGUSR1 */
2335 "user defined signal 2", /* 17 SIGUSR2 */
2336 "death of a child", /* 18 SIGCLD */
2337 "power-fail restart", /* 19 SIGPWR */
2338 #endif /* not AIX */
2343 * Warning, this function may not duplicate 4.2 action properly
2344 * under error conditions.
2348 /* In 4.1, param.h fails to define this. */
2349 #define MAXPATHLEN 1024
2358 char *npath
, *spath
;
2359 extern char *getcwd ();
2361 BLOCK_INPUT
; /* getcwd uses malloc */
2362 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2363 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2364 up to first slash. Should be harmless on other systems. */
2365 while (*npath
&& *npath
!= '/')
2367 strcpy (pathname
, npath
);
2368 free (spath
); /* getcwd uses malloc */
2373 #endif /* HAVE_GETWD */
2376 * Emulate rename using unlink/link. Note that this is
2377 * only partially correct. Also, doesn't enforce restriction
2378 * that files be of same type (regular->regular, dir->dir, etc).
2387 if (access (from
, 0) == 0)
2390 if (link (from
, to
) == 0)
2391 if (unlink (from
) == 0)
2402 * Substitute fork for vfork on USG flavors.
2410 #endif /* not HAVE_VFORK */
2412 #ifdef MISSING_UTIMES
2414 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2423 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2424 utimbuf structure defined anywhere but in the man page. */
2434 struct timeval tvp
[];
2437 utb
.actime
= tvp
[0].tv_sec
;
2438 utb
.modtime
= tvp
[1].tv_sec
;
2441 #endif /* IRIS_UTIME */
2447 /* HPUX curses library references perror, but as far as we know
2448 it won't be called. Anyway this definition will do for now. */
2454 #endif /* not HAVE_PERROR */
2460 * Emulate BSD dup2. First close newd if it already exists.
2461 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2462 * until we are, then close the unsuccessful ones.
2469 register int fd
, ret
;
2474 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2476 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2483 ret
= dup2 (old
,new);
2489 #endif /* not HAVE_DUP2 */
2492 * Gettimeofday. Simulate as much as possible. Only accurate
2493 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2494 * Only needed when subprocesses are defined.
2499 #ifndef HAVE_GETTIMEOFDAY
2503 gettimeofday (tp
, tzp
)
2505 struct timezone
*tzp
;
2507 extern long time ();
2509 tp
->tv_sec
= time ((long *)0);
2511 tzp
->tz_minuteswest
= -1;
2517 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2520 * This function will go away as soon as all the stubs fixed. (fnf)
2526 printf ("%s not yet implemented\r\n", badfunc
);
2535 char *sys_siglist
[NSIG
+ 1] =
2537 "null signal", /* 0 SIGNULL */
2538 "hangup", /* 1 SIGHUP */
2539 "interrupt", /* 2 SIGINT */
2540 "quit", /* 3 SIGQUIT */
2541 "illegal instruction", /* 4 SIGILL */
2542 "trace trap", /* 5 SIGTRAP */
2543 "abort termination", /* 6 SIGABRT */
2544 "SIGEMT", /* 7 SIGEMT */
2545 "floating point exception", /* 8 SIGFPE */
2546 "kill", /* 9 SIGKILL */
2547 "bus error", /* 10 SIGBUS */
2548 "segmentation violation", /* 11 SIGSEGV */
2549 "bad argument to system call", /* 12 SIGSYS */
2550 "write on a pipe with no reader", /* 13 SIGPIPE */
2551 "alarm clock", /* 14 SIGALRM */
2552 "software termination signal", /* 15 SIGTERM */
2553 "user defined signal 1", /* 16 SIGUSR1 */
2554 "user defined signal 2", /* 17 SIGUSR2 */
2555 "child stopped or terminated", /* 18 SIGCLD */
2556 "power-fail restart", /* 19 SIGPWR */
2557 "window size changed", /* 20 SIGWINCH */
2558 "undefined", /* 21 */
2559 "pollable event occured", /* 22 SIGPOLL */
2560 "sendable stop signal not from tty", /* 23 SIGSTOP */
2561 "stop signal from tty", /* 24 SIGSTP */
2562 "continue a stopped process", /* 25 SIGCONT */
2563 "attempted background tty read", /* 26 SIGTTIN */
2564 "attempted background tty write", /* 27 SIGTTOU */
2565 "undefined", /* 28 */
2566 "undefined", /* 29 */
2567 "undefined", /* 30 */
2568 "undefined", /* 31 */
2569 "undefined", /* 32 */
2570 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2571 "I/O is possible", /* 34 SIGIO */
2572 "exceeded cpu time limit", /* 35 SIGXCPU */
2573 "exceeded file size limit", /* 36 SIGXFSZ */
2574 "virtual time alarm", /* 37 SIGVTALRM */
2575 "profiling time alarm", /* 38 SIGPROF */
2576 "undefined", /* 39 */
2577 "file record locks revoked", /* 40 SIGLOST */
2578 "undefined", /* 41 */
2579 "undefined", /* 42 */
2580 "undefined", /* 43 */
2581 "undefined", /* 44 */
2582 "undefined", /* 45 */
2583 "undefined", /* 46 */
2584 "undefined", /* 47 */
2585 "undefined", /* 48 */
2586 "undefined", /* 49 */
2587 "undefined", /* 50 */
2588 "undefined", /* 51 */
2589 "undefined", /* 52 */
2590 "undefined", /* 53 */
2591 "undefined", /* 54 */
2592 "undefined", /* 55 */
2593 "undefined", /* 56 */
2594 "undefined", /* 57 */
2595 "undefined", /* 58 */
2596 "undefined", /* 59 */
2597 "undefined", /* 60 */
2598 "undefined", /* 61 */
2599 "undefined", /* 62 */
2600 "undefined", /* 63 */
2601 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2607 /* Directory routines for systems that don't have them. */
2609 #ifdef SYSV_SYSTEM_DIR
2616 register DIR *dirp
; /* stream from opendir */
2618 sys_close (dirp
->dd_fd
);
2619 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2620 xfree ((char *) dirp
);
2622 #endif /* not AIX */
2623 #endif /* SYSV_SYSTEM_DIR */
2625 #ifdef NONSYSTEM_DIR_LIBRARY
2629 char *filename
; /* name of directory */
2631 register DIR *dirp
; /* -> malloc'ed storage */
2632 register int fd
; /* file descriptor for read */
2633 struct stat sbuf
; /* result of fstat */
2635 fd
= sys_open (filename
, 0);
2640 if (fstat (fd
, &sbuf
) < 0
2641 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2642 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2646 return 0; /* bad luck today */
2651 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2658 register DIR *dirp
; /* stream from opendir */
2660 sys_close (dirp
->dd_fd
);
2661 xfree ((char *) dirp
);
2669 ino_t od_ino
; /* inode */
2670 char od_name
[DIRSIZ
]; /* filename */
2672 #endif /* not VMS */
2674 struct direct dir_static
; /* simulated directory contents */
2679 register DIR *dirp
; /* stream from opendir */
2682 register struct olddir
*dp
; /* -> directory data */
2684 register struct dir$_name
*dp
; /* -> directory data */
2685 register struct dir$_version
*dv
; /* -> version data */
2690 if (dirp
->dd_loc
>= dirp
->dd_size
)
2691 dirp
->dd_loc
= dirp
->dd_size
= 0;
2693 if (dirp
->dd_size
== 0 /* refill buffer */
2694 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2698 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
2699 dirp
->dd_loc
+= sizeof (struct olddir
);
2701 if (dp
->od_ino
!= 0) /* not deleted entry */
2703 dir_static
.d_ino
= dp
->od_ino
;
2704 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
2705 dir_static
.d_name
[DIRSIZ
] = '\0';
2706 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2707 dir_static
.d_reclen
= sizeof (struct direct
)
2709 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2710 return &dir_static
; /* -> simulated structure */
2713 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2714 if (dirp
->dd_loc
== 0)
2715 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
2716 : dp
->dir$b_namecount
;
2717 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
2718 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2719 dir_static
.d_namlen
= dp
->dir$b_namecount
;
2720 dir_static
.d_reclen
= sizeof (struct direct
)
2722 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2723 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2724 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
2725 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
2732 /* readdirver is just like readdir except it returns all versions of a file
2733 as separate entries. */
2738 register DIR *dirp
; /* stream from opendir */
2740 register struct dir$_name
*dp
; /* -> directory data */
2741 register struct dir$_version
*dv
; /* -> version data */
2743 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
2744 dirp
->dd_loc
= dirp
->dd_size
= 0;
2746 if (dirp
->dd_size
== 0 /* refill buffer */
2747 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2750 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2751 if (dirp
->dd_loc
== 0)
2752 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
2753 : dp
->dir$b_namecount
;
2754 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
2755 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2756 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
2757 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2758 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2759 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
2760 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2761 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
2767 #endif /* NONSYSTEM_DIR_LIBRARY */
2769 /* Functions for VMS */
2771 #include "vms-pwd.h"
2776 /* Return as a string the VMS error string pertaining to STATUS.
2777 Reuses the same static buffer each time it is called. */
2781 int status
; /* VMS status code */
2785 static char buf
[257];
2787 bufadr
[0] = sizeof buf
- 1;
2788 bufadr
[1] = (int) buf
;
2789 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
2790 return "untranslatable VMS error status";
2798 /* The following is necessary because 'access' emulation by VMS C (2.0) does
2799 * not work correctly. (It also doesn't work well in version 2.3.)
2804 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
2805 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
2809 unsigned short s_buflen
;
2810 unsigned short s_code
;
2812 unsigned short *s_retlenadr
;
2816 #define buflen s.s_buflen
2817 #define code s.s_code
2818 #define bufadr s.s_bufadr
2819 #define retlenadr s.s_retlenadr
2821 #define R_OK 4 /* test for read permission */
2822 #define W_OK 2 /* test for write permission */
2823 #define X_OK 1 /* test for execute (search) permission */
2824 #define F_OK 0 /* test for presence of file */
2827 sys_access (path
, mode
)
2831 static char *user
= NULL
;
2834 /* translate possible directory spec into .DIR file name, so brain-dead
2835 * access can treat the directory like a file. */
2836 if (directory_file_name (path
, dir_fn
))
2840 return access (path
, mode
);
2841 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
2847 unsigned short int dummy
;
2849 static int constant
= ACL$C_FILE
;
2850 DESCRIPTOR (path_desc
, path
);
2851 DESCRIPTOR (user_desc
, user
);
2855 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
2858 acces
|= CHP$M_READ
;
2860 acces
|= CHP$M_WRITE
;
2861 itemlst
[0].buflen
= sizeof (int);
2862 itemlst
[0].code
= CHP$_FLAGS
;
2863 itemlst
[0].bufadr
= (char *) &flags
;
2864 itemlst
[0].retlenadr
= &dummy
;
2865 itemlst
[1].buflen
= sizeof (int);
2866 itemlst
[1].code
= CHP$_ACCESS
;
2867 itemlst
[1].bufadr
= (char *) &acces
;
2868 itemlst
[1].retlenadr
= &dummy
;
2869 itemlst
[2].end
= CHP$_END
;
2870 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
2871 return stat
== SS$_NORMAL
? 0 : -1;
2875 #else /* not VMS4_4 */
2878 #define ACE$M_WRITE 2
2879 #define ACE$C_KEYID 1
2881 static unsigned short memid
, grpid
;
2882 static unsigned int uic
;
2884 /* Called from init_sys_modes, so it happens not very often
2885 but at least each time Emacs is loaded. */
2886 sys_access_reinit ()
2892 sys_access (filename
, type
)
2898 int status
, size
, i
, typecode
, acl_controlled
;
2899 unsigned int *aclptr
, *aclend
, aclbuf
[60];
2900 union prvdef prvmask
;
2902 /* Get UIC and GRP values for protection checking. */
2905 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
2908 memid
= uic
& 0xFFFF;
2912 if (type
!= 2) /* not checking write access */
2913 return access (filename
, type
);
2915 /* Check write protection. */
2917 #define CHECKPRIV(bit) (prvmask.bit)
2918 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
2920 /* Find privilege bits */
2921 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
2923 error ("Unable to find privileges: %s", vmserrstr (status
));
2924 if (CHECKPRIV (PRV$V_BYPASS
))
2925 return 0; /* BYPASS enabled */
2927 fab
.fab$b_fac
= FAB$M_GET
;
2928 fab
.fab$l_fna
= filename
;
2929 fab
.fab$b_fns
= strlen (filename
);
2930 fab
.fab$l_xab
= &xab
;
2931 xab
= cc$rms_xabpro
;
2932 xab
.xab$l_aclbuf
= aclbuf
;
2933 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
2934 status
= SYS$
OPEN (&fab
, 0, 0);
2937 SYS$
CLOSE (&fab
, 0, 0);
2938 /* Check system access */
2939 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
2941 /* Check ACL entries, if any */
2943 if (xab
.xab$w_acllen
> 0)
2946 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
2947 while (*aclptr
&& aclptr
< aclend
)
2949 size
= (*aclptr
& 0xff) / 4;
2950 typecode
= (*aclptr
>> 8) & 0xff;
2951 if (typecode
== ACE$C_KEYID
)
2952 for (i
= size
- 1; i
> 1; i
--)
2953 if (aclptr
[i
] == uic
)
2956 if (aclptr
[1] & ACE$M_WRITE
)
2957 return 0; /* Write access through ACL */
2959 aclptr
= &aclptr
[size
];
2961 if (acl_controlled
) /* ACL specified, prohibits write access */
2964 /* No ACL entries specified, check normal protection */
2965 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
2967 if (WRITEABLE (XAB$V_GRP
) &&
2968 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
2969 return 0; /* Group writeable */
2970 if (WRITEABLE (XAB$V_OWN
) &&
2971 (xab
.xab$l_uic
& 0xFFFF) == memid
)
2972 return 0; /* Owner writeable */
2974 return -1; /* Not writeable */
2976 #endif /* not VMS4_4 */
2979 static char vtbuf
[NAM$C_MAXRSS
+1];
2981 /* translate a vms file spec to a unix path */
2983 sys_translate_vms (vfile
)
2994 /* leading device or logical name is a root directory */
2995 if (p
= strchr (vfile
, ':'))
3004 if (*p
== '[' || *p
== '<')
3006 while (*++vfile
!= *p
+ 2)
3010 if (vfile
[-1] == *p
)
3033 static char utbuf
[NAM$C_MAXRSS
+1];
3035 /* translate a unix path to a VMS file spec */
3037 sys_translate_unix (ufile
)
3060 if (index (&ufile
[1], '/'))
3067 if (index (&ufile
[1], '/'))
3074 if (strncmp (ufile
, "./", 2) == 0)
3081 ufile
++; /* skip the dot */
3082 if (index (&ufile
[1], '/'))
3087 else if (strncmp (ufile
, "../", 3) == 0)
3095 ufile
+= 2; /* skip the dots */
3096 if (index (&ufile
[1], '/'))
3121 extern char *getcwd ();
3123 #define MAXPATHLEN 1024
3125 ptr
= xmalloc (MAXPATHLEN
);
3126 getcwd (ptr
, MAXPATHLEN
);
3127 strcpy (pathname
, ptr
);
3135 long item_code
= JPI$_OWNER
;
3136 unsigned long parent_id
;
3139 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3142 vaxc$errno
= status
;
3152 return (getgid () << 16) | getuid ();
3156 sys_read (fildes
, buf
, nbyte
)
3161 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3166 sys_write (fildes
, buf
, nbyte
)
3171 register int nwrote
, rtnval
= 0;
3173 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3179 return rtnval
? rtnval
: -1;
3180 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3181 return rtnval
? rtnval
: -1;
3182 return (rtnval
+ nwrote
);
3187 * VAX/VMS VAX C RTL really loses. It insists that records
3188 * end with a newline (carriage return) character, and if they
3189 * don't it adds one (nice of it isn't it!)
3191 * Thus we do this stupidity below.
3195 sys_write (fildes
, buf
, nbytes
)
3198 unsigned int nbytes
;
3205 fstat (fildes
, &st
);
3211 /* Handle fixed-length files with carriage control. */
3212 if (st
.st_fab_rfm
== FAB$C_FIX
3213 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3215 len
= st
.st_fab_mrs
;
3216 retval
= write (fildes
, p
, min (len
, nbytes
));
3219 retval
++; /* This skips the implied carriage control */
3223 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3224 while (*e
!= '\n' && e
> p
) e
--;
3225 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3226 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3228 retval
= write (fildes
, p
, len
);
3239 /* Create file NEW copying its attributes from file OLD. If
3240 OLD is 0 or does not exist, create based on the value of
3243 /* Protection value the file should ultimately have.
3244 Set by create_copy_attrs, and use by rename_sansversions. */
3245 static unsigned short int fab_final_pro
;
3248 creat_copy_attrs (old
, new)
3251 struct FAB fab
= cc$rms_fab
;
3252 struct XABPRO xabpro
;
3253 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3254 extern int vms_stmlf_recfm
;
3258 fab
.fab$b_fac
= FAB$M_GET
;
3259 fab
.fab$l_fna
= old
;
3260 fab
.fab$b_fns
= strlen (old
);
3261 fab
.fab$l_xab
= (char *) &xabpro
;
3262 xabpro
= cc$rms_xabpro
;
3263 xabpro
.xab$l_aclbuf
= aclbuf
;
3264 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3265 /* Call $OPEN to fill in the fab & xabpro fields. */
3266 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3268 SYS$
CLOSE (&fab
, 0, 0);
3269 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3270 if (xabpro
.xab$w_acllen
> 0)
3272 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3273 /* If the acl buffer was too short, redo open with longer one.
3274 Wouldn't need to do this if there were some system imposed
3275 limit on the size of an ACL, but I can't find any such. */
3277 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3278 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3279 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3280 SYS$
CLOSE (&fab
, 0, 0);
3286 xabpro
.xab$l_aclbuf
= 0;
3291 fab
.fab$l_fna
= new;
3292 fab
.fab$b_fns
= strlen (new);
3296 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3297 fab
.fab$b_rat
= FAB$M_CR
;
3300 /* Set the file protections such that we will be able to manipulate
3301 this file. Once we are done writing and renaming it, we will set
3302 the protections back. */
3304 fab_final_pro
= xabpro
.xab$w_pro
;
3306 SYS$
SETDFPROT (0, &fab_final_pro
);
3307 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3309 /* Create the new file with either default attrs or attrs copied
3311 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3313 SYS$
CLOSE (&fab
, 0, 0);
3314 /* As this is a "replacement" for creat, return a file descriptor
3315 opened for writing. */
3316 return open (new, O_WRONLY
);
3321 #include <varargs.h>
3324 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3328 sys_creat (va_alist
)
3331 va_list list_incrementor
;
3334 int rfd
; /* related file descriptor */
3335 int fd
; /* Our new file descriptor */
3342 extern int vms_stmlf_recfm
;
3345 va_start (list_incrementor
);
3346 name
= va_arg (list_incrementor
, char *);
3347 mode
= va_arg (list_incrementor
, int);
3349 rfd
= va_arg (list_incrementor
, int);
3350 va_end (list_incrementor
);
3353 /* Use information from the related file descriptor to set record
3354 format of the newly created file. */
3355 fstat (rfd
, &st_buf
);
3356 switch (st_buf
.st_fab_rfm
)
3359 strcpy (rfm
, "rfm = fix");
3360 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3361 strcpy (rat
, "rat = ");
3362 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3364 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3365 strcat (rat
, "ftn");
3366 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3367 strcat (rat
, "prn");
3368 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3369 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3370 strcat (rat
, ", blk");
3372 strcat (rat
, "blk");
3373 return creat (name
, 0, rfm
, rat
, mrs
);
3376 strcpy (rfm
, "rfm = vfc");
3377 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3378 strcpy (rat
, "rat = ");
3379 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3381 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3382 strcat (rat
, "ftn");
3383 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3384 strcat (rat
, "prn");
3385 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3386 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3387 strcat (rat
, ", blk");
3389 strcat (rat
, "blk");
3390 return creat (name
, 0, rfm
, rat
, fsz
);
3393 strcpy (rfm
, "rfm = stm");
3397 strcpy (rfm
, "rfm = stmcr");
3401 strcpy (rfm
, "rfm = stmlf");
3405 strcpy (rfm
, "rfm = udf");
3409 strcpy (rfm
, "rfm = var");
3412 strcpy (rat
, "rat = ");
3413 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3415 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3416 strcat (rat
, "ftn");
3417 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3418 strcat (rat
, "prn");
3419 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3420 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3421 strcat (rat
, ", blk");
3423 strcat (rat
, "blk");
3427 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3428 strcpy (rat
, "rat=cr");
3430 /* Until the VAX C RTL fixes the many bugs with modes, always use
3431 mode 0 to get the user's default protection. */
3432 fd
= creat (name
, 0, rfm
, rat
);
3433 if (fd
< 0 && errno
== EEXIST
)
3435 if (unlink (name
) < 0)
3436 report_file_error ("delete", build_string (name
));
3437 fd
= creat (name
, 0, rfm
, rat
);
3443 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3444 sys_fwrite (ptr
, size
, num
, fp
)
3445 register char * ptr
;
3448 register int tot
= num
* size
;
3455 * The VMS C library routine creat actually creates a new version of an
3456 * existing file rather than truncating the old version. There are times
3457 * when this is not the desired behavior, for instance, when writing an
3458 * auto save file (you only want one version), or when you don't have
3459 * write permission in the directory containing the file (but the file
3460 * itself is writable). Hence this routine, which is equivalent to
3461 * "close (creat (fn, 0));" on Unix if fn already exists.
3467 struct FAB xfab
= cc$rms_fab
;
3468 struct RAB xrab
= cc$rms_rab
;
3471 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3472 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3473 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3474 xfab
.fab$l_fna
= fn
;
3475 xfab
.fab$b_fns
= strlen (fn
);
3476 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3478 xrab
.rab$l_fab
= &xfab
;
3480 /* This gibberish opens the file, positions to the first record, and
3481 deletes all records from there until the end of file. */
3482 if ((SYS$
OPEN (&xfab
) & 01) == 01)
3484 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
3485 (SYS$
FIND (&xrab
) & 01) == 01 &&
3486 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
3497 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3498 SYSPRV or a readable SYSUAF.DAT. */
3504 * Routine to read the VMS User Authorization File and return
3505 * a specific user's record.
3508 static struct UAF retuaf
;
3511 get_uaf_name (uname
)
3518 uaf_fab
= cc$rms_fab
;
3519 uaf_rab
= cc$rms_rab
;
3520 /* initialize fab fields */
3521 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3522 uaf_fab
.fab$b_fns
= 21;
3523 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3524 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3525 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3526 /* initialize rab fields */
3527 uaf_rab
.rab$l_fab
= &uaf_fab
;
3528 /* open the User Authorization File */
3529 status
= SYS$
OPEN (&uaf_fab
);
3533 vaxc$errno
= status
;
3536 status
= SYS$
CONNECT (&uaf_rab
);
3540 vaxc$errno
= status
;
3543 /* read the requested record - index is in uname */
3544 uaf_rab
.rab$l_kbf
= uname
;
3545 uaf_rab
.rab$b_ksz
= strlen (uname
);
3546 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3547 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3548 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3549 status
= SYS$
GET (&uaf_rab
);
3553 vaxc$errno
= status
;
3556 /* close the User Authorization File */
3557 status
= SYS$
DISCONNECT (&uaf_rab
);
3561 vaxc$errno
= status
;
3564 status
= SYS$
CLOSE (&uaf_fab
);
3568 vaxc$errno
= status
;
3582 uaf_fab
= cc$rms_fab
;
3583 uaf_rab
= cc$rms_rab
;
3584 /* initialize fab fields */
3585 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3586 uaf_fab
.fab$b_fns
= 21;
3587 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3588 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3589 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3590 /* initialize rab fields */
3591 uaf_rab
.rab$l_fab
= &uaf_fab
;
3592 /* open the User Authorization File */
3593 status
= SYS$
OPEN (&uaf_fab
);
3597 vaxc$errno
= status
;
3600 status
= SYS$
CONNECT (&uaf_rab
);
3604 vaxc$errno
= status
;
3607 /* read the requested record - index is in uic */
3608 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3609 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3610 uaf_rab
.rab$b_ksz
= sizeof uic
;
3611 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3612 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3613 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3614 status
= SYS$
GET (&uaf_rab
);
3618 vaxc$errno
= status
;
3621 /* close the User Authorization File */
3622 status
= SYS$
DISCONNECT (&uaf_rab
);
3626 vaxc$errno
= status
;
3629 status
= SYS$
CLOSE (&uaf_fab
);
3633 vaxc$errno
= status
;
3639 static struct passwd retpw
;
3647 /* copy these out first because if the username is 32 chars, the next
3648 section will overwrite the first byte of the UIC */
3649 retpw
.pw_uid
= up
->uaf$w_mem
;
3650 retpw
.pw_gid
= up
->uaf$w_grp
;
3652 /* I suppose this is not the best sytle, to possibly overwrite one
3653 byte beyond the end of the field, but what the heck... */
3654 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3655 while (ptr
[-1] == ' ')
3658 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3660 /* the rest of these are counted ascii strings */
3661 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3662 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3663 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3664 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3665 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3666 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3667 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3668 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3672 #else /* not READ_SYSUAF */
3673 static struct passwd retpw
;
3674 #endif /* not READ_SYSUAF */
3685 unsigned char * full
;
3686 #endif /* READ_SYSUAF */
3691 if ('a' <= *ptr
&& *ptr
<= 'z')
3696 if (!(up
= get_uaf_name (name
)))
3698 return cnv_uaf_pw (up
);
3700 if (strcmp (name
, getenv ("USER")) == 0)
3702 retpw
.pw_uid
= getuid ();
3703 retpw
.pw_gid
= getgid ();
3704 strcpy (retpw
.pw_name
, name
);
3705 if (full
= egetenv ("FULLNAME"))
3706 strcpy (retpw
.pw_gecos
, full
);
3708 *retpw
.pw_gecos
= '\0';
3709 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
3710 *retpw
.pw_shell
= '\0';
3715 #endif /* not READ_SYSUAF */
3725 if (!(up
= get_uaf_uic (uid
)))
3727 return cnv_uaf_pw (up
);
3729 if (uid
== sys_getuid ())
3730 return getpwnam (egetenv ("USER"));
3733 #endif /* not READ_SYSUAF */
3736 /* return total address space available to the current process. This is
3737 the sum of the current p0 size, p1 size and free page table entries
3742 unsigned long free_pages
;
3743 unsigned long frep0va
;
3744 unsigned long frep1va
;
3747 item_code
= JPI$_FREPTECNT
;
3748 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
3751 vaxc$errno
= status
;
3756 item_code
= JPI$_FREP0VA
;
3757 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
3760 vaxc$errno
= status
;
3763 item_code
= JPI$_FREP1VA
;
3764 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
3767 vaxc$errno
= status
;
3771 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
3774 define_logical_name (varname
, string
)
3778 struct dsc$descriptor_s strdsc
=
3779 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
3780 struct dsc$descriptor_s envdsc
=
3781 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3782 struct dsc$descriptor_s lnmdsc
=
3783 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3785 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
3788 delete_logical_name (varname
)
3791 struct dsc$descriptor_s envdsc
=
3792 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3793 struct dsc$descriptor_s lnmdsc
=
3794 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3796 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
3807 error ("execvp system call not implemented");
3815 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
3816 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
3817 char from_esn
[NAM$C_MAXRSS
];
3818 char to_esn
[NAM$C_MAXRSS
];
3820 from_fab
.fab$l_fna
= from
;
3821 from_fab
.fab$b_fns
= strlen (from
);
3822 from_fab
.fab$l_nam
= &from_nam
;
3823 from_fab
.fab$l_fop
= FAB$M_NAM
;
3825 from_nam
.nam$l_esa
= from_esn
;
3826 from_nam
.nam$b_ess
= sizeof from_esn
;
3828 to_fab
.fab$l_fna
= to
;
3829 to_fab
.fab$b_fns
= strlen (to
);
3830 to_fab
.fab$l_nam
= &to_nam
;
3831 to_fab
.fab$l_fop
= FAB$M_NAM
;
3833 to_nam
.nam$l_esa
= to_esn
;
3834 to_nam
.nam$b_ess
= sizeof to_esn
;
3836 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
3842 if (status
== RMS$_DEV
)
3846 vaxc$errno
= status
;
3851 /* This function renames a file like `rename', but it strips
3852 the version number from the "to" filename, such that the "to" file is
3853 will always be a new version. It also sets the file protection once it is
3854 finished. The protection that we will use is stored in fab_final_pro,
3855 and was set when we did a creat_copy_attrs to create the file that we
3858 We could use the chmod function, but Eunichs uses 3 bits per user category
3859 to describe the protection, and VMS uses 4 (write and delete are seperate
3860 bits). To maintain portability, the VMS implementation of `chmod' wires
3861 the W and D bits together. */
3864 static struct fibdef fib
; /* We need this initialized to zero */
3865 char vms_file_written
[NAM$C_MAXRSS
];
3868 rename_sans_version (from
,to
)
3875 struct FAB to_fab
= cc$rms_fab
;
3876 struct NAM to_nam
= cc$rms_nam
;
3877 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
3878 struct dsc$descriptor fib_attr
[2]
3879 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
3880 char to_esn
[NAM$C_MAXRSS
];
3882 $
DESCRIPTOR (disk
,to_esn
);
3884 to_fab
.fab$l_fna
= to
;
3885 to_fab
.fab$b_fns
= strlen (to
);
3886 to_fab
.fab$l_nam
= &to_nam
;
3887 to_fab
.fab$l_fop
= FAB$M_NAM
;
3889 to_nam
.nam$l_esa
= to_esn
;
3890 to_nam
.nam$b_ess
= sizeof to_esn
;
3892 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
3894 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
3895 *(to_nam
.nam$l_ver
) = '\0';
3897 stat
= rename (from
, to_esn
);
3901 strcpy (vms_file_written
, to_esn
);
3903 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
3904 to_fab
.fab$b_fns
= strlen (vms_file_written
);
3906 /* Now set the file protection to the correct value */
3907 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
3909 /* Copy these fields into the fib */
3910 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
3911 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
3912 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
3914 SYS$
CLOSE (&to_fab
, 0, 0);
3916 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
3919 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
3920 0, 0, 0, &fib_attr
, 0);
3923 stat
= SYS$
DASSGN (chan
);
3926 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
3936 unsigned short fid
[3];
3937 char esa
[NAM$C_MAXRSS
];
3940 fab
.fab$l_fop
= FAB$M_OFP
;
3941 fab
.fab$l_fna
= file
;
3942 fab
.fab$b_fns
= strlen (file
);
3943 fab
.fab$l_nam
= &nam
;
3946 nam
.nam$l_esa
= esa
;
3947 nam
.nam$b_ess
= NAM$C_MAXRSS
;
3949 status
= SYS$
PARSE (&fab
);
3950 if ((status
& 1) == 0)
3953 vaxc$errno
= status
;
3956 status
= SYS$
SEARCH (&fab
);
3957 if ((status
& 1) == 0)
3960 vaxc$errno
= status
;
3964 fid
[0] = nam
.nam$w_fid
[0];
3965 fid
[1] = nam
.nam$w_fid
[1];
3966 fid
[2] = nam
.nam$w_fid
[2];
3968 fab
.fab$l_fna
= new;
3969 fab
.fab$b_fns
= strlen (new);
3971 status
= SYS$
PARSE (&fab
);
3972 if ((status
& 1) == 0)
3975 vaxc$errno
= status
;
3979 nam
.nam$w_fid
[0] = fid
[0];
3980 nam
.nam$w_fid
[1] = fid
[1];
3981 nam
.nam$w_fid
[2] = fid
[2];
3983 nam
.nam$l_esa
= nam
.nam$l_name
;
3984 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
3986 status
= SYS$
ENTER (&fab
);
3987 if ((status
& 1) == 0)
3990 vaxc$errno
= status
;
4000 printf ("%s not yet implemented\r\n", badfunc
);
4008 /* Arrange to return a range centered on zero. */
4009 return rand () - (1 << 30);
4020 /* Called from init_sys_modes. */
4025 /* If we're not on an HFT we shouldn't do any of this. We determine
4026 if we are on an HFT by trying to get an HFT error code. If this
4027 call fails, we're not on an HFT. */
4029 if (ioctl (0, HFQERROR
, &junk
) < 0)
4031 #else /* not IBMR2AIX */
4032 if (ioctl (0, HFQEIO
, 0) < 0)
4034 #endif /* not IBMR2AIX */
4036 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4037 as the rubout key's ASCII code. Here this is changed. The bug is that
4038 there's no way to determine the old mapping, so in reset_sys_modes
4039 we need to assume that the normal map had been present. Of course, this
4040 code also doesn't help if on a terminal emulator which doesn't understand
4044 struct hfkeymap keymap
;
4046 buf
.hf_bufp
= (char *)&keymap
;
4047 buf
.hf_buflen
= sizeof (keymap
);
4048 keymap
.hf_nkeys
= 2;
4049 keymap
.hfkey
[0].hf_kpos
= 15;
4050 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4052 keymap
.hfkey
[0].hf_keyidh
= '<';
4053 #else /* not IBMR2AIX */
4054 keymap
.hfkey
[0].hf_page
= '<';
4055 #endif /* not IBMR2AIX */
4056 keymap
.hfkey
[0].hf_char
= 127;
4057 keymap
.hfkey
[1].hf_kpos
= 15;
4058 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4060 keymap
.hfkey
[1].hf_keyidh
= '<';
4061 #else /* not IBMR2AIX */
4062 keymap
.hfkey
[1].hf_page
= '<';
4063 #endif /* not IBMR2AIX */
4064 keymap
.hfkey
[1].hf_char
= 127;
4065 hftctl (0, HFSKBD
, &buf
);
4067 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4069 line_ins_del_ok
= char_ins_del_ok
= 0;
4072 /* Reset the rubout key to backspace. */
4077 struct hfkeymap keymap
;
4081 if (ioctl (0, HFQERROR
, &junk
) < 0)
4083 #else /* not IBMR2AIX */
4084 if (ioctl (0, HFQEIO
, 0) < 0)
4086 #endif /* not IBMR2AIX */
4088 buf
.hf_bufp
= (char *)&keymap
;
4089 buf
.hf_buflen
= sizeof (keymap
);
4090 keymap
.hf_nkeys
= 2;
4091 keymap
.hfkey
[0].hf_kpos
= 15;
4092 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4094 keymap
.hfkey
[0].hf_keyidh
= '<';
4095 #else /* not IBMR2AIX */
4096 keymap
.hfkey
[0].hf_page
= '<';
4097 #endif /* not IBMR2AIX */
4098 keymap
.hfkey
[0].hf_char
= 8;
4099 keymap
.hfkey
[1].hf_kpos
= 15;
4100 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4102 keymap
.hfkey
[1].hf_keyidh
= '<';
4103 #else /* not IBMR2AIX */
4104 keymap
.hfkey
[1].hf_page
= '<';
4105 #endif /* not IBMR2AIX */
4106 keymap
.hfkey
[1].hf_char
= 8;
4107 hftctl (0, HFSKBD
, &buf
);