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. */
28 #define min(x,y) ((x) > (y) ? (y) : (x))
30 /* In this file, open, read and write refer to the system calls,
31 not our sugared interfaces sys_open, sys_read and sys_write.
32 Contrariwise, for systems where we use the system calls directly,
33 define sys_read, etc. here as aliases for them. */
36 #define sys_write write
37 #endif /* `read' is not a macro */
43 #define sys_close close
50 #else /* `open' is a macro */
52 #endif /* `open' is a macro */
54 /* Does anyone other than VMS need this? */
56 #define sys_fwrite fwrite
62 #include <sys/types.h>
68 extern char *sys_errlist
[];
91 #define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */
95 #ifdef BSD /* this is done this way to avoid defined (BSD) || defined (USG)
96 because the vms compiler doesn't grok `defined' */
104 #endif /* not 4.1 bsd */
106 /* Get DGUX definition for FASYNC - DJB */
108 #include <sys/file.h>
111 #include <sys/ioctl.h>
118 #include <sys/wait.h>
122 #ifdef BROKEN_TIOCGWINSZ
127 #include <sys/utsname.h>
129 #ifndef MEMORY_IN_STRING_H
134 #include <sys/sioctl.h>
137 #include <sys/stream.h>
138 #include <sys/ptem.h>
140 #endif /* TIOCGWINSZ */
143 extern int quit_char
;
147 #include "termhooks.h"
148 #include "termchar.h"
149 #include "termopts.h"
150 #include "dispextern.h"
153 #ifdef NONSYSTEM_DIR_LIBRARY
155 #endif /* NONSYSTEM_DIR_LIBRARY */
157 #include "syssignal.h"
160 static int baud_convert
[] =
165 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
166 1800, 2400, 4800, 9600, 19200, 38400
172 /* The file descriptor for Emacs's input terminal.
173 Under Unix, this is always left zero;
174 under VMS, we place the input channel number here.
175 This allows us to write more code that works for both VMS and Unix. */
180 struct emacs_tty buf
;
185 /* Discarding input is not safe when the input could contain
186 replies from the X server. So don't do it. */
187 if (read_socket_hook
)
192 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
193 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
199 ioctl (0, TIOCFLUSH
, &zero
);
201 #else /* not Apollo */
202 EMACS_GET_TTY (input_fd
, &buf
);
203 EMACS_SET_TTY (input_fd
, &buf
, 0);
204 #endif /* not Apollo */
213 /* Should perhaps error if in batch mode */
215 ioctl (0, TIOCSTI
, &c
);
216 #else /* no TIOCSTI */
217 error ("Cannot stuff terminal input characters in this version of Unix.");
218 #endif /* no TIOCSTI */
232 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
233 &sg
.class, 12, 0, 0, 0, 0 );
234 ospeed
= sg
.xmit_baud
;
239 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
241 ospeed
= sg
.c_cflag
& CBAUD
;
242 #else /* neither VMS nor TERMIOS */
246 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
250 ioctl (input_fd
, TCGETA
, &sg
);
252 ospeed
= sg
.c_cflag
& CBAUD
;
253 #else /* neither VMS nor TERMIOS nor TERMIO */
256 sg
.sg_ospeed
= B9600
;
257 ioctl (0, TIOCGETP
, &sg
);
258 ospeed
= sg
.sg_ospeed
;
259 #endif /* not HAVE_TERMIO */
260 #endif /* not HAVE_TERMIOS */
264 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
265 ? baud_convert
[ospeed
] : 9600);
271 set_exclusive_use (fd
)
275 ioctl (fd
, FIOCLEX
, 0);
277 /* Ok to do nothing if this feature does not exist */
282 wait_without_blocking ()
285 wait3 (0, WNOHANG
| WUNTRACED
, 0);
287 croak ("wait_without_blocking");
289 synch_process_alive
= 0;
292 #endif /* not subprocesses */
294 int wait_debugging
; /* Set nonzero to make following function work under dbx
295 (at least for bsd). */
298 wait_for_termination_signal ()
301 /* Wait for subprocess with process id `pid' to terminate and
302 make sure it will get eliminated (not remain forever as a zombie) */
304 wait_for_termination (pid
)
313 status
= SYS$
FORCEX (&pid
, 0, 0);
317 /* Exit if the process has terminated. */
318 if (!synch_process_alive
)
320 /* Otherwise wait 1 second or until a signal comes in. */
321 signal (SIGALRM
, wait_for_termination_signal
);
325 signal (SIGALRM
, SIG_IGN
);
327 #else /* not subprocesses */
329 if (kill (pid
, 0) < 0)
335 if (status
== pid
|| status
== -1)
338 #endif /* not subprocesses */
345 * flush any pending output
346 * (may flush input as well; it does not matter the way we use it)
349 flush_pending_output (channel
)
353 /* If we try this, we get hit with SIGTTIN, because
354 the child's tty belongs to the child's pgrp. */
357 ioctl (channel
, TCFLSH
, 1);
361 /* 3rd arg should be ignored
362 but some 4.2 kernels actually want the address of an int
363 and nonzero means something different. */
364 ioctl (channel
, TIOCFLUSH
, &zero
);
371 /* Set up the terminal at the other end of a pseudo-terminal that
372 we will be controlling an inferior through.
373 It should not echo or do line-editing, since that is done
374 in Emacs. No padding needed for insertion into an Emacs buffer. */
376 child_setup_tty (out
)
381 EMACS_GET_TTY (out
, &s
);
383 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
384 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
385 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
386 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
387 /* No output delays */
388 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
389 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
390 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
392 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
395 /* Said to be unnecesary: */
396 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
397 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
400 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
401 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
402 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
403 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
406 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
410 /* AIX enhanced edit loses NULs, so disable it */
413 s
.main
.c_iflag
&= ~ASCEDIT
;
415 /* Also, PTY overloads NUL and BREAK.
416 don't ignore break, but don't signal either, so it looks like NUL. */
417 s
.main
.c_iflag
&= ~IGNBRK
;
418 s
.main
.c_iflag
&= ~BRKINT
;
419 /* QUIT and INTR work better as signals, so disable character forms */
420 s
.main
.c_cc
[VQUIT
] = 0377;
421 s
.main
.c_cc
[VINTR
] = 0377;
422 s
.main
.c_cc
[VEOL
] = 0377;
423 s
.main
.c_lflag
&= ~ISIG
;
424 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
427 #else /* not HAVE_TERMIO */
429 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
431 s
.main
.sg_erase
= 0377;
432 s
.main
.sg_kill
= 0377;
434 #endif /* not HAVE_TERMIO */
436 EMACS_SET_TTY (out
, &s
, 0);
445 ioctl (out
, FIOASYNC
, &zero
);
451 #endif /* subprocesses */
457 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
460 /* Record a signal code and the handler for it. */
464 SIGTYPE (*handler
) ();
467 /* Suspend the Emacs process; give terminal to its superior. */
472 /* "Foster" parentage allows emacs to return to a subprocess that attached
473 to the current emacs as a cheaper than starting a whole new process. This
474 is set up by KEPTEDITOR.COM. */
475 unsigned long parent_id
, foster_parent_id
;
478 fpid_string
= getenv ("EMACS_PARENT_PID");
479 if (fpid_string
!= NULL
)
481 sscanf (fpid_string
, "%x", &foster_parent_id
);
482 if (foster_parent_id
!= 0)
483 parent_id
= foster_parent_id
;
485 parent_id
= getppid ();
488 parent_id
= getppid ();
490 free (fpid_string
); /* On VMS, this was malloc'd */
492 if (parent_id
&& parent_id
!= 0xffffffff)
494 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
495 int status
= LIB$
ATTACH (&parent_id
) & 1;
496 signal (SIGINT
, oldsig
);
505 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
506 d_prompt
.a
= "Emacs: "; /* Just a reminder */
507 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
514 EMACS_KILLPG (getpgrp (0), SIGTSTP
);
516 #else /* No SIGTSTP */
517 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
518 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
519 kill (getpid (), SIGQUIT
);
521 #else /* No SIGTSTP or USG_JOBCTRL */
523 /* On a system where suspending is not implemented,
524 instead fork a subshell and let it talk directly to the terminal
527 struct save_signal saved_handlers
[5];
529 saved_handlers
[0].code
= SIGINT
;
530 saved_handlers
[1].code
= SIGQUIT
;
531 saved_handlers
[2].code
= SIGTERM
;
533 saved_handlers
[3].code
= SIGIO
;
534 saved_handlers
[4].code
= 0;
536 saved_handlers
[3].code
= 0;
540 error ("Can't spawn subshell");
545 sh
= (char *) egetenv ("SHELL");
548 /* Use our buffer's default directory for the subshell. */
554 /* mentioning current_buffer->buffer would mean including buffer.h,
555 which somehow wedges the hp compiler. So instead... */
557 dir
= intern ("default-directory");
559 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
561 dir
= Fsymbol_value (dir
);
562 if (XTYPE (dir
) != Lisp_String
)
565 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
566 len
= XSTRING (dir
)->size
;
567 bcopy (XSTRING (dir
)->data
, str
, len
);
568 if (str
[len
- 1] != '/') str
[len
++] = '/';
574 close_process_descs (); /* Close Emacs's pipes/ptys */
579 extern int emacs_priority
;
582 nice (-emacs_priority
);
587 write (1, "Can't execute subshell", 22);
591 save_signal_handlers (saved_handlers
);
592 wait_for_termination (pid
);
593 restore_signal_handlers (saved_handlers
);
595 #endif /* no USG_JOBCTRL */
596 #endif /* no SIGTSTP */
600 save_signal_handlers (saved_handlers
)
601 struct save_signal
*saved_handlers
;
603 while (saved_handlers
->code
)
605 saved_handlers
->handler
606 = (SIGTYPE (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
611 restore_signal_handlers (saved_handlers
)
612 struct save_signal
*saved_handlers
;
614 while (saved_handlers
->code
)
616 signal (saved_handlers
->code
, saved_handlers
->handler
);
628 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
638 #ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
643 sigunblock (sigmask (SIGWINCH
));
645 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
647 interrupts_deferred
= 0;
653 sigblock (sigmask (SIGWINCH
));
655 fcntl (0, F_SETFL
, old_fcntl_flags
);
656 interrupts_deferred
= 1;
659 #else /* no FASYNC */
660 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
665 ioctl (0, FIOASYNC
, &on
);
666 interrupts_deferred
= 0;
673 ioctl (0, FIOASYNC
, &off
);
674 interrupts_deferred
= 1;
677 #else /* not FASYNC, not STRIDE */
681 croak ("request_sigio");
686 croak ("unrequest_sigio");
693 /* The initial tty mode bits */
694 struct emacs_tty old_tty
;
696 int term_initted
; /* 1 if outer tty status has been recorded */
699 /* BSD 4.1 needs to keep track of the lmode bits in order to start
706 #endif /* F_SETOWN */
708 /* This may also be defined in stdio,
709 but if so, this does no harm,
710 and using the same name avoids wasting the other one's space. */
712 #if defined (USG) || defined (DGUX)
713 unsigned char _sobuf
[BUFSIZ
+8];
719 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
722 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
727 struct emacs_tty tty
;
731 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
732 extern int (*interrupt_signal
) ();
741 input_ef
= get_kbd_event_flag ();
742 /* LIB$GET_EF (&input_ef); */
743 SYS$
CLREF (input_ef
);
746 timer_ef
= get_timer_event_flag ();
747 /* LIB$GET_EF (&timer_ef); */
748 SYS$
CLREF (timer_ef
);
752 LIB$
GET_EF (&process_ef
);
753 SYS$
CLREF (process_ef
);
755 if (input_ef
/ 32 != process_ef
/ 32)
756 croak ("Input and process event flags in different clusters.");
758 if (input_ef
/ 32 != timer_ef
/ 32)
759 croak ("Input and timer event flags in different clusters.");
761 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
762 ((unsigned) 1 << (process_ef
% 32));
764 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
765 ((unsigned) 1 << (timer_ef
% 32));
767 sys_access_reinit ();
771 EMACS_GET_TTY (input_fd
, &old_tty
);
773 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
777 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
778 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
779 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
781 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
783 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
784 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
786 tty
.main
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
788 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
791 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
793 tty
.main
.c_iflag
&= ~IXANY
;
797 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
798 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
800 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
804 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
805 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
808 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
809 /* Set up C-g for both SIGQUIT and SIGINT.
810 We don't know which we will get, but we handle both alike
811 so which one it really gives us does not matter. */
812 tty
.main
.c_cc
[VQUIT
] = quit_char
;
813 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
814 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
816 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
819 #if defined (mips) || defined (HAVE_TCATTR)
821 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
824 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
826 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
827 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
829 #endif /* mips or HAVE_TCATTR */
832 /* AIX enhanced edit loses NULs, so disable it */
834 tty
.main
.c_iflag
&= ~ASCEDIT
;
836 tty
.main
.c_cc
[VSTRT
] = 255;
837 tty
.main
.c_cc
[VSTOP
] = 255;
838 tty
.main
.c_cc
[VSUSP
] = 255;
839 tty
.main
.c_cc
[VDSUSP
] = 255;
840 #endif /* IBMR2AIX */
841 /* Also, PTY overloads NUL and BREAK.
842 don't ignore break, but don't signal either, so it looks like NUL.
843 This really serves a purpose only if running in an XTERM window
844 or via TELNET or the like, but does no harm elsewhere. */
845 tty
.main
.c_iflag
&= ~IGNBRK
;
846 tty
.main
.c_iflag
&= ~BRKINT
;
848 #else /* if not HAVE_TERMIO */
850 tty
.main
.tt_char
|= TT$M_NOECHO
;
852 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
854 tty
.main
.tt_char
|= TT$M_TTSYNC
;
856 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
857 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
858 #else /* not VMS (BSD, that is) */
859 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
861 tty
.main
.sg_flags
|= ANYP
;
862 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
863 #endif /* not VMS (BSD, that is) */
864 #endif /* not HAVE_TERMIO */
866 /* If going to use CBREAK mode, we must request C-g to interrupt
867 and turn off start and stop chars, etc. If not going to use
868 CBREAK mode, do this anyway so as to turn off local flow
869 control for user coming over network on 4.2; in this case,
870 only t_stopc and t_startc really matter. */
873 /* Note: if not using CBREAK mode, it makes no difference how we
875 tty
.tchars
= new_tchars
;
876 tty
.tchars
.t_intrc
= quit_char
;
879 tty
.tchars
.t_startc
= '\021';
880 tty
.tchars
.t_stopc
= '\023';
883 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
889 #define LNOFLSH 0100000
892 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
898 #endif /* TIOCGETC */
899 #endif /* not HAVE_TERMIO */
902 tty
.ltchars
= new_ltchars
;
903 #endif /* TIOCGLTC */
905 EMACS_SET_TTY (input_fd
, &tty
, 0);
907 /* This code added to insure that, if flow-control is not to be used,
908 we have an unlocked terminal at the start. */
911 if (!flow_control
) ioctl (0, TCXONC
, 1);
915 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
923 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
924 to be only LF. This is the way that is done. */
927 if (ioctl (1, HFTGETID
, &tty
) != -1)
928 write (1, "\033[20l", 5);
934 /* Appears to do nothing when in PASTHRU mode.
935 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
936 interrupt_signal, oob_chars, 0, 0, 0, 0);
943 #ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
946 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
947 fcntl (0, F_SETOWN
, getpid ());
950 #endif /* F_GETOWN */
958 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
962 /* This symbol is defined on recent USG systems.
963 Someone says without this call USG won't really buffer the file
964 even with a call to setbuf. */
965 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
967 setbuf (stdout
, _sobuf
);
969 set_terminal_modes ();
970 if (term_initted
&& no_redraw_on_reenter
)
972 if (display_completed
)
973 direct_output_forward_char (0);
979 if (FRAMEP (Vterminal_frame
))
980 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
987 /* Return nonzero if safe to use tabs in output.
988 At the time this is called, init_sys_modes has not been done yet. */
992 struct emacs_tty tty
;
994 EMACS_GET_TTY (input_fd
, &tty
);
995 return EMACS_TTY_TABS_OK (&tty
);
998 /* Get terminal size from system.
999 Store number of lines into *heightp and width into *widthp.
1000 If zero or a negative number is stored, the value is not valid. */
1002 get_frame_size (widthp
, heightp
)
1003 int *widthp
, *heightp
;
1009 struct winsize size
;
1011 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1012 *widthp
= *heightp
= 0;
1015 *widthp
= size
.ws_col
;
1016 *heightp
= size
.ws_row
;
1022 /* SunOS - style. */
1023 struct ttysize size
;
1025 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1026 *widthp
= *heightp
= 0;
1029 *widthp
= size
.ts_cols
;
1030 *heightp
= size
.ts_lines
;
1036 struct sensemode tty
;
1038 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1039 &tty
.class, 12, 0, 0, 0, 0);
1040 *widthp
= tty
.scr_wid
;
1041 *heightp
= tty
.scr_len
;
1043 #else /* system doesn't know size */
1048 #endif /* not VMS */
1049 #endif /* not SunOS-style */
1050 #endif /* not BSD-style */
1054 /* Prepare the terminal for exiting Emacs; move the cursor to the
1055 bottom of the frame, turn off interrupt-driven I/O, etc. */
1065 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1067 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1068 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1069 /* clear_end_of_line may move the cursor */
1070 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1073 /* HFT devices normally use ^J as a LF/CR. We forced it to
1074 do the LF only. Now, we need to reset it. */
1077 if (ioctl (1, HFTGETID
, &tty
) != -1)
1078 write (1, "\033[20h", 5);
1082 reset_terminal_modes ();
1086 /* Avoid possible loss of output when changing terminal modes. */
1087 fsync (fileno (stdout
));
1092 #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */
1093 if (interrupt_input
)
1096 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1098 #endif /* F_SETOWN */
1099 #endif /* F_SETFL */
1101 if (interrupt_input
)
1105 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1115 /* Set up the proper status flags for use of a pty. */
1120 /* I'm told that TOICREMOTE does not mean control chars
1121 "can't be sent" but rather that they don't have
1122 input-editing or signaling effects.
1123 That should be good, because we have other ways
1124 to do those things in Emacs.
1125 However, telnet mode seems not to work on 4.2.
1126 So TIOCREMOTE is turned off now. */
1128 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1129 will hang. In particular, the "timeout" feature (which
1130 causes a read to return if there is no data available)
1131 does this. Also it is known that telnet mode will hang
1132 in such a way that Emacs must be stopped (perhaps this
1133 is the same problem).
1135 If TIOCREMOTE is turned off, then there is a bug in
1136 hp-ux which sometimes loses data. Apparently the
1137 code which blocks the master process when the internal
1138 buffer fills up does not work. Other than this,
1139 though, everything else seems to work fine.
1141 Since the latter lossage is more benign, we may as well
1142 lose that way. -- cph */
1147 ioctl (fd
, FIONBIO
, &on
);
1152 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1153 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1154 /* cause EMACS not to die when it should, i.e., when its own controlling */
1155 /* tty goes away. I've complained to the AIX developers, and they may */
1156 /* change this behavior, but I'm not going to hold my breath. */
1157 signal (SIGHUP
, SIG_IGN
);
1160 #endif /* HAVE_PTYS */
1164 /* Assigning an input channel is done at the start of Emacs execution.
1165 This is called each time Emacs is resumed, also, but does nothing
1166 because input_chain is no longer zero. */
1174 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1180 /* Deassigning the input channel is done before exiting. */
1184 return SYS$
DASSGN (input_fd
);
1189 /* Request reading one character into the keyboard buffer.
1190 This is done as soon as the buffer becomes empty. */
1195 extern kbd_input_ast ();
1197 waiting_for_ast
= 0;
1199 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1200 &input_iosb
, kbd_input_ast
, 1,
1201 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1206 /* Ast routine that is called when keyboard input comes in
1207 in accord with the SYS$QIO above. */
1211 register int c
= -1;
1212 int old_errno
= errno
;
1213 extern EMACS_TIME
*input_available_clear_time
;
1215 if (waiting_for_ast
)
1216 SYS$
SETEF (input_ef
);
1217 waiting_for_ast
= 0;
1220 if (input_count
== 25)
1222 printf ("Ast # %d,", input_count
);
1223 printf (" iosb = %x, %x, %x, %x",
1224 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1227 if (input_iosb
.offset
)
1231 printf (", char = 0%o", c
);
1243 struct input_event e
;
1244 e
.kind
= ascii_keystroke
;
1245 XSET (e
.code
, Lisp_Int
, c
);
1247 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1249 e
.frame_or_window
= Qnil
;
1251 kbd_buffer_store_event (&e
);
1253 if (input_available_clear_time
)
1254 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1258 /* Wait until there is something in kbd_buffer. */
1260 wait_for_kbd_input ()
1262 extern int have_process_input
, process_exited
;
1264 /* If already something, avoid doing system calls. */
1265 if (detect_input_pending ())
1269 /* Clear a flag, and tell ast routine above to set it. */
1270 SYS$
CLREF (input_ef
);
1271 waiting_for_ast
= 1;
1272 /* Check for timing error: ast happened while we were doing that. */
1273 if (!detect_input_pending ())
1275 /* No timing error: wait for flag to be set. */
1276 set_waiting_for_input (0);
1277 SYS$
WFLOR (input_ef
, input_eflist
);
1278 clear_waiting_for_input (0);
1279 if (!detect_input_pending ())
1280 /* Check for subprocess input availability */
1282 int dsp
= have_process_input
|| process_exited
;
1284 SYS$
CLREF (process_ef
);
1285 if (have_process_input
)
1286 process_command_input ();
1291 update_mode_lines
++;
1292 redisplay_preserve_echo_area ();
1296 waiting_for_ast
= 0;
1299 /* Get rid of any pending QIO, when we are about to suspend
1300 or when we want to throw away pending input.
1301 We wait for a positive sign that the AST routine has run
1302 and therefore there is no I/O request queued when we return.
1303 SYS$SETAST is used to avoid a timing error. */
1308 printf ("At end_kbd_input.\n");
1312 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1314 SYS$
CANCEL (input_fd
);
1319 /* Clear a flag, and tell ast routine above to set it. */
1320 SYS$
CLREF (input_ef
);
1321 waiting_for_ast
= 1;
1323 SYS$
CANCEL (input_fd
);
1325 SYS$
WAITFR (input_ef
);
1326 waiting_for_ast
= 0;
1329 /* Wait for either input available or time interval expiry. */
1331 input_wait_timeout (timeval
)
1332 int timeval
; /* Time to wait, in seconds */
1335 static int zero
= 0;
1336 static int large
= -10000000;
1338 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1340 /* If already something, avoid doing system calls. */
1341 if (detect_input_pending ())
1345 /* Clear a flag, and tell ast routine above to set it. */
1346 SYS$
CLREF (input_ef
);
1347 waiting_for_ast
= 1;
1348 /* Check for timing error: ast happened while we were doing that. */
1349 if (!detect_input_pending ())
1351 /* No timing error: wait for flag to be set. */
1353 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1354 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1356 waiting_for_ast
= 0;
1359 /* The standard `sleep' routine works some other way
1360 and it stops working if you have ever quit out of it.
1361 This one continues to work. */
1367 static int zero
= 0;
1368 static int large
= -10000000;
1370 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1373 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1374 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1389 croak ("request sigio");
1394 croak ("unrequest sigio");
1399 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1404 #ifndef SYSTEM_MALLOC
1411 /* Some systems that cannot dump also cannot implement these. */
1414 * Return the address of the start of the text segment prior to
1415 * doing an unexec. After unexec the return value is undefined.
1416 * See crt0.c for further explanation and _start.
1420 #ifndef CANNOT_UNEXEC
1425 return ((char *) TEXT_START
);
1429 return ((char *) csrt
);
1430 #else /* not GOULD */
1431 extern int _start ();
1432 return ((char *) _start
);
1434 #endif /* TEXT_START */
1436 #endif /* not CANNOT_UNEXEC */
1439 * Return the address of the start of the data segment prior to
1440 * doing an unexec. After unexec the return value is undefined.
1441 * See crt0.c for further information and definition of data_start.
1443 * Apparently, on BSD systems this is etext at startup. On
1444 * USG systems (swapping) this is highly mmu dependent and
1445 * is also dependent on whether or not the program is running
1446 * with shared text. Generally there is a (possibly large)
1447 * gap between end of text and start of data with shared text.
1449 * On Uniplus+ systems with shared text, data starts at a
1450 * fixed address. Each port (from a given oem) is generally
1451 * different, and the specific value of the start of data can
1452 * be obtained via the UniPlus+ specific "uvar" system call,
1453 * however the method outlined in crt0.c seems to be more portable.
1455 * Probably what will have to happen when a USG unexec is available,
1456 * at least on UniPlus, is temacs will have to be made unshared so
1457 * that text and data are contiguous. Then once loadup is complete,
1458 * unexec will produce a shared executable where the data can be
1459 * at the normal shared text boundry and the startofdata variable
1460 * will be patched by unexec to the correct value.
1468 return ((char *) DATA_START
);
1470 #ifdef ORDINARY_LINK
1472 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1473 * data_start isn't defined. We take the address of environ, which
1474 * is known to live at or near the start of the system crt0.c, and
1475 * we don't sweat the handful of bytes that might lose.
1477 extern char **environ
;
1479 return((char *) &environ
);
1481 extern int data_start
;
1482 return ((char *) &data_start
);
1483 #endif /* ORDINARY_LINK */
1484 #endif /* DATA_START */
1486 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1489 /* Some systems that cannot dump also cannot implement these. */
1492 * Return the address of the end of the text segment prior to
1493 * doing an unexec. After unexec the return value is undefined.
1500 return ((char *) TEXT_END
);
1503 return ((char *) &etext
);
1508 * Return the address of the end of the data segment prior to
1509 * doing an unexec. After unexec the return value is undefined.
1516 return ((char *) DATA_END
);
1519 return ((char *) &edata
);
1523 #endif /* not CANNOT_DUMP */
1525 /* Get_system_name returns as its value
1526 a string for the Lisp function system-name to return. */
1532 /* Can't have this within the function since `static' is #defined to
1533 nothing for some USG systems. */
1535 #ifdef HAVE_GETHOSTNAME
1536 static char get_system_name_name
[256];
1537 #else /* not HAVE_GETHOSTNAME */
1538 static struct utsname get_system_name_name
;
1539 #endif /* not HAVE_GETHOSTNAME */
1546 #ifdef HAVE_GETHOSTNAME
1547 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1548 return get_system_name_name
;
1549 #else /* not HAVE_GETHOSTNAME */
1550 uname (&get_system_name_name
);
1551 return (get_system_name_name
.nodename
);
1552 #endif /* not HAVE_GETHOSTNAME */
1556 #else /* not USG, not 4.1 */
1557 static char system_name_saved
[32];
1560 if ((sp
= egetenv ("SYS$NODE")) == 0)
1566 if ((end
= index (sp
, ':')) != 0)
1569 strcpy (system_name_saved
, sp
);
1571 gethostname (system_name_saved
, sizeof (system_name_saved
));
1572 #endif /* not VMS */
1573 return system_name_saved
;
1574 #endif /* not USG, not 4.1 */
1575 #endif /* not USG */
1579 #ifndef HAVE_GETHOSTNAME
1580 void gethostname(buf
, len
)
1585 s
= getenv ("SYS$NODE");
1589 strncpy (buf
, s
, len
- 2);
1590 buf
[len
- 1] = '\0';
1592 } /* static void gethostname */
1593 #endif /* ! HAVE_GETHOSTNAME */
1600 #ifdef HAVE_X_WINDOWS
1601 /* Cause explanatory error message at compile time,
1602 since the select emulation is not good enough for X. */
1603 int *x
= &x_windows_lose_if_no_select_system_call
;
1606 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1607 * Only checks read descriptors.
1609 /* How long to wait between checking fds in select */
1610 #define SELECT_PAUSE 1
1613 /* For longjmp'ing back to read_input_waiting. */
1615 jmp_buf read_alarm_throw
;
1617 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1618 The read_socket_hook function sets this to 1 while it is waiting. */
1620 int read_alarm_should_throw
;
1628 #else /* not BSD4_1 */
1629 signal (SIGALRM
, SIG_IGN
);
1630 #endif /* not BSD4_1 */
1631 if (read_alarm_should_throw
)
1632 longjmp (read_alarm_throw
, 1);
1635 /* Only rfds are checked. */
1637 select (nfds
, rfds
, wfds
, efds
, timeout
)
1639 int *rfds
, *wfds
, *efds
, *timeout
;
1641 int ravail
= 0, orfds
= 0, old_alarm
;
1642 int timeoutval
= timeout
? *timeout
: 100000;
1643 int *local_timeout
= &timeoutval
;
1644 extern int proc_buffered_char
[];
1645 #ifndef subprocesses
1646 int process_tick
= 0, update_tick
= 0;
1648 extern int process_tick
, update_tick
;
1650 SIGTYPE (*old_trap
) ();
1663 /* If we are looking only for the terminal, with no timeout,
1664 just read it and wait -- that's more efficient. */
1665 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1667 if (! detect_input_pending ())
1668 read_input_waiting ();
1673 /* Once a second, till the timer expires, check all the flagged read
1674 * descriptors to see if any input is available. If there is some then
1675 * set the corresponding bit in the return copy of rfds.
1679 register int to_check
, bit
, fd
;
1683 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1687 int avail
= 0, status
= 0;
1690 avail
= detect_input_pending (); /* Special keyboard handler */
1694 status
= ioctl (fd
, FIONREAD
, &avail
);
1695 #else /* no FIONREAD */
1696 /* Hoping it will return -1 if nothing available
1697 or 0 if all 0 chars requested are read. */
1698 if (proc_buffered_char
[fd
] >= 0)
1702 avail
= read (fd
, &buf
, 1);
1704 proc_buffered_char
[fd
] = buf
;
1706 #endif /* no FIONREAD */
1708 if (status
>= 0 && avail
> 0)
1716 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
1718 old_alarm
= alarm (0);
1719 old_trap
= signal (SIGALRM
, select_alarm
);
1721 alarm (SELECT_PAUSE
);
1722 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1723 while (select_alarmed
== 0 && *local_timeout
!= 0
1724 && process_tick
== update_tick
)
1726 /* If we are interested in terminal input,
1727 wait by reading the terminal.
1728 That makes instant wakeup for terminal input at least. */
1731 read_input_waiting ();
1732 if (detect_input_pending ())
1738 (*local_timeout
) -= SELECT_PAUSE
;
1739 /* Reset the old alarm if there was one */
1741 signal (SIGALRM
, old_trap
);
1744 /* Reset or forge an interrupt for the original handler. */
1745 old_alarm
-= SELECT_PAUSE
;
1747 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
1751 if (*local_timeout
== 0) /* Stop on timer being cleared */
1757 /* Read keyboard input into the standard buffer,
1758 waiting for at least one character. */
1760 /* Make all keyboard buffers much bigger when using X windows. */
1761 #ifdef HAVE_X_WINDOWS
1762 #define BUFFER_SIZE_FACTOR 16
1764 #define BUFFER_SIZE_FACTOR 1
1767 read_input_waiting ()
1769 char buf
[256 * BUFFER_SIZE_FACTOR
];
1770 struct input_event e
;
1772 extern int quit_char
;
1774 if (read_socket_hook
)
1776 read_alarm_should_throw
= 0;
1777 if (! setjmp (read_alarm_throw
))
1778 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
1783 nread
= read (fileno (stdin
), buf
, 1);
1785 /* Scan the chars for C-g and store them in kbd_buffer. */
1786 e
.kind
= ascii_keystroke
;
1787 e
.frame_or_window
= selected_frame
;
1788 for (i
= 0; i
< nread
; i
++)
1790 XSET (e
.code
, Lisp_Int
, buf
[i
]);
1791 kbd_buffer_store_event (&e
);
1792 /* Don't look at input that follows a C-g too closely.
1793 This reduces lossage due to autorepeat on C-g. */
1794 if (buf
[i
] == quit_char
)
1799 #endif /* not HAVE_SELECT */
1800 #endif /* not VMS */
1804 * Partially emulate 4.2 open call.
1805 * open is defined as this in 4.1.
1807 * - added by Michael Bloom @ Citicorp/TTI
1812 sys_open (path
, oflag
, mode
)
1816 if (oflag
& O_CREAT
)
1817 return creat (path
, mode
);
1819 return open (path
, oflag
);
1826 lmode
= LINTRUP
| lmode
;
1827 ioctl (0, TIOCLSET
, &lmode
);
1834 lmode
= ~LINTRUP
& lmode
;
1835 ioctl (0, TIOCLSET
, &lmode
);
1842 interrupts_deferred
= 0;
1849 interrupts_deferred
= 1;
1852 /* still inside #ifdef BSD4_1 */
1855 int sigheld
; /* Mask of held signals */
1860 sigheld
|= sigbit (signum
);
1867 sigheld
|= sigbit (signum
);
1873 sigheld
&= ~sigbit (signum
);
1877 sigfree () /* Free all held signals */
1880 for (i
= 0; i
< NSIG
; i
++)
1881 if (sigheld
& sigbit (i
))
1888 return 1 << (i
- 1);
1890 #endif /* subprocesses */
1893 /* POSIX signals support - DJB */
1894 /* Anyone with POSIX signals should have ANSI C declarations */
1896 #ifdef POSIX_SIGNALS
1898 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
1899 static struct sigaction new_action
, old_action
;
1903 #ifdef POSIX_SIGNALS
1904 sigemptyset (&signal_empty_mask
);
1905 sigfillset (&signal_full_mask
);
1909 int (*signal_handler_t
) ();
1912 sys_signal (int signal_number
, signal_handler_t action
)
1915 /* This gets us restartable system calls for efficiency.
1916 The "else" code will works as well. */
1917 return (berk_signal (signal_number
, action
));
1919 sigemptyset (&new_action
.sa_mask
);
1920 new_action
.sa_handler
= action
;
1921 new_action
.sa_flags
= NULL
;
1922 sigaction (signal_number
, &new_action
, &old_action
);
1923 return (old_action
.sa_handler
);
1928 /* If we're compiling with GCC, we don't need this function, since it
1929 can be written as a macro. */
1931 sys_sigmask (int sig
)
1934 sigemptyset (&mask
);
1935 sigaddset (&mask
, sig
);
1941 sys_sigpause (sigset_t new_mask
)
1943 /* pause emulating berk sigpause... */
1944 sigsuspend (&new_mask
);
1948 /* I'd like to have these guys return pointers to the mask storage in here,
1949 but there'd be trouble if the code was saving multiple masks. I'll be
1950 safe and pass the structure. It normally won't be more than 2 bytes
1954 sys_sigblock (sigset_t new_mask
)
1957 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
1962 sys_sigunblock (sigset_t new_mask
)
1965 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
1970 sys_sigsetmask (sigset_t new_mask
)
1973 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1977 #endif /* POSIX_SIGNALS */
1984 register int length
;
1988 long max_str
= 65535;
1990 while (length
> max_str
) {
1991 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1996 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1998 while (length
-- > 0)
2000 #endif /* not VMS */
2003 /* Saying `void' requires a declaration, above, where bcopy is used
2004 and that declaration causes pain for systems where bcopy is a macro. */
2005 bcopy (b1
, b2
, length
)
2008 register int length
;
2011 long max_str
= 65535;
2013 while (length
> max_str
) {
2014 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2020 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2022 while (length
-- > 0)
2024 #endif /* not VMS */
2028 bcmp (b1
, b2
, length
) /* This could be a macro! */
2031 register int length
;
2034 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2035 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2037 return STR$
COMPARE (&src1
, &src2
);
2039 while (length
-- > 0)
2044 #endif /* not VMS */
2046 #endif /* not BSTRING */
2050 * The BSD random returns numbers in the range of
2051 * 0 to 2e31 - 1. The USG rand returns numbers in the
2052 * range of 0 to 2e15 - 1. This is probably not significant
2059 /* Arrange to return a range centered on zero. */
2060 return (rand () << 15) + rand () - (1 << 29);
2074 /* Arrange to return a range centered on zero. */
2075 return (rand () << 15) + rand () - (1 << 29);
2085 #ifdef WRONG_NAME_INSQUE
2098 /* If any place else asks for the TERM variable,
2099 allow it to be overridden with the EMACS_TERM variable
2100 before attempting to translate the logical name TERM. As a last
2101 resort, ask for VAX C's special idea of the TERM variable. */
2108 static char buf
[256];
2109 static struct dsc$descriptor_s equiv
2110 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2111 static struct dsc$descriptor_s d_name
2112 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2115 if (!strcmp (name
, "TERM"))
2117 val
= (char *) getenv ("EMACS_TERM");
2122 d_name
.dsc$w_length
= strlen (name
);
2123 d_name
.dsc$a_pointer
= name
;
2124 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2126 char *str
= (char *) xmalloc (eqlen
+ 1);
2127 bcopy (buf
, str
, eqlen
);
2129 /* This is a storage leak, but a pain to fix. With luck,
2130 no one will ever notice. */
2133 return (char *) getenv (name
);
2138 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2139 to force a call on the debugger from within the image. */
2144 LIB$
SIGNAL (SS$_DEBUG
);
2150 #ifdef LINK_CRTL_SHARE
2151 #ifdef SHAREABLE_LIB_BUG
2152 /* Variables declared noshare and initialized in shareable libraries
2153 cannot be shared. The VMS linker incorrectly forces you to use a private
2154 version which is uninitialized... If not for this "feature", we
2155 could use the C library definition of sys_nerr and sys_errlist. */
2157 char *sys_errlist
[] =
2161 "no such file or directory",
2163 "interrupted system call",
2165 "no such device or address",
2166 "argument list too long",
2167 "exec format error",
2170 "no more processes",
2171 "not enough memory",
2172 "permission denied",
2174 "block device required",
2175 "mount devices busy",
2177 "cross-device link",
2182 "file table overflow",
2183 "too many open files",
2187 "no space left on device",
2189 "read-only file system",
2195 "vax/vms specific error code nontranslatable error"
2197 #endif /* SHAREABLE_LIB_BUG */
2198 #endif /* LINK_CRTL_SHARE */
2201 #ifdef INTERRUPTIBLE_OPEN
2205 sys_open (path
, oflag
, mode
)
2209 register int rtnval
;
2211 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2212 && (errno
== EINTR
));
2216 #endif /* INTERRUPTIBLE_OPEN */
2218 #ifdef INTERRUPTIBLE_CLOSE
2223 register int rtnval
;
2225 while ((rtnval
= close (fd
)) == -1
2226 && (errno
== EINTR
));
2230 #endif /* INTERRUPTIBLE_CLOSE */
2232 #ifdef INTERRUPTIBLE_IO
2235 sys_read (fildes
, buf
, nbyte
)
2240 register int rtnval
;
2242 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2243 && (errno
== EINTR
));
2248 sys_write (fildes
, buf
, nbyte
)
2253 register int rtnval
;
2255 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2256 && (errno
== EINTR
));
2260 #endif /* INTERRUPTIBLE_IO */
2264 * All of the following are for USG.
2266 * On USG systems the system calls are INTERRUPTIBLE by signals
2267 * that the user program has elected to catch. Thus the system call
2268 * must be retried in these cases. To handle this without massive
2269 * changes in the source code, we remap the standard system call names
2270 * to names for our own functions in sysdep.c that do the system call
2271 * with retries. Actually, for portability reasons, it is good
2272 * programming practice, as this example shows, to limit all actual
2273 * system calls to a single occurance in the source. Sure, this
2274 * adds an extra level of function call overhead but it is almost
2275 * always negligible. Fred Fish, Unisoft Systems Inc.
2278 char *sys_siglist
[NSIG
+ 1] =
2281 /* AIX has changed the signals a bit */
2282 "bogus signal", /* 0 */
2283 "hangup", /* 1 SIGHUP */
2284 "interrupt", /* 2 SIGINT */
2285 "quit", /* 3 SIGQUIT */
2286 "illegal instruction", /* 4 SIGILL */
2287 "trace trap", /* 5 SIGTRAP */
2288 "IOT instruction", /* 6 SIGIOT */
2289 "crash likely", /* 7 SIGDANGER */
2290 "floating point exception", /* 8 SIGFPE */
2291 "kill", /* 9 SIGKILL */
2292 "bus error", /* 10 SIGBUS */
2293 "segmentation violation", /* 11 SIGSEGV */
2294 "bad argument to system call", /* 12 SIGSYS */
2295 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2296 "alarm clock", /* 14 SIGALRM */
2297 "software termination signum", /* 15 SIGTERM */
2298 "user defined signal 1", /* 16 SIGUSR1 */
2299 "user defined signal 2", /* 17 SIGUSR2 */
2300 "death of a child", /* 18 SIGCLD */
2301 "power-fail restart", /* 19 SIGPWR */
2302 "bogus signal", /* 20 */
2303 "bogus signal", /* 21 */
2304 "bogus signal", /* 22 */
2305 "bogus signal", /* 23 */
2306 "bogus signal", /* 24 */
2307 "LAN I/O interrupt", /* 25 SIGAIO */
2308 "PTY I/O interrupt", /* 26 SIGPTY */
2309 "I/O intervention required", /* 27 SIGIOINT */
2310 "HFT grant", /* 28 SIGGRANT */
2311 "HFT retract", /* 29 SIGRETRACT */
2312 "HFT sound done", /* 30 SIGSOUND */
2313 "HFT input ready", /* 31 SIGMSG */
2315 "bogus signal", /* 0 */
2316 "hangup", /* 1 SIGHUP */
2317 "interrupt", /* 2 SIGINT */
2318 "quit", /* 3 SIGQUIT */
2319 "illegal instruction", /* 4 SIGILL */
2320 "trace trap", /* 5 SIGTRAP */
2321 "IOT instruction", /* 6 SIGIOT */
2322 "EMT instruction", /* 7 SIGEMT */
2323 "floating point exception", /* 8 SIGFPE */
2324 "kill", /* 9 SIGKILL */
2325 "bus error", /* 10 SIGBUS */
2326 "segmentation violation", /* 11 SIGSEGV */
2327 "bad argument to system call", /* 12 SIGSYS */
2328 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2329 "alarm clock", /* 14 SIGALRM */
2330 "software termination signum", /* 15 SIGTERM */
2331 "user defined signal 1", /* 16 SIGUSR1 */
2332 "user defined signal 2", /* 17 SIGUSR2 */
2333 "death of a child", /* 18 SIGCLD */
2334 "power-fail restart", /* 19 SIGPWR */
2335 #endif /* not AIX */
2340 * Warning, this function may not duplicate 4.2 action properly
2341 * under error conditions.
2345 /* In 4.1, param.h fails to define this. */
2346 #define MAXPATHLEN 1024
2355 char *npath
, *spath
;
2356 extern char *getcwd ();
2358 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2359 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2360 up to first slash. Should be harmless on other systems. */
2361 while (*npath
&& *npath
!= '/')
2363 strcpy (pathname
, npath
);
2364 free (spath
); /* getcwd uses malloc */
2368 #endif /* HAVE_GETWD */
2371 * Emulate rename using unlink/link. Note that this is
2372 * only partially correct. Also, doesn't enforce restriction
2373 * that files be of same type (regular->regular, dir->dir, etc).
2382 if (access (from
, 0) == 0)
2385 if (link (from
, to
) == 0)
2386 if (unlink (from
) == 0)
2397 * Substitute fork for vfork on USG flavors.
2405 #endif /* not HAVE_VFORK */
2407 #ifdef MISSING_UTIMES
2409 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2418 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2419 utimbuf structure defined anywhere but in the man page. */
2429 struct timeval tvp
[];
2432 utb
.actime
= tvp
[0].tv_sec
;
2433 utb
.modtime
= tvp
[1].tv_sec
;
2436 #endif /* IRIS_UTIME */
2442 /* HPUX curses library references perror, but as far as we know
2443 it won't be called. Anyway this definition will do for now. */
2449 #endif /* not HAVE_PERROR */
2455 * Emulate BSD dup2. First close newd if it already exists.
2456 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2457 * until we are, then close the unsuccessful ones.
2464 register int fd
, ret
;
2469 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2471 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2478 ret
= dup2 (old
,new);
2484 #endif /* not HAVE_DUP2 */
2487 * Gettimeofday. Simulate as much as possible. Only accurate
2488 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2489 * Only needed when subprocesses are defined.
2494 #ifndef HAVE_GETTIMEOFDAY
2498 gettimeofday (tp
, tzp
)
2500 struct timezone
*tzp
;
2502 extern long time ();
2504 tp
->tv_sec
= time ((long *)0);
2506 tzp
->tz_minuteswest
= -1;
2512 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2515 * This function will go away as soon as all the stubs fixed. (fnf)
2521 printf ("%s not yet implemented\r\n", badfunc
);
2530 char *sys_siglist
[NSIG
+ 1] =
2532 "null signal", /* 0 SIGNULL */
2533 "hangup", /* 1 SIGHUP */
2534 "interrupt", /* 2 SIGINT */
2535 "quit", /* 3 SIGQUIT */
2536 "illegal instruction", /* 4 SIGILL */
2537 "trace trap", /* 5 SIGTRAP */
2538 "abort termination", /* 6 SIGABRT */
2539 "SIGEMT", /* 7 SIGEMT */
2540 "floating point exception", /* 8 SIGFPE */
2541 "kill", /* 9 SIGKILL */
2542 "bus error", /* 10 SIGBUS */
2543 "segmentation violation", /* 11 SIGSEGV */
2544 "bad argument to system call", /* 12 SIGSYS */
2545 "write on a pipe with no reader", /* 13 SIGPIPE */
2546 "alarm clock", /* 14 SIGALRM */
2547 "software termination signal", /* 15 SIGTERM */
2548 "user defined signal 1", /* 16 SIGUSR1 */
2549 "user defined signal 2", /* 17 SIGUSR2 */
2550 "child stopped or terminated", /* 18 SIGCLD */
2551 "power-fail restart", /* 19 SIGPWR */
2552 "window size changed", /* 20 SIGWINCH */
2553 "undefined", /* 21 */
2554 "pollable event occured", /* 22 SIGPOLL */
2555 "sendable stop signal not from tty", /* 23 SIGSTOP */
2556 "stop signal from tty", /* 24 SIGSTP */
2557 "continue a stopped process", /* 25 SIGCONT */
2558 "attempted background tty read", /* 26 SIGTTIN */
2559 "attempted background tty write", /* 27 SIGTTOU */
2560 "undefined", /* 28 */
2561 "undefined", /* 29 */
2562 "undefined", /* 30 */
2563 "undefined", /* 31 */
2564 "undefined", /* 32 */
2565 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2566 "I/O is possible", /* 34 SIGIO */
2567 "exceeded cpu time limit", /* 35 SIGXCPU */
2568 "exceeded file size limit", /* 36 SIGXFSZ */
2569 "virtual time alarm", /* 37 SIGVTALRM */
2570 "profiling time alarm", /* 38 SIGPROF */
2571 "undefined", /* 39 */
2572 "file record locks revoked", /* 40 SIGLOST */
2573 "undefined", /* 41 */
2574 "undefined", /* 42 */
2575 "undefined", /* 43 */
2576 "undefined", /* 44 */
2577 "undefined", /* 45 */
2578 "undefined", /* 46 */
2579 "undefined", /* 47 */
2580 "undefined", /* 48 */
2581 "undefined", /* 49 */
2582 "undefined", /* 50 */
2583 "undefined", /* 51 */
2584 "undefined", /* 52 */
2585 "undefined", /* 53 */
2586 "undefined", /* 54 */
2587 "undefined", /* 55 */
2588 "undefined", /* 56 */
2589 "undefined", /* 57 */
2590 "undefined", /* 58 */
2591 "undefined", /* 59 */
2592 "undefined", /* 60 */
2593 "undefined", /* 61 */
2594 "undefined", /* 62 */
2595 "undefined", /* 63 */
2596 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2602 /* Directory routines for systems that don't have them. */
2604 #ifdef SYSV_SYSTEM_DIR
2611 register DIR *dirp
; /* stream from opendir */
2613 sys_close (dirp
->dd_fd
);
2614 free ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2615 free ((char *) dirp
);
2617 #endif /* not AIX */
2618 #endif /* SYSV_SYSTEM_DIR */
2620 #ifdef NONSYSTEM_DIR_LIBRARY
2624 char *filename
; /* name of directory */
2626 register DIR *dirp
; /* -> malloc'ed storage */
2627 register int fd
; /* file descriptor for read */
2628 struct stat sbuf
; /* result of fstat */
2630 fd
= sys_open (filename
, 0);
2634 if (fstat (fd
, &sbuf
) < 0
2635 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2636 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2639 return 0; /* bad luck today */
2643 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2650 register DIR *dirp
; /* stream from opendir */
2652 sys_close (dirp
->dd_fd
);
2653 free ((char *) dirp
);
2661 ino_t od_ino
; /* inode */
2662 char od_name
[DIRSIZ
]; /* filename */
2664 #endif /* not VMS */
2666 struct direct dir_static
; /* simulated directory contents */
2671 register DIR *dirp
; /* stream from opendir */
2674 register struct olddir
*dp
; /* -> directory data */
2676 register struct dir$_name
*dp
; /* -> directory data */
2677 register struct dir$_version
*dv
; /* -> version data */
2682 if (dirp
->dd_loc
>= dirp
->dd_size
)
2683 dirp
->dd_loc
= dirp
->dd_size
= 0;
2685 if (dirp
->dd_size
== 0 /* refill buffer */
2686 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2690 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
2691 dirp
->dd_loc
+= sizeof (struct olddir
);
2693 if (dp
->od_ino
!= 0) /* not deleted entry */
2695 dir_static
.d_ino
= dp
->od_ino
;
2696 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
2697 dir_static
.d_name
[DIRSIZ
] = '\0';
2698 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2699 dir_static
.d_reclen
= sizeof (struct direct
)
2701 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2702 return &dir_static
; /* -> simulated structure */
2705 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2706 if (dirp
->dd_loc
== 0)
2707 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
2708 : dp
->dir$b_namecount
;
2709 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
2710 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2711 dir_static
.d_namlen
= dp
->dir$b_namecount
;
2712 dir_static
.d_reclen
= sizeof (struct direct
)
2714 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2715 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2716 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
2717 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
2724 /* readdirver is just like readdir except it returns all versions of a file
2725 as separate entries. */
2730 register DIR *dirp
; /* stream from opendir */
2732 register struct dir$_name
*dp
; /* -> directory data */
2733 register struct dir$_version
*dv
; /* -> version data */
2735 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
2736 dirp
->dd_loc
= dirp
->dd_size
= 0;
2738 if (dirp
->dd_size
== 0 /* refill buffer */
2739 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2742 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2743 if (dirp
->dd_loc
== 0)
2744 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
2745 : dp
->dir$b_namecount
;
2746 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
2747 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2748 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
2749 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2750 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2751 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
2752 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2753 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
2759 #endif /* NONSYSTEM_DIR_LIBRARY */
2761 /* Functions for VMS */
2763 #include "vms-pwd.h"
2768 /* Return as a string the VMS error string pertaining to STATUS.
2769 Reuses the same static buffer each time it is called. */
2773 int status
; /* VMS status code */
2777 static char buf
[257];
2779 bufadr
[0] = sizeof buf
- 1;
2780 bufadr
[1] = (int) buf
;
2781 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
2782 return "untranslatable VMS error status";
2790 /* The following is necessary because 'access' emulation by VMS C (2.0) does
2791 * not work correctly. (It also doesn't work well in version 2.3.)
2796 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
2797 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
2801 unsigned short s_buflen
;
2802 unsigned short s_code
;
2804 unsigned short *s_retlenadr
;
2808 #define buflen s.s_buflen
2809 #define code s.s_code
2810 #define bufadr s.s_bufadr
2811 #define retlenadr s.s_retlenadr
2813 #define R_OK 4 /* test for read permission */
2814 #define W_OK 2 /* test for write permission */
2815 #define X_OK 1 /* test for execute (search) permission */
2816 #define F_OK 0 /* test for presence of file */
2819 sys_access (path
, mode
)
2823 static char *user
= NULL
;
2826 /* translate possible directory spec into .DIR file name, so brain-dead
2827 * access can treat the directory like a file. */
2828 if (directory_file_name (path
, dir_fn
))
2832 return access (path
, mode
);
2833 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
2839 unsigned short int dummy
;
2841 static int constant
= ACL$C_FILE
;
2842 DESCRIPTOR (path_desc
, path
);
2843 DESCRIPTOR (user_desc
, user
);
2847 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
2850 acces
|= CHP$M_READ
;
2852 acces
|= CHP$M_WRITE
;
2853 itemlst
[0].buflen
= sizeof (int);
2854 itemlst
[0].code
= CHP$_FLAGS
;
2855 itemlst
[0].bufadr
= (char *) &flags
;
2856 itemlst
[0].retlenadr
= &dummy
;
2857 itemlst
[1].buflen
= sizeof (int);
2858 itemlst
[1].code
= CHP$_ACCESS
;
2859 itemlst
[1].bufadr
= (char *) &acces
;
2860 itemlst
[1].retlenadr
= &dummy
;
2861 itemlst
[2].end
= CHP$_END
;
2862 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
2863 return stat
== SS$_NORMAL
? 0 : -1;
2867 #else /* not VMS4_4 */
2870 #define ACE$M_WRITE 2
2871 #define ACE$C_KEYID 1
2873 static unsigned short memid
, grpid
;
2874 static unsigned int uic
;
2876 /* Called from init_sys_modes, so it happens not very often
2877 but at least each time Emacs is loaded. */
2878 sys_access_reinit ()
2884 sys_access (filename
, type
)
2890 int status
, size
, i
, typecode
, acl_controlled
;
2891 unsigned int *aclptr
, *aclend
, aclbuf
[60];
2892 union prvdef prvmask
;
2894 /* Get UIC and GRP values for protection checking. */
2897 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
2900 memid
= uic
& 0xFFFF;
2904 if (type
!= 2) /* not checking write access */
2905 return access (filename
, type
);
2907 /* Check write protection. */
2909 #define CHECKPRIV(bit) (prvmask.bit)
2910 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
2912 /* Find privilege bits */
2913 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
2915 error ("Unable to find privileges: %s", vmserrstr (status
));
2916 if (CHECKPRIV (PRV$V_BYPASS
))
2917 return 0; /* BYPASS enabled */
2919 fab
.fab$b_fac
= FAB$M_GET
;
2920 fab
.fab$l_fna
= filename
;
2921 fab
.fab$b_fns
= strlen (filename
);
2922 fab
.fab$l_xab
= &xab
;
2923 xab
= cc$rms_xabpro
;
2924 xab
.xab$l_aclbuf
= aclbuf
;
2925 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
2926 status
= SYS$
OPEN (&fab
, 0, 0);
2929 SYS$
CLOSE (&fab
, 0, 0);
2930 /* Check system access */
2931 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
2933 /* Check ACL entries, if any */
2935 if (xab
.xab$w_acllen
> 0)
2938 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
2939 while (*aclptr
&& aclptr
< aclend
)
2941 size
= (*aclptr
& 0xff) / 4;
2942 typecode
= (*aclptr
>> 8) & 0xff;
2943 if (typecode
== ACE$C_KEYID
)
2944 for (i
= size
- 1; i
> 1; i
--)
2945 if (aclptr
[i
] == uic
)
2948 if (aclptr
[1] & ACE$M_WRITE
)
2949 return 0; /* Write access through ACL */
2951 aclptr
= &aclptr
[size
];
2953 if (acl_controlled
) /* ACL specified, prohibits write access */
2956 /* No ACL entries specified, check normal protection */
2957 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
2959 if (WRITEABLE (XAB$V_GRP
) &&
2960 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
2961 return 0; /* Group writeable */
2962 if (WRITEABLE (XAB$V_OWN
) &&
2963 (xab
.xab$l_uic
& 0xFFFF) == memid
)
2964 return 0; /* Owner writeable */
2966 return -1; /* Not writeable */
2968 #endif /* not VMS4_4 */
2971 static char vtbuf
[NAM$C_MAXRSS
+1];
2973 /* translate a vms file spec to a unix path */
2975 sys_translate_vms (vfile
)
2986 /* leading device or logical name is a root directory */
2987 if (p
= strchr (vfile
, ':'))
2996 if (*p
== '[' || *p
== '<')
2998 while (*++vfile
!= *p
+ 2)
3002 if (vfile
[-1] == *p
)
3025 static char utbuf
[NAM$C_MAXRSS
+1];
3027 /* translate a unix path to a VMS file spec */
3029 sys_translate_unix (ufile
)
3052 if (index (&ufile
[1], '/'))
3059 if (index (&ufile
[1], '/'))
3066 if (strncmp (ufile
, "./", 2) == 0)
3073 ufile
++; /* skip the dot */
3074 if (index (&ufile
[1], '/'))
3079 else if (strncmp (ufile
, "../", 3) == 0)
3087 ufile
+= 2; /* skip the dots */
3088 if (index (&ufile
[1], '/'))
3113 extern char *getcwd ();
3115 #define MAXPATHLEN 1024
3117 ptr
= malloc (MAXPATHLEN
);
3118 getcwd (ptr
, MAXPATHLEN
);
3119 strcpy (pathname
, ptr
);
3127 long item_code
= JPI$_OWNER
;
3128 unsigned long parent_id
;
3131 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3134 vaxc$errno
= status
;
3144 return (getgid () << 16) | getuid ();
3148 sys_read (fildes
, buf
, nbyte
)
3153 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3158 sys_write (fildes
, buf
, nbyte
)
3163 register int nwrote
, rtnval
= 0;
3165 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3171 return rtnval
? rtnval
: -1;
3172 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3173 return rtnval
? rtnval
: -1;
3174 return (rtnval
+ nwrote
);
3179 * VAX/VMS VAX C RTL really loses. It insists that records
3180 * end with a newline (carriage return) character, and if they
3181 * don't it adds one (nice of it isn't it!)
3183 * Thus we do this stupidity below.
3187 sys_write (fildes
, buf
, nbytes
)
3190 unsigned int nbytes
;
3197 fstat (fildes
, &st
);
3203 /* Handle fixed-length files with carriage control. */
3204 if (st
.st_fab_rfm
== FAB$C_FIX
3205 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3207 len
= st
.st_fab_mrs
;
3208 retval
= write (fildes
, p
, min (len
, nbytes
));
3211 retval
++; /* This skips the implied carriage control */
3215 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3216 while (*e
!= '\n' && e
> p
) e
--;
3217 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3218 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3220 retval
= write (fildes
, p
, len
);
3231 /* Create file NEW copying its attributes from file OLD. If
3232 OLD is 0 or does not exist, create based on the value of
3235 /* Protection value the file should ultimately have.
3236 Set by create_copy_attrs, and use by rename_sansversions. */
3237 static unsigned short int fab_final_pro
;
3240 creat_copy_attrs (old
, new)
3243 struct FAB fab
= cc$rms_fab
;
3244 struct XABPRO xabpro
;
3245 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3246 extern int vms_stmlf_recfm
;
3250 fab
.fab$b_fac
= FAB$M_GET
;
3251 fab
.fab$l_fna
= old
;
3252 fab
.fab$b_fns
= strlen (old
);
3253 fab
.fab$l_xab
= (char *) &xabpro
;
3254 xabpro
= cc$rms_xabpro
;
3255 xabpro
.xab$l_aclbuf
= aclbuf
;
3256 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3257 /* Call $OPEN to fill in the fab & xabpro fields. */
3258 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3260 SYS$
CLOSE (&fab
, 0, 0);
3261 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3262 if (xabpro
.xab$w_acllen
> 0)
3264 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3265 /* If the acl buffer was too short, redo open with longer one.
3266 Wouldn't need to do this if there were some system imposed
3267 limit on the size of an ACL, but I can't find any such. */
3269 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3270 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3271 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3272 SYS$
CLOSE (&fab
, 0, 0);
3278 xabpro
.xab$l_aclbuf
= 0;
3283 fab
.fab$l_fna
= new;
3284 fab
.fab$b_fns
= strlen (new);
3288 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3289 fab
.fab$b_rat
= FAB$M_CR
;
3292 /* Set the file protections such that we will be able to manipulate
3293 this file. Once we are done writing and renaming it, we will set
3294 the protections back. */
3296 fab_final_pro
= xabpro
.xab$w_pro
;
3298 SYS$
SETDFPROT (0, &fab_final_pro
);
3299 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3301 /* Create the new file with either default attrs or attrs copied
3303 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3305 SYS$
CLOSE (&fab
, 0, 0);
3306 /* As this is a "replacement" for creat, return a file descriptor
3307 opened for writing. */
3308 return open (new, O_WRONLY
);
3313 #include <varargs.h>
3316 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3320 sys_creat (va_alist
)
3323 va_list list_incrementor
;
3326 int rfd
; /* related file descriptor */
3327 int fd
; /* Our new file descriptor */
3334 extern int vms_stmlf_recfm
;
3337 va_start (list_incrementor
);
3338 name
= va_arg (list_incrementor
, char *);
3339 mode
= va_arg (list_incrementor
, int);
3341 rfd
= va_arg (list_incrementor
, int);
3342 va_end (list_incrementor
);
3345 /* Use information from the related file descriptor to set record
3346 format of the newly created file. */
3347 fstat (rfd
, &st_buf
);
3348 switch (st_buf
.st_fab_rfm
)
3351 strcpy (rfm
, "rfm = fix");
3352 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3353 strcpy (rat
, "rat = ");
3354 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3356 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3357 strcat (rat
, "ftn");
3358 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3359 strcat (rat
, "prn");
3360 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3361 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3362 strcat (rat
, ", blk");
3364 strcat (rat
, "blk");
3365 return creat (name
, 0, rfm
, rat
, mrs
);
3368 strcpy (rfm
, "rfm = vfc");
3369 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3370 strcpy (rat
, "rat = ");
3371 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3373 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3374 strcat (rat
, "ftn");
3375 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3376 strcat (rat
, "prn");
3377 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3378 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3379 strcat (rat
, ", blk");
3381 strcat (rat
, "blk");
3382 return creat (name
, 0, rfm
, rat
, fsz
);
3385 strcpy (rfm
, "rfm = stm");
3389 strcpy (rfm
, "rfm = stmcr");
3393 strcpy (rfm
, "rfm = stmlf");
3397 strcpy (rfm
, "rfm = udf");
3401 strcpy (rfm
, "rfm = var");
3404 strcpy (rat
, "rat = ");
3405 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3407 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3408 strcat (rat
, "ftn");
3409 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3410 strcat (rat
, "prn");
3411 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3412 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3413 strcat (rat
, ", blk");
3415 strcat (rat
, "blk");
3419 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3420 strcpy (rat
, "rat=cr");
3422 /* Until the VAX C RTL fixes the many bugs with modes, always use
3423 mode 0 to get the user's default protection. */
3424 fd
= creat (name
, 0, rfm
, rat
);
3425 if (fd
< 0 && errno
== EEXIST
)
3427 if (unlink (name
) < 0)
3428 report_file_error ("delete", build_string (name
));
3429 fd
= creat (name
, 0, rfm
, rat
);
3435 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3436 sys_fwrite (ptr
, size
, num
, fp
)
3437 register char * ptr
;
3440 register int tot
= num
* size
;
3447 * The VMS C library routine creat actually creates a new version of an
3448 * existing file rather than truncating the old version. There are times
3449 * when this is not the desired behavior, for instance, when writing an
3450 * auto save file (you only want one version), or when you don't have
3451 * write permission in the directory containing the file (but the file
3452 * itself is writable). Hence this routine, which is equivalent to
3453 * "close (creat (fn, 0));" on Unix if fn already exists.
3459 struct FAB xfab
= cc$rms_fab
;
3460 struct RAB xrab
= cc$rms_rab
;
3463 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3464 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3465 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3466 xfab
.fab$l_fna
= fn
;
3467 xfab
.fab$b_fns
= strlen (fn
);
3468 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3470 xrab
.rab$l_fab
= &xfab
;
3472 /* This gibberish opens the file, positions to the first record, and
3473 deletes all records from there until the end of file. */
3474 if ((SYS$
OPEN (&xfab
) & 01) == 01)
3476 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
3477 (SYS$
FIND (&xrab
) & 01) == 01 &&
3478 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
3489 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3490 SYSPRV or a readable SYSUAF.DAT. */
3496 * Routine to read the VMS User Authorization File and return
3497 * a specific user's record.
3500 static struct UAF retuaf
;
3503 get_uaf_name (uname
)
3510 uaf_fab
= cc$rms_fab
;
3511 uaf_rab
= cc$rms_rab
;
3512 /* initialize fab fields */
3513 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3514 uaf_fab
.fab$b_fns
= 21;
3515 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3516 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3517 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3518 /* initialize rab fields */
3519 uaf_rab
.rab$l_fab
= &uaf_fab
;
3520 /* open the User Authorization File */
3521 status
= SYS$
OPEN (&uaf_fab
);
3525 vaxc$errno
= status
;
3528 status
= SYS$
CONNECT (&uaf_rab
);
3532 vaxc$errno
= status
;
3535 /* read the requested record - index is in uname */
3536 uaf_rab
.rab$l_kbf
= uname
;
3537 uaf_rab
.rab$b_ksz
= strlen (uname
);
3538 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3539 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3540 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3541 status
= SYS$
GET (&uaf_rab
);
3545 vaxc$errno
= status
;
3548 /* close the User Authorization File */
3549 status
= SYS$
DISCONNECT (&uaf_rab
);
3553 vaxc$errno
= status
;
3556 status
= SYS$
CLOSE (&uaf_fab
);
3560 vaxc$errno
= status
;
3574 uaf_fab
= cc$rms_fab
;
3575 uaf_rab
= cc$rms_rab
;
3576 /* initialize fab fields */
3577 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3578 uaf_fab
.fab$b_fns
= 21;
3579 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3580 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3581 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3582 /* initialize rab fields */
3583 uaf_rab
.rab$l_fab
= &uaf_fab
;
3584 /* open the User Authorization File */
3585 status
= SYS$
OPEN (&uaf_fab
);
3589 vaxc$errno
= status
;
3592 status
= SYS$
CONNECT (&uaf_rab
);
3596 vaxc$errno
= status
;
3599 /* read the requested record - index is in uic */
3600 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3601 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3602 uaf_rab
.rab$b_ksz
= sizeof uic
;
3603 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3604 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3605 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3606 status
= SYS$
GET (&uaf_rab
);
3610 vaxc$errno
= status
;
3613 /* close the User Authorization File */
3614 status
= SYS$
DISCONNECT (&uaf_rab
);
3618 vaxc$errno
= status
;
3621 status
= SYS$
CLOSE (&uaf_fab
);
3625 vaxc$errno
= status
;
3631 static struct passwd retpw
;
3639 /* copy these out first because if the username is 32 chars, the next
3640 section will overwrite the first byte of the UIC */
3641 retpw
.pw_uid
= up
->uaf$w_mem
;
3642 retpw
.pw_gid
= up
->uaf$w_grp
;
3644 /* I suppose this is not the best sytle, to possibly overwrite one
3645 byte beyond the end of the field, but what the heck... */
3646 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3647 while (ptr
[-1] == ' ')
3650 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3652 /* the rest of these are counted ascii strings */
3653 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3654 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3655 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3656 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3657 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3658 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3659 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3660 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3664 #else /* not READ_SYSUAF */
3665 static struct passwd retpw
;
3666 #endif /* not READ_SYSUAF */
3677 unsigned char * full
;
3678 #endif /* READ_SYSUAF */
3683 if ('a' <= *ptr
&& *ptr
<= 'z')
3688 if (!(up
= get_uaf_name (name
)))
3690 return cnv_uaf_pw (up
);
3692 if (strcmp (name
, getenv ("USER")) == 0)
3694 retpw
.pw_uid
= getuid ();
3695 retpw
.pw_gid
= getgid ();
3696 strcpy (retpw
.pw_name
, name
);
3697 if (full
= egetenv ("FULLNAME"))
3698 strcpy (retpw
.pw_gecos
, full
);
3700 *retpw
.pw_gecos
= '\0';
3701 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
3702 *retpw
.pw_shell
= '\0';
3707 #endif /* not READ_SYSUAF */
3717 if (!(up
= get_uaf_uic (uid
)))
3719 return cnv_uaf_pw (up
);
3721 if (uid
== sys_getuid ())
3722 return getpwnam (egetenv ("USER"));
3725 #endif /* not READ_SYSUAF */
3728 /* return total address space available to the current process. This is
3729 the sum of the current p0 size, p1 size and free page table entries
3734 unsigned long free_pages
;
3735 unsigned long frep0va
;
3736 unsigned long frep1va
;
3739 item_code
= JPI$_FREPTECNT
;
3740 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
3743 vaxc$errno
= status
;
3748 item_code
= JPI$_FREP0VA
;
3749 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
3752 vaxc$errno
= status
;
3755 item_code
= JPI$_FREP1VA
;
3756 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
3759 vaxc$errno
= status
;
3763 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
3766 define_logical_name (varname
, string
)
3770 struct dsc$descriptor_s strdsc
=
3771 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
3772 struct dsc$descriptor_s envdsc
=
3773 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3774 struct dsc$descriptor_s lnmdsc
=
3775 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3777 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
3780 delete_logical_name (varname
)
3783 struct dsc$descriptor_s envdsc
=
3784 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3785 struct dsc$descriptor_s lnmdsc
=
3786 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3788 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
3799 error ("execvp system call not implemented");
3807 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
3808 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
3809 char from_esn
[NAM$C_MAXRSS
];
3810 char to_esn
[NAM$C_MAXRSS
];
3812 from_fab
.fab$l_fna
= from
;
3813 from_fab
.fab$b_fns
= strlen (from
);
3814 from_fab
.fab$l_nam
= &from_nam
;
3815 from_fab
.fab$l_fop
= FAB$M_NAM
;
3817 from_nam
.nam$l_esa
= from_esn
;
3818 from_nam
.nam$b_ess
= sizeof from_esn
;
3820 to_fab
.fab$l_fna
= to
;
3821 to_fab
.fab$b_fns
= strlen (to
);
3822 to_fab
.fab$l_nam
= &to_nam
;
3823 to_fab
.fab$l_fop
= FAB$M_NAM
;
3825 to_nam
.nam$l_esa
= to_esn
;
3826 to_nam
.nam$b_ess
= sizeof to_esn
;
3828 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
3834 if (status
== RMS$_DEV
)
3838 vaxc$errno
= status
;
3843 /* This function renames a file like `rename', but it strips
3844 the version number from the "to" filename, such that the "to" file is
3845 will always be a new version. It also sets the file protection once it is
3846 finished. The protection that we will use is stored in fab_final_pro,
3847 and was set when we did a creat_copy_attrs to create the file that we
3850 We could use the chmod function, but Eunichs uses 3 bits per user category
3851 to describe the protection, and VMS uses 4 (write and delete are seperate
3852 bits). To maintain portability, the VMS implementation of `chmod' wires
3853 the W and D bits together. */
3856 static struct fibdef fib
; /* We need this initialized to zero */
3857 char vms_file_written
[NAM$C_MAXRSS
];
3860 rename_sans_version (from
,to
)
3867 struct FAB to_fab
= cc$rms_fab
;
3868 struct NAM to_nam
= cc$rms_nam
;
3869 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
3870 struct dsc$descriptor fib_attr
[2]
3871 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
3872 char to_esn
[NAM$C_MAXRSS
];
3874 $
DESCRIPTOR (disk
,to_esn
);
3876 to_fab
.fab$l_fna
= to
;
3877 to_fab
.fab$b_fns
= strlen (to
);
3878 to_fab
.fab$l_nam
= &to_nam
;
3879 to_fab
.fab$l_fop
= FAB$M_NAM
;
3881 to_nam
.nam$l_esa
= to_esn
;
3882 to_nam
.nam$b_ess
= sizeof to_esn
;
3884 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
3886 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
3887 *(to_nam
.nam$l_ver
) = '\0';
3889 stat
= rename (from
, to_esn
);
3893 strcpy (vms_file_written
, to_esn
);
3895 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
3896 to_fab
.fab$b_fns
= strlen (vms_file_written
);
3898 /* Now set the file protection to the correct value */
3899 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
3901 /* Copy these fields into the fib */
3902 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
3903 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
3904 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
3906 SYS$
CLOSE (&to_fab
, 0, 0);
3908 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
3911 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
3912 0, 0, 0, &fib_attr
, 0);
3915 stat
= SYS$
DASSGN (chan
);
3918 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
3928 unsigned short fid
[3];
3929 char esa
[NAM$C_MAXRSS
];
3932 fab
.fab$l_fop
= FAB$M_OFP
;
3933 fab
.fab$l_fna
= file
;
3934 fab
.fab$b_fns
= strlen (file
);
3935 fab
.fab$l_nam
= &nam
;
3938 nam
.nam$l_esa
= esa
;
3939 nam
.nam$b_ess
= NAM$C_MAXRSS
;
3941 status
= SYS$
PARSE (&fab
);
3942 if ((status
& 1) == 0)
3945 vaxc$errno
= status
;
3948 status
= SYS$
SEARCH (&fab
);
3949 if ((status
& 1) == 0)
3952 vaxc$errno
= status
;
3956 fid
[0] = nam
.nam$w_fid
[0];
3957 fid
[1] = nam
.nam$w_fid
[1];
3958 fid
[2] = nam
.nam$w_fid
[2];
3960 fab
.fab$l_fna
= new;
3961 fab
.fab$b_fns
= strlen (new);
3963 status
= SYS$
PARSE (&fab
);
3964 if ((status
& 1) == 0)
3967 vaxc$errno
= status
;
3971 nam
.nam$w_fid
[0] = fid
[0];
3972 nam
.nam$w_fid
[1] = fid
[1];
3973 nam
.nam$w_fid
[2] = fid
[2];
3975 nam
.nam$l_esa
= nam
.nam$l_name
;
3976 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
3978 status
= SYS$
ENTER (&fab
);
3979 if ((status
& 1) == 0)
3982 vaxc$errno
= status
;
3992 printf ("%s not yet implemented\r\n", badfunc
);
4000 /* Arrange to return a range centered on zero. */
4001 return rand () - (1 << 30);
4012 /* Called from init_sys_modes. */
4017 /* If we're not on an HFT we shouldn't do any of this. We determine
4018 if we are on an HFT by trying to get an HFT error code. If this
4019 call fails, we're not on an HFT. */
4021 if (ioctl (0, HFQERROR
, &junk
) < 0)
4023 #else /* not IBMR2AIX */
4024 if (ioctl (0, HFQEIO
, 0) < 0)
4026 #endif /* not IBMR2AIX */
4028 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4029 as the rubout key's ASCII code. Here this is changed. The bug is that
4030 there's no way to determine the old mapping, so in reset_sys_modes
4031 we need to assume that the normal map had been present. Of course, this
4032 code also doesn't help if on a terminal emulator which doesn't understand
4036 struct hfkeymap keymap
;
4038 buf
.hf_bufp
= (char *)&keymap
;
4039 buf
.hf_buflen
= sizeof (keymap
);
4040 keymap
.hf_nkeys
= 2;
4041 keymap
.hfkey
[0].hf_kpos
= 15;
4042 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4044 keymap
.hfkey
[0].hf_keyidh
= '<';
4045 #else /* not IBMR2AIX */
4046 keymap
.hfkey
[0].hf_page
= '<';
4047 #endif /* not IBMR2AIX */
4048 keymap
.hfkey
[0].hf_char
= 127;
4049 keymap
.hfkey
[1].hf_kpos
= 15;
4050 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4052 keymap
.hfkey
[1].hf_keyidh
= '<';
4053 #else /* not IBMR2AIX */
4054 keymap
.hfkey
[1].hf_page
= '<';
4055 #endif /* not IBMR2AIX */
4056 keymap
.hfkey
[1].hf_char
= 127;
4057 hftctl (0, HFSKBD
, &buf
);
4059 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4061 line_ins_del_ok
= char_ins_del_ok
= 0;
4064 /* Reset the rubout key to backspace. */
4069 struct hfkeymap keymap
;
4073 if (ioctl (0, HFQERROR
, &junk
) < 0)
4075 #else /* not IBMR2AIX */
4076 if (ioctl (0, HFQEIO
, 0) < 0)
4078 #endif /* not IBMR2AIX */
4080 buf
.hf_bufp
= (char *)&keymap
;
4081 buf
.hf_buflen
= sizeof (keymap
);
4082 keymap
.hf_nkeys
= 2;
4083 keymap
.hfkey
[0].hf_kpos
= 15;
4084 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4086 keymap
.hfkey
[0].hf_keyidh
= '<';
4087 #else /* not IBMR2AIX */
4088 keymap
.hfkey
[0].hf_page
= '<';
4089 #endif /* not IBMR2AIX */
4090 keymap
.hfkey
[0].hf_char
= 8;
4091 keymap
.hfkey
[1].hf_kpos
= 15;
4092 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4094 keymap
.hfkey
[1].hf_keyidh
= '<';
4095 #else /* not IBMR2AIX */
4096 keymap
.hfkey
[1].hf_page
= '<';
4097 #endif /* not IBMR2AIX */
4098 keymap
.hfkey
[1].hf_char
= 8;
4099 hftctl (0, HFSKBD
, &buf
);