1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 1986, 1987, 1988 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 */
55 #include <sys/types.h>
61 extern char *sys_errlist
[];
84 #define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */
88 #ifdef BSD /* this is done this way to avoid defined (BSD) || defined (USG)
89 because the vms compiler doesn't grok `defined' */
95 #endif /* not 4.1 bsd */
97 /* Get DGUX definition for FASYNC - DJB */
102 #include <sys/ioctl.h>
112 #include <sys/wait.h>
117 /* Get files for keyboard remapping */
120 #include <sys/devinfo.h>
123 /* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs. */
135 #define TIOCGETP TCGETS
137 #define TIOCSETN TCSETSW
139 #define TIOCSETP TCSETSF
141 #define TCSETAW TCSETS
142 #define TERMINAL struct termios
143 #define OSPEED(str) (str.c_cflag & CBAUD)
144 #define SETOSPEED(str,new) (str.c_cflag = (str.c_cflag & ~CBAUD) | (new))
145 #define TABS_OK(str) ((str.c_oflag & TABDLY) != TAB3)
147 #define tcgetattr(fd, addr) ioctl (fd, TIOCGETP, addr)
148 #endif /* HAVE_TERMIOS */
153 #define TIOCGETP TCGETA
155 /* Wait for output to finish before switching modes.
156 Otherwise screen can be garbaged. */
157 #define TIOCSETN TCSETAW
159 #define TIOCSETP TCSETAF
160 #define TERMINAL struct termio
161 #define OSPEED(str) (str.c_cflag & CBAUD)
162 #define SETOSPEED(str,new) (str.c_cflag = (str.c_cflag & ~CBAUD) | (new))
163 #define TABS_OK(str) ((str.c_oflag & TABDLY) != TAB3)
164 #endif /* HAVE_TERMIO */
166 #ifdef BROKEN_TIOCGETC
167 #undef TIOCGETC /* Avoid confusing some conditionals that test this. */
170 #ifdef BROKEN_TIOCGWINSZ
177 #define TERMINAL struct sgttyb
178 #define OSPEED(str) str.sg_ospeed
179 #define SETOSPEED(str,new) (str.sg_ospeed = (new))
180 #define TABS_OK(str) ((str.sg_flags & XTABS) != XTABS)
182 #define TCSETAW TIOCSETN
184 #endif /* not HAVE_TERMIO */
187 #include <sys/utsname.h>
189 #ifndef MEMORY_IN_STRING_H
194 #include <sys/sioctl.h>
197 #include <sys/stream.h>
198 #include <sys/ptem.h>
200 #endif /* TIOCGWINSZ */
203 #else /* not NEED_TIME_H */
205 #include <sys/time.h>
206 #endif /* HAVE_TIMEVAL */
207 #endif /* not NEED_TIME_H */
211 #include <sys/bsdtty.h>
214 #if defined (HPUX) && defined (HAVE_PTYS)
215 #include <sys/ptyio.h>
228 #ifdef BROKEN_FIONREAD
233 extern int quit_char
;
237 #include "termhooks.h"
238 #include "termchar.h"
239 #include "termopts.h"
240 #include "dispextern.h"
243 #ifdef NONSYSTEM_DIR_LIBRARY
245 #endif /* NONSYSTEM_DIR_LIBRARY */
247 #include "emacssignal.h"
250 #define sigunblock(SIG) \
251 { SIGMASKTYPE omask = sigblock (SIGEMPTYMASK); sigsetmask (omask & ~SIG); }
254 /* Define SIGCHLD as an alias for SIGCLD. There are many conditionals
260 #define SIGCHLD SIGCLD
261 #endif /* not SIGCHLD */
265 static int baud_convert
[] =
270 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
271 1800, 2400, 4800, 9600, 19200, 38400
286 int kbd_input_ast ();
296 static int input_chan
;
297 static $
DESCRIPTOR (input_dsc
, "TT");
298 static int terminator_mask
[2] = { 0, 0 };
300 static struct sensemode
{
302 unsigned char xmit_baud
;
303 unsigned char rcv_baud
;
304 unsigned char crfill
;
305 unsigned char lffill
;
306 unsigned char parity
;
307 unsigned char unused
;
311 unsigned long tt_char
: 24, scr_len
: 8;
312 unsigned long tt2_char
;
314 #define TERMINAL struct sensemode
315 #define OSPEED(str) (str.xmit_baud)
316 #define TABS_OK(str) ((str.tt_char & TT$M_MECHTAB) != 0)
326 /* Discarding input is not safe when the input could contain
327 replies from the X server. So don't do it. */
328 if (read_socket_hook
)
333 SYS$
QIOW (0, input_chan
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
334 &buf
, 0, 0, terminator_mask
, 0, 0);
340 ioctl (0, TIOCFLUSH
, &zero
);
342 #else /* not Apollo */
345 ioctl (0, TIOCSETP
, &buf
);
347 tcsetattr (0, TCSAFLUSH
, &buf
);
349 #endif /* not Apollo */
358 /* Should perhaps error if in batch mode */
360 ioctl (0, TIOCSTI
, &c
);
361 #else /* no TIOCSTI */
362 error ("Cannot stuff terminal input characters in this version of Unix.");
363 #endif /* no TIOCSTI */
377 SYS$
QIOW (0, input_chan
, IO$_SENSEMODE
, &sg
, 0, 0,
378 &sg
.class, 12, 0, 0, 0, 0 );
380 SETOSPEED (sg
, B9600
);
383 ospeed
= OSPEED (sg
);
386 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
387 ? baud_convert
[ospeed
] : 9600);
393 set_exclusive_use (fd
)
397 ioctl (fd
, FIOCLEX
, 0);
399 /* Ok to do nothing if this feature does not exist */
404 wait_without_blocking ()
407 wait3 (0, WNOHANG
| WUNTRACED
, 0);
409 croak ("wait_without_blocking");
411 synch_process_alive
= 0;
414 #endif /* not subprocesses */
416 int wait_debugging
; /* Set nonzero to make following function work under dbx
417 (at least for bsd). */
420 wait_for_termination_signal ()
423 /* Wait for subprocess with process id `pid' to terminate and
424 make sure it will get eliminated (not remain forever as a zombie) */
426 wait_for_termination (pid
)
435 status
= sys$
forcex (&pid
, 0, 0);
439 /* Exit if the process has terminated. */
440 if (!synch_process_alive
)
442 /* Otherwise wait 1 second or until a signal comes in. */
443 signal (SIGALRM
, wait_for_termination_signal
);
447 signal (SIGALRM
, SIG_IGN
);
449 #else /* not subprocesses */
451 if (kill (pid
, 0) < 0)
457 if (status
== pid
|| status
== -1)
460 #endif /* not subprocesses */
467 * flush any pending output
468 * (may flush input as well; it does not matter the way we use it)
471 flush_pending_output (channel
)
475 /* If we try this, we get hit with SIGTTIN, because
476 the child's tty belongs to the child's pgrp. */
479 ioctl (channel
, TCFLSH
, 1);
483 /* 3rd arg should be ignored
484 but some 4.2 kernels actually want the address of an int
485 and nonzero means something different. */
486 ioctl (channel
, TIOCFLUSH
, &zero
);
493 /* Set up the terminal at the other end of a pseudo-terminal that
494 we will be controlling an inferior through.
495 It should not echo or do line-editing, since that is done
496 in Emacs. No padding needed for insertion into an Emacs buffer. */
498 child_setup_tty (out
)
505 s
.c_oflag
|= OPOST
; /* Enable output postprocessing */
506 s
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
507 s
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
); /* No output delays */
508 s
.c_lflag
&= ~ECHO
; /* Disable echo */
509 s
.c_lflag
|= ISIG
; /* Enable signals */
510 s
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on input */
511 s
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on output */
512 /* said to be unnecesary
513 s.c_cc[VMIN] = 1; /* minimum number of characters to accept
514 s.c_cc[VTIME] = 0; /* wait forever for at least 1 character
516 s
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
517 s
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
518 s
.c_cc
[VERASE
] = 0377; /* disable erase processing */
519 s
.c_cc
[VKILL
] = 0377; /* disable kill processing */
521 s
.c_cflag
= (s
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
524 /* AIX enhanced edit loses NULs, so disable it */
527 s
.c_iflag
&= ~ASCEDIT
;
529 /* Also, PTY overloads NUL and BREAK.
530 don't ignore break, but don't signal either, so it looks like NUL. */
531 s
.c_iflag
&= ~IGNBRK
;
532 s
.c_iflag
&= ~BRKINT
;
533 /* QUIT and INTR work better as signals, so disable character forms */
534 s
.c_cc
[VQUIT
] = 0377;
535 s
.c_cc
[VINTR
] = 0377;
538 s
.c_cflag
= (s
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
541 #else /* not HAVE_TERMIO */
542 s
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
| CBREAK
| TANDEM
);
545 #endif /* not HAVE_TERMIO */
548 ioctl (out
, TIOCSETN
, &s
);
550 tcsetattr (out
, TCSADRAIN
, &s
);
560 ioctl (out
, FIOASYNC
, &zero
);
566 #endif /* subprocesses */
576 ioctl (0, TIOCSPGRP
, &pid
);
578 /* Just ignore this for now and hope for the best */
583 /* Record a signal code and the handler for it. */
587 SIGTYPE (*handler
) ();
590 /* Suspend the Emacs process; give terminal to its superior. */
595 unsigned long parent_id
;
597 parent_id
= getppid ();
598 if (parent_id
&& parent_id
!= 0xffffffff)
600 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
601 int status
= LIB$
ATTACH (&parent_id
) & 1;
602 signal (SIGINT
, oldsig
);
611 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
612 d_prompt
.a
= "Emacs: "; /* Just a reminder */
613 lib$
spawn (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
621 killpg (getpgrp (0), SIGTSTP
);
623 kill (-getpgrp (0), SIGTSTP
);
626 #else /* No SIGTSTP */
627 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
628 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
629 kill (getpid (), SIGQUIT
);
631 #else /* No SIGTSTP or USG_JOBCTRL */
633 /* On a system where suspending is not implemented,
634 instead fork a subshell and let it talk directly to the terminal
637 struct save_signal saved_handlers
[5];
639 saved_handlers
[0].code
= SIGINT
;
640 saved_handlers
[1].code
= SIGQUIT
;
641 saved_handlers
[2].code
= SIGTERM
;
643 saved_handlers
[3].code
= SIGIO
;
644 saved_handlers
[4].code
= 0;
646 saved_handlers
[3].code
= 0;
650 error ("Can't spawn subshell");
655 sh
= (char *) egetenv ("SHELL");
658 /* Use our buffer's default directory for the subshell. */
664 /* mentioning current_buffer->buffer would mean including buffer.h,
665 which somehow wedges the hp compiler. So instead... */
667 dir
= intern ("default-directory");
669 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
671 dir
= Fsymbol_value (dir
);
672 if (XTYPE (dir
) != Lisp_String
)
675 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
676 len
= XSTRING (dir
)->size
;
677 bcopy (XSTRING (dir
)->data
, str
, len
);
678 if (str
[len
- 1] != '/') str
[len
++] = '/';
684 close_process_descs (); /* Close Emacs's pipes/ptys */
686 nice (-nice (0)); /* Give the new shell the default piority */
688 write (1, "Can't execute subshell", 22);
692 save_signal_handlers (saved_handlers
);
693 wait_for_termination (pid
);
694 restore_signal_handlers (saved_handlers
);
696 #endif /* no USG_JOBCTRL */
697 #endif /* no SIGTSTP */
701 save_signal_handlers (saved_handlers
)
702 struct save_signal
*saved_handlers
;
704 while (saved_handlers
->code
)
706 saved_handlers
->handler
= signal (saved_handlers
->code
, SIG_IGN
);
711 restore_signal_handlers (saved_handlers
)
712 struct save_signal
*saved_handlers
;
714 while (saved_handlers
->code
)
716 signal (saved_handlers
->code
, saved_handlers
->handler
);
728 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
738 #ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
743 sigunblock (sigmask (SIGWINCH
));
745 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
747 interrupts_deferred
= 0;
753 sigblock (sigmask (SIGWINCH
));
755 fcntl (0, F_SETFL
, old_fcntl_flags
);
756 interrupts_deferred
= 1;
759 #else /* no FASYNC */
760 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
765 ioctl (0, FIOASYNC
, &on
);
766 interrupts_deferred
= 0;
773 ioctl (0, FIOASYNC
, &off
);
774 interrupts_deferred
= 1;
777 #else /* not FASYNC, not STRIDE */
781 croak ("request_sigio");
786 croak ("unrequest_sigio");
793 TERMINAL old_gtty
; /* The initial tty mode bits */
795 int term_initted
; /* 1 if outer tty status has been recorded */
799 #endif /* F_SETOWN */
802 struct ltchars old_ltchars
;
803 #endif /* TIOCGLTC */
806 struct tchars old_tchars
;
809 int lmode
; /* Current lmode value. */
810 /* Needed as global for 4.1 */
811 #endif /* TIOCGETC */
813 /* This may also be defined in stdio,
814 but if so, this does no harm,
815 and using the same name avoids wasting the other one's space. */
817 #if defined (USG) || defined (DGUX)
818 unsigned char _sobuf
[BUFSIZ
+8];
824 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
827 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
834 struct tchars tchars
;
838 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
839 extern int (*interrupt_signal
) ();
848 input_ef
= get_kbd_event_flag ();
849 /* LIB$GET_EF (&input_ef); */
850 SYS$
CLREF (input_ef
);
853 timer_ef
= get_timer_event_flag ();
854 /* LIB$GET_EF (&timer_ef); */
855 SYS$
CLREF (timer_ef
);
858 LIB$
GET_EF (&process_ef
);
859 SYS$
CLREF (process_ef
);
861 if (input_ef
/ 32 != process_ef
/ 32)
862 croak ("Input and process event flags in different clusters.");
863 if (input_ef
/ 32 != timer_ef
/ 32)
864 croak ("Input and process event flags in different clusters.");
865 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
866 ((unsigned) 1 << (process_ef
% 32));
867 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
868 ((unsigned) 1 << (timer_ef
% 32));
869 SYS$
QIOW (0, input_chan
, IO$_SENSEMODE
, &old_gtty
, 0, 0,
870 &old_gtty
.class, 12, 0, 0, 0, 0);
872 sys_access_reinit ();
875 tcgetattr (0, &old_gtty
);
877 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
882 tty
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
883 tty
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
885 tty
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
887 tty
.c_lflag
&= ~ECHO
; /* Disable echo */
888 tty
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
889 tty
.c_lflag
|= ISIG
; /* Enable signals */
892 tty
.c_iflag
|= IXON
; /* Enable start/stop output control */
894 tty
.c_iflag
&= ~IXANY
;
898 tty
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
899 tty
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
900 tty
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
904 tty
.c_cflag
|= CS8
; /* allow 8th bit on input */
905 tty
.c_cflag
&= ~PARENB
;/* Don't check parity */
908 tty
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
909 /* Set up C-g for both SIGQUIT and SIGINT.
910 We don't know which we will get, but we handle both alike
911 so which one it really gives us does not matter. */
912 tty
.c_cc
[VQUIT
] = quit_char
;
913 tty
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
914 tty
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
916 tty
.c_cc
[VSWTCH
] = CDEL
; /* Turn off shell layering use of C-z */
918 #if defined (mips) || defined (HAVE_TCATTR)
919 /* The following code looks like the right thing in general,
920 but it is said to cause a crash on USG V.4.
921 Let's play safe by turning it on only for the MIPS. */
923 tty
.c_cc
[VSUSP
] = CDEL
; /* Turn off mips handling of C-z. */
926 tty
.c_cc
[V_DSUSP
] = CDEL
; /* Turn off mips handling of C-y. */
928 #endif /* mips or HAVE_TCATTR */
931 /* AIX enhanced edit loses NULs, so disable it */
933 tty
.c_iflag
&= ~ASCEDIT
;
935 tty
.c_cc
[VSTRT
] = 255;
936 tty
.c_cc
[VSTOP
] = 255;
937 tty
.c_cc
[VSUSP
] = 255;
938 tty
.c_cc
[VDSUSP
] = 255;
939 #endif /* IBMR2AIX */
940 /* Also, PTY overloads NUL and BREAK.
941 don't ignore break, but don't signal either, so it looks like NUL.
942 This really serves a purpose only if running in an XTERM window
943 or via TELNET or the like, but does no harm elsewhere. */
944 tty
.c_iflag
&= ~IGNBRK
;
945 tty
.c_iflag
&= ~BRKINT
;
947 #else /* if not HAVE_TERMIO */
949 tty
.tt_char
|= TT$M_NOECHO
;
951 tty
.tt_char
|= TT$M_EIGHTBIT
953 tty
.tt_char
|= TT$M_TTSYNC
;
955 tty
.tt_char
&= ~TT$M_TTSYNC
;
956 tty
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
957 #else /* not VMS (BSD, that is) */
958 tty
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
960 tty
.sg_flags
|= ANYP
;
961 tty
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
962 #endif /* not VMS (BSD, that is) */
963 #endif /* not HAVE_TERMIO */
966 SYS$
QIOW (0, input_chan
, IO$_SETMODE
, &input_iosb
, 0, 0,
967 &tty
.class, 12, 0, 0, 0, 0);
970 ioctl (0, TIOCSETN
, &tty
);
972 tcsetattr (0, TCSADRAIN
, &tty
);
976 /* This code added to insure that, if flow-control is not to be used,
977 we have an unlocked screen at the start. */
979 if (!flow_control
) ioctl (0, TCXONC
, 1);
983 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
991 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
992 to be only LF. This is the way that is done. */
995 if (ioctl (1, HFTGETID
, &tty
) != -1)
996 write (1, "\033[20l", 5);
1001 /* If going to use CBREAK mode, we must request C-g to interrupt
1002 and turn off start and stop chars, etc. If not going to use
1003 CBREAK mode, do this anyway so as to turn off local flow
1004 control for user coming over network on 4.2; in this case,
1005 only t_stopc and t_startc really matter. */
1007 ioctl (0, TIOCGLTC
, &old_ltchars
);
1008 #endif /* TIOCGLTC */
1011 ioctl (0, TIOCGETC
, &old_tchars
);
1012 ioctl (0, TIOCLGET
, &old_lmode
);
1014 /* Note: if not using CBREAK mode, it makes no difference how we set this */
1015 tchars
= new_tchars
;
1016 tchars
.t_intrc
= quit_char
;
1019 tchars
.t_startc
= '\021';
1020 tchars
.t_stopc
= '\023';
1022 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
1028 #define LNOFLSH 0100000
1031 lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_lmode
;
1033 ioctl (0, TIOCSETC
, &tchars
);
1034 ioctl (0, TIOCLSET
, &lmode
);
1035 #endif /* TIOCGETC */
1036 #endif /* not HAVE_TERMIO */
1038 ioctl (0, TIOCSLTC
, &new_ltchars
);
1039 #endif /* TIOCGLTC */
1042 /* Appears to do nothing when in PASTHRU mode.
1043 SYS$QIOW (0, input_chan, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1044 interrupt_signal, oob_chars, 0, 0, 0, 0);
1046 queue_kbd_input (0);
1051 #ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
1052 if (interrupt_input
)
1054 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
1055 fcntl (0, F_SETOWN
, getpid ());
1058 #endif /* F_GETOWN */
1059 #endif /* F_SETFL */
1062 if (interrupt_input
)
1066 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1070 /* This symbol is defined on recent USG systems.
1071 Someone says without this call USG won't really buffer the file
1072 even with a call to setbuf. */
1073 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1075 setbuf (stdout
, _sobuf
);
1077 set_terminal_modes ();
1078 if (term_initted
&& no_redraw_on_reenter
)
1080 if (display_completed
)
1081 direct_output_forward_char (0);
1085 screen_garbaged
= 1;
1087 if (SCREENP (Vterminal_screen
))
1088 SCREEN_GARBAGED_P (XSCREEN (Vterminal_screen
)) = 1;
1094 /* Return nonzero if safe to use tabs in output.
1095 At the time this is called, init_sys_modes has not been done yet. */
1103 SYS$
QIOW (0, input_chan
, IO$_SENSEMODE
, &tty
, 0, 0,
1104 &tty
.class, 12, 0, 0, 0, 0);
1106 tcgetattr (0, &tty
);
1107 #endif /* not VMS */
1108 return (TABS_OK (tty
));
1111 /* Get terminal size from system.
1112 Store number of lines into *heightp and width into *widthp.
1113 If zero or a negative number is stored, the value is not valid. */
1115 get_screen_size (widthp
, heightp
)
1116 int *widthp
, *heightp
;
1118 /* Define the 4.3 names in terms of the Sun names
1119 if the latter exist and the former do not. */
1122 #define TIOCGWINSZ TIOCGSIZE
1123 #define winsize ttysize
1124 #define ws_row ts_lines
1125 #define ws_col ts_cols
1129 /* Do it using the 4.3 names if possible. */
1131 struct winsize size
;
1134 if (ioctl (0, TIOCGWINSZ
, &size
) < 0)
1136 *widthp
= size
.ws_col
;
1137 *heightp
= size
.ws_row
;
1138 #else /* not TIOCGWNSIZ */
1141 SYS$
QIOW (0, input_chan
, IO$_SENSEMODE
, &tty
, 0, 0,
1142 &tty
.class, 12, 0, 0, 0, 0);
1143 *widthp
= tty
.scr_wid
;
1144 *heightp
= tty
.scr_len
;
1145 #else /* system doesn't know size */
1148 #endif /* system does not know size */
1149 #endif /* not TIOCGWINSZ */
1161 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1163 cursor_to (SCREEN_HEIGHT (selected_screen
) - 1, 0);
1164 clear_end_of_line (SCREEN_WIDTH (selected_screen
));
1165 /* clear_end_of_line may move the cursor */
1166 cursor_to (SCREEN_HEIGHT (selected_screen
) - 1, 0);
1169 /* HFT devices normally use ^J as a LF/CR. We forced it to
1170 do the LF only. Now, we need to reset it. */
1173 if (ioctl (1, HFTGETID
, &tty
) != -1)
1174 write (1, "\033[20h", 5);
1178 reset_terminal_modes ();
1182 /* Avoid possible loss of output when changing terminal modes. */
1183 fsync (fileno (stdout
));
1187 ioctl (0, TIOCSLTC
, &old_ltchars
);
1188 #endif /* TIOCGLTC */
1191 ioctl (0, TIOCSETC
, &old_tchars
);
1192 ioctl (0, TIOCLSET
, &old_lmode
);
1193 #endif /* TIOCGETC */
1194 #endif /* not HAVE_TERMIO */
1196 #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */
1197 if (interrupt_input
)
1200 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1202 #endif /* F_SETOWN */
1203 #endif /* F_SETFL */
1205 if (interrupt_input
)
1210 SYS$
QIOW (0, input_chan
, IO$_SETMODE
, &input_iosb
, 0, 0,
1211 &old_gtty
.class, 12, 0, 0, 0, 0);
1214 while (ioctl (0, TCSETAW
, &old_gtty
) < 0 && errno
== EINTR
);
1216 while (tcsetattr (0, TCSADRAIN
, &old_gtty
) < 0 && errno
== EINTR
);
1218 #endif /* not VMS */
1227 /* Set up the proper status flags for use of a pty. */
1232 /* I'm told that TOICREMOTE does not mean control chars
1233 "can't be sent" but rather that they don't have
1234 input-editing or signaling effects.
1235 That should be good, because we have other ways
1236 to do those things in Emacs.
1237 However, telnet mode seems not to work on 4.2.
1238 So TIOCREMOTE is turned off now. */
1240 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1241 will hang. In particular, the "timeout" feature (which
1242 causes a read to return if there is no data available)
1243 does this. Also it is known that telnet mode will hang
1244 in such a way that Emacs must be stopped (perhaps this
1245 is the same problem).
1247 If TIOCREMOTE is turned off, then there is a bug in
1248 hp-ux which sometimes loses data. Apparently the
1249 code which blocks the master process when the internal
1250 buffer fills up does not work. Other than this,
1251 though, everything else seems to work fine.
1253 Since the latter lossage is more benign, we may as well
1254 lose that way. -- cph */
1259 ioctl (fd
, FIONBIO
, &on
);
1264 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1265 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1266 /* cause EMACS not to die when it should, i.e., when its own controlling */
1267 /* tty goes away. I've complained to the AIX developers, and they may */
1268 /* change this behavior, but I'm not going to hold my breath. */
1269 signal (SIGHUP
, SIG_IGN
);
1272 #endif /* HAVE_PTYS */
1276 /* Assigning an input channel is done at the start of Emacs execution.
1277 This is called each time Emacs is resumed, also, but does nothing
1278 because input_chain is no longer zero. */
1284 if (input_chan
== 0)
1286 status
= SYS$
ASSIGN (&input_dsc
, &input_chan
, 0, 0);
1292 /* Deassigning the input channel is done before exiting. */
1296 return SYS$
DASSGN (input_chan
);
1301 /* Request reading one character into the keyboard buffer.
1302 This is done as soon as the buffer becomes empty. */
1307 waiting_for_ast
= 0;
1309 status
= SYS$
QIO (0, input_chan
, IO$_READVBLK
,
1310 &input_iosb
, kbd_input_ast
, 1,
1311 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1316 /* Ast routine that is called when keyboard input comes in
1317 in accord with the SYS$QIO above. */
1321 register int c
= -1;
1322 int old_errno
= errno
;
1323 extern int *input_available_clear_word
;
1325 if (waiting_for_ast
)
1326 SYS$
SETEF (input_ef
);
1327 waiting_for_ast
= 0;
1330 if (input_count
== 25)
1332 printf ("Ast # %d,", input_count
);
1333 printf (" iosb = %x, %x, %x, %x",
1334 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1337 if (input_iosb
.offset
)
1341 printf (", char = 0%o", c
);
1353 struct input_event e
;
1354 e
.kind
= ascii_keystroke
;
1355 XSET (buf
[i
].code
, Lisp_Int
, cbuf
[i
]);
1356 e
.screen
= selected_screen
;
1357 kbd_buffer_store_event (&e
);
1360 if (input_available_clear_word
)
1361 *input_available_clear_word
= 0;
1365 /* Wait until there is something in kbd_buffer. */
1367 wait_for_kbd_input ()
1369 extern int have_process_input
, process_exited
;
1371 /* If already something, avoid doing system calls. */
1372 if (detect_input_pending ())
1376 /* Clear a flag, and tell ast routine above to set it. */
1377 SYS$
CLREF (input_ef
);
1378 waiting_for_ast
= 1;
1379 /* Check for timing error: ast happened while we were doing that. */
1380 if (!detect_input_pending ())
1382 /* No timing error: wait for flag to be set. */
1383 set_waiting_for_input (0);
1384 SYS$
WFLOR (input_ef
, input_eflist
);
1385 clear_waiting_for_input (0);
1386 if (!detect_input_pending ())
1387 /* Check for subprocess input availability */
1389 int dsp
= have_process_input
|| process_exited
;
1391 SYS$
CLREF (process_ef
);
1392 if (have_process_input
)
1393 process_command_input ();
1398 update_mode_lines
++;
1399 redisplay_preserve_echo_area ();
1403 waiting_for_ast
= 0;
1406 /* Get rid of any pending QIO, when we are about to suspend
1407 or when we want to throw away pending input.
1408 We wait for a positive sign that the AST routine has run
1409 and therefore there is no I/O request queued when we return.
1410 SYS$SETAST is used to avoid a timing error. */
1415 printf ("At end_kbd_input.\n");
1419 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1421 SYS$
CANCEL (input_chan
);
1426 /* Clear a flag, and tell ast routine above to set it. */
1427 SYS$
CLREF (input_ef
);
1428 waiting_for_ast
= 1;
1430 SYS$
CANCEL (input_chan
);
1432 SYS$
WAITFR (input_ef
);
1433 waiting_for_ast
= 0;
1436 /* Wait for either input available or time interval expiry. */
1438 input_wait_timeout (timeval
)
1439 int timeval
; /* Time to wait, in seconds */
1442 static int zero
= 0;
1443 static int large
= -10000000;
1445 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1447 /* If already something, avoid doing system calls. */
1448 if (detect_input_pending ())
1452 /* Clear a flag, and tell ast routine above to set it. */
1453 SYS$
CLREF (input_ef
);
1454 waiting_for_ast
= 1;
1455 /* Check for timing error: ast happened while we were doing that. */
1456 if (!detect_input_pending ())
1458 /* No timing error: wait for flag to be set. */
1460 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1461 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1463 waiting_for_ast
= 0;
1466 /* The standard `sleep' routine works some other way
1467 and it stops working if you have ever quit out of it.
1468 This one continues to work. */
1474 static int zero
= 0;
1475 static int large
= -10000000;
1477 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1480 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1481 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1496 croak ("request sigio");
1501 croak ("unrequest sigio");
1506 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1511 #ifndef SYSTEM_MALLOC
1518 /* Some systems that cannot dump also cannot implement these. */
1521 * Return the address of the start of the text segment prior to
1522 * doing an unexec. After unexec the return value is undefined.
1523 * See crt0.c for further explanation and _start.
1527 #ifndef CANNOT_UNEXEC
1532 return ((char *) TEXT_START
);
1536 return ((char *) csrt
);
1537 #else /* not GOULD */
1538 extern int _start ();
1539 return ((char *) _start
);
1541 #endif /* TEXT_START */
1543 #endif /* not CANNOT_UNEXEC */
1546 * Return the address of the start of the data segment prior to
1547 * doing an unexec. After unexec the return value is undefined.
1548 * See crt0.c for further information and definition of data_start.
1550 * Apparently, on BSD systems this is etext at startup. On
1551 * USG systems (swapping) this is highly mmu dependent and
1552 * is also dependent on whether or not the program is running
1553 * with shared text. Generally there is a (possibly large)
1554 * gap between end of text and start of data with shared text.
1556 * On Uniplus+ systems with shared text, data starts at a
1557 * fixed address. Each port (from a given oem) is generally
1558 * different, and the specific value of the start of data can
1559 * be obtained via the UniPlus+ specific "uvar" system call,
1560 * however the method outlined in crt0.c seems to be more portable.
1562 * Probably what will have to happen when a USG unexec is available,
1563 * at least on UniPlus, is temacs will have to be made unshared so
1564 * that text and data are contiguous. Then once loadup is complete,
1565 * unexec will produce a shared executable where the data can be
1566 * at the normal shared text boundry and the startofdata variable
1567 * will be patched by unexec to the correct value.
1575 return ((char *) DATA_START
);
1577 extern int data_start
;
1578 return ((char *) &data_start
);
1581 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1584 /* Some systems that cannot dump also cannot implement these. */
1587 * Return the address of the end of the text segment prior to
1588 * doing an unexec. After unexec the return value is undefined.
1595 return ((char *) TEXT_END
);
1598 return ((char *) &etext
);
1603 * Return the address of the end of the data segment prior to
1604 * doing an unexec. After unexec the return value is undefined.
1611 return ((char *) DATA_END
);
1614 return ((char *) &edata
);
1618 #endif /* not CANNOT_DUMP */
1620 /* Get_system_name returns as its value
1621 a string for the Lisp function system-name to return. */
1628 /* Can't have this within the function since `static' is #defined to nothing */
1629 static struct utsname get_system_name_name
;
1636 uname (&get_system_name_name
);
1637 return (get_system_name_name
.nodename
);
1641 #else /* not USG, not 4.1 */
1642 static char system_name_saved
[32];
1645 if ((sp
= egetenv ("SYS$NODE")) == 0)
1651 if ((end
= index (sp
, ':')) != 0)
1654 strcpy (system_name_saved
, sp
);
1656 gethostname (system_name_saved
, sizeof (system_name_saved
));
1657 #endif /* not VMS */
1658 return system_name_saved
;
1659 #endif /* not USG, not 4.1 */
1660 #endif /* not USG */
1666 #ifdef HAVE_X_WINDOWS
1667 /* Cause explanatory error message at compile time,
1668 since the select emulation is not good enough for X. */
1669 int *x
= &x_windows_lose_if_no_select_system_call
;
1672 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1673 * Only checks read descriptors.
1675 /* How long to wait between checking fds in select */
1676 #define SELECT_PAUSE 1
1679 /* For longjmp'ing back to read_input_waiting. */
1681 jmp_buf read_alarm_throw
;
1683 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1684 The read_socket_hook function sets this to 1 while it is waiting. */
1686 int read_alarm_should_throw
;
1694 #else /* not BSD4_1 */
1695 signal (SIGALRM
, SIG_IGN
);
1696 #endif /* not BSD4_1 */
1697 if (read_alarm_should_throw
)
1698 longjmp (read_alarm_throw
, 1);
1701 /* Only rfds are checked. */
1703 select (nfds
, rfds
, wfds
, efds
, timeout
)
1705 int *rfds
, *wfds
, *efds
, *timeout
;
1707 int ravail
= 0, orfds
= 0, old_alarm
;
1708 int timeoutval
= timeout
? *timeout
: 100000;
1709 int *local_timeout
= &timeoutval
;
1710 extern int proc_buffered_char
[];
1711 #ifndef subprocesses
1712 int process_tick
= 0, update_tick
= 0;
1714 extern int process_tick
, update_tick
;
1716 SIGTYPE (*old_trap
) ();
1729 /* If we are looking only for the terminal, with no timeout,
1730 just read it and wait -- that's more efficient. */
1731 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1733 if (! detect_input_pending ())
1734 read_input_waiting ();
1739 /* Once a second, till the timer expires, check all the flagged read
1740 * descriptors to see if any input is available. If there is some then
1741 * set the corresponding bit in the return copy of rfds.
1745 register int to_check
, bit
, fd
;
1749 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1753 int avail
= 0, status
= 0;
1756 avail
= detect_input_pending (); /* Special keyboard handler */
1760 status
= ioctl (fd
, FIONREAD
, &avail
);
1761 #else /* no FIONREAD */
1762 /* Hoping it will return -1 if nothing available
1763 or 0 if all 0 chars requested are read. */
1764 if (proc_buffered_char
[fd
] >= 0)
1768 avail
= read (fd
, &buf
, 1);
1770 proc_buffered_char
[fd
] = buf
;
1772 #endif /* no FIONREAD */
1774 if (status
>= 0 && avail
> 0)
1782 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
1784 old_alarm
= alarm (0);
1785 old_trap
= (int (*)()) signal (SIGALRM
, select_alarm
);
1787 alarm (SELECT_PAUSE
);
1788 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1789 while (select_alarmed
== 0 && *local_timeout
!= 0
1790 && process_tick
== update_tick
)
1792 /* If we are interested in terminal input,
1793 wait by reading the terminal.
1794 That makes instant wakeup for terminal input at least. */
1797 read_input_waiting ();
1798 if (detect_input_pending ())
1804 (*local_timeout
) -= SELECT_PAUSE
;
1805 /* Reset the old alarm if there was one */
1807 signal (SIGALRM
, old_trap
);
1810 /* Reset or forge an interrupt for the original handler. */
1811 old_alarm
-= SELECT_PAUSE
;
1813 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
1817 if (*local_timeout
== 0) /* Stop on timer being cleared */
1823 /* Read keyboard input into the standard buffer,
1824 waiting for at least one character. */
1826 /* Make all keyboard buffers much bigger when using X windows. */
1827 #ifdef HAVE_X_WINDOWS
1828 #define BUFFER_SIZE_FACTOR 16
1830 #define BUFFER_SIZE_FACTOR 1
1833 read_input_waiting ()
1835 char buf
[256 * BUFFER_SIZE_FACTOR
];
1836 struct input_event e
;
1839 if (read_socket_hook
)
1841 read_alarm_should_throw
= 0;
1842 if (! setjmp (read_alarm_throw
))
1843 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
1848 nread
= read (fileno (stdin
), buf
, 1);
1850 /* Scan the chars for C-g and store them in kbd_buffer. */
1851 e
.kind
= ascii_keystroke
;
1852 e
.screen
= selected_screen
;
1853 for (i
= 0; i
< nread
; i
++)
1855 XSET (e
.code
, Lisp_Int
, buf
[i
]);
1856 kbd_buffer_store_event (&e
);
1857 /* Don't look at input that follows a C-g too closely.
1858 This reduces lossage due to autorepeat on C-g. */
1859 if (buf
[i
] == Ctl ('G'))
1864 #endif /* not HAVE_SELECT */
1865 #endif /* not VMS */
1875 * Partially emulate 4.2 open call.
1876 * open is defined as this in 4.1.
1878 * - added by Michael Bloom @ Citicorp/TTI
1883 sys_open (path
, oflag
, mode
)
1887 if (oflag
& O_CREAT
)
1888 return creat (path
, mode
);
1890 return open (path
, oflag
);
1897 lmode
= LINTRUP
| lmode
;
1898 ioctl (0, TIOCLSET
, &lmode
);
1905 lmode
= ~LINTRUP
& lmode
;
1906 ioctl (0, TIOCLSET
, &lmode
);
1913 interrupts_deferred
= 0;
1920 interrupts_deferred
= 1;
1923 /* still inside #ifdef BSD4_1 */
1926 int sigheld
; /* Mask of held signals */
1931 sigheld
|= sigbit (signum
);
1938 sigheld
|= sigbit (signum
);
1944 sigheld
&= ~sigbit (signum
);
1948 sigfree () /* Free all held signals */
1951 for (i
= 0; i
< NSIG
; i
++)
1952 if (sigheld
& sigbit (i
))
1959 return 1 << (i
- 1);
1961 #endif /* subprocesses */
1964 /* POSIX signals support - DJB */
1965 /* Anyone with POSIX signals should have ANSI C declarations */
1967 #ifdef POSIX_SIGNALS
1969 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
1970 static struct sigaction new_action
, old_action
;
1974 #ifdef POSIX_SIGNALS
1975 sigemptyset (&signal_empty_mask
);
1976 sigfillset (&signal_full_mask
);
1980 int (*signal_handler_t
) ();
1983 sys_signal (int signal_number
, signal_handler_t action
)
1986 /* This gets us restartable system calls for efficiency.
1987 The "else" code will works as well. */
1988 return (berk_signal (signal_number
, action
));
1990 sigemptyset (&new_action
.sa_mask
);
1991 new_action
.sa_handler
= action
;
1992 new_action
.sa_flags
= NULL
;
1993 new_action (signal_number
, &new_action
, &old_action
);
1994 return (old_action
.sa_handler
);
1999 sys_sigpause (sigset_t new_mask
)
2001 /* pause emulating berk sigpause... */
2002 sigsuspend (&new_mask
);
2006 /* I'd like to have these guys return pointers to the mask storage in here,
2007 but there'd be trouble if the code was saving multiple masks. I'll be
2008 safe and pass the structure. It normally won't be more than 2 bytes
2012 sys_sigblock (sigset_t new_mask
)
2015 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2020 sys_sigunblock (sigset_t new_mask
)
2023 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2028 sys_sigsetmask (sigset_t new_mask
)
2031 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2035 #endif /* POSIX_SIGNALS */
2042 register int length
;
2046 long max_str
= 65535;
2048 while (length
> max_str
) {
2049 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2054 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2056 while (length
-- > 0)
2058 #endif /* not VMS */
2061 /* Saying `void' requires a declaration, above, where bcopy is used
2062 and that declaration causes pain for systems where bcopy is a macro. */
2063 bcopy (b1
, b2
, length
)
2066 register int length
;
2069 long max_str
= 65535;
2071 while (length
> max_str
) {
2072 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2078 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2080 while (length
-- > 0)
2082 #endif /* not VMS */
2086 bcmp (b1
, b2
, length
) /* This could be a macro! */
2089 register int length
;
2092 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2093 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2095 return STR$
COMPARE (&src1
, &src2
);
2097 while (length
-- > 0)
2102 #endif /* not VMS */
2104 #endif /* not BSTRING */
2108 * The BSD random returns numbers in the range of
2109 * 0 to 2e31 - 1. The USG rand returns numbers in the
2110 * range of 0 to 2e15 - 1. This is probably not significant
2117 /* Arrange to return a range centered on zero. */
2118 return (rand () << 15) + rand () - (1 << 29);
2132 /* Arrange to return a range centered on zero. */
2133 return (rand () << 15) + rand () - (1 << 29);
2143 #ifdef WRONG_NAME_INSQUE
2156 /* If any place else asks for the TERM variable,
2157 allow it to be overridden with the EMACS_TERM variable
2158 before attempting to translate the logical name TERM. As a last
2159 resort, ask for VAX C's special idea of the TERM variable. */
2166 static char buf
[256];
2167 static struct dsc$descriptor_s equiv
2168 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2169 static struct dsc$descriptor_s d_name
2170 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2173 if (!strcmp (name
, "TERM"))
2175 val
= (char *) getenv ("EMACS_TERM");
2180 d_name
.dsc$w_length
= strlen (name
);
2181 d_name
.dsc$a_pointer
= name
;
2182 if (lib$
sys_trnlog (&d_name
, &eqlen
, &equiv
) == 1)
2184 char *str
= (char *) xmalloc (eqlen
+ 1);
2185 bcopy (buf
, str
, eqlen
);
2187 /* This is a storage leak, but a pain to fix. With luck,
2188 no one will ever notice. */
2191 return (char *) getenv (name
);
2196 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2197 to force a call on the debugger from within the image. */
2202 LIB$
SIGNAL (SS$_DEBUG
);
2208 #ifdef LINK_CRTL_SHARE
2209 #ifdef SHAREABLE_LIB_BUG
2210 /* Variables declared noshare and initialized in shareable libraries
2211 cannot be shared. The VMS linker incorrectly forces you to use a private
2212 version which is uninitialized... If not for this "feature", we
2213 could use the C library definition of sys_nerr and sys_errlist. */
2215 char *sys_errlist
[] =
2219 "no such file or directory",
2221 "interrupted system call",
2223 "no such device or address",
2224 "argument list too long",
2225 "exec format error",
2228 "no more processes",
2229 "not enough memory",
2230 "permission denied",
2232 "block device required",
2233 "mount devices busy",
2235 "cross-device link",
2240 "file table overflow",
2241 "too many open files",
2245 "no space left on device",
2247 "read-only file system",
2253 "vax/vms specific error code nontranslatable error"
2255 #endif /* SHAREABLE_LIB_BUG */
2256 #endif /* LINK_CRTL_SHARE */
2259 #ifdef INTERRUPTIBLE_OPEN
2263 sys_open (path
, oflag
, mode
)
2267 register int rtnval
;
2269 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2270 && (errno
== EINTR
));
2274 #endif /* INTERRUPTIBLE_OPEN */
2276 #ifdef INTERRUPTIBLE_CLOSE
2281 register int rtnval
;
2283 while ((rtnval
= close (fd
)) == -1
2284 && (errno
== EINTR
));
2288 #endif /* INTERRUPTIBLE_CLOSE */
2290 #ifdef INTERRUPTIBLE_IO
2293 sys_read (fildes
, buf
, nbyte
)
2298 register int rtnval
;
2300 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2301 && (errno
== EINTR
));
2306 sys_write (fildes
, buf
, nbyte
)
2311 register int rtnval
;
2313 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2314 && (errno
== EINTR
));
2318 #endif /* INTERRUPTIBLE_IO */
2322 * All of the following are for USG.
2324 * On USG systems the system calls are INTERRUPTIBLE by signals
2325 * that the user program has elected to catch. Thus the system call
2326 * must be retried in these cases. To handle this without massive
2327 * changes in the source code, we remap the standard system call names
2328 * to names for our own functions in sysdep.c that do the system call
2329 * with retries. Actually, for portability reasons, it is good
2330 * programming practice, as this example shows, to limit all actual
2331 * system calls to a single occurance in the source. Sure, this
2332 * adds an extra level of function call overhead but it is almost
2333 * always negligible. Fred Fish, Unisoft Systems Inc.
2336 char *sys_siglist
[NSIG
+ 1] =
2339 /* AIX has changed the signals a bit */
2340 "bogus signal", /* 0 */
2341 "hangup", /* 1 SIGHUP */
2342 "interrupt", /* 2 SIGINT */
2343 "quit", /* 3 SIGQUIT */
2344 "illegal instruction", /* 4 SIGILL */
2345 "trace trap", /* 5 SIGTRAP */
2346 "IOT instruction", /* 6 SIGIOT */
2347 "crash likely", /* 7 SIGDANGER */
2348 "floating point exception", /* 8 SIGFPE */
2349 "kill", /* 9 SIGKILL */
2350 "bus error", /* 10 SIGBUS */
2351 "segmentation violation", /* 11 SIGSEGV */
2352 "bad argument to system call", /* 12 SIGSYS */
2353 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2354 "alarm clock", /* 14 SIGALRM */
2355 "software termination signum", /* 15 SIGTERM */
2356 "user defined signal 1", /* 16 SIGUSR1 */
2357 "user defined signal 2", /* 17 SIGUSR2 */
2358 "death of a child", /* 18 SIGCLD */
2359 "power-fail restart", /* 19 SIGPWR */
2360 "bogus signal", /* 20 */
2361 "bogus signal", /* 21 */
2362 "bogus signal", /* 22 */
2363 "bogus signal", /* 23 */
2364 "bogus signal", /* 24 */
2365 "LAN I/O interrupt", /* 25 SIGAIO */
2366 "PTY I/O interrupt", /* 26 SIGPTY */
2367 "I/O intervention required", /* 27 SIGIOINT */
2368 "HFT grant", /* 28 SIGGRANT */
2369 "HFT retract", /* 29 SIGRETRACT */
2370 "HFT sound done", /* 30 SIGSOUND */
2371 "HFT input ready", /* 31 SIGMSG */
2373 "bogus signal", /* 0 */
2374 "hangup", /* 1 SIGHUP */
2375 "interrupt", /* 2 SIGINT */
2376 "quit", /* 3 SIGQUIT */
2377 "illegal instruction", /* 4 SIGILL */
2378 "trace trap", /* 5 SIGTRAP */
2379 "IOT instruction", /* 6 SIGIOT */
2380 "EMT instruction", /* 7 SIGEMT */
2381 "floating point exception", /* 8 SIGFPE */
2382 "kill", /* 9 SIGKILL */
2383 "bus error", /* 10 SIGBUS */
2384 "segmentation violation", /* 11 SIGSEGV */
2385 "bad argument to system call", /* 12 SIGSYS */
2386 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2387 "alarm clock", /* 14 SIGALRM */
2388 "software termination signum", /* 15 SIGTERM */
2389 "user defined signal 1", /* 16 SIGUSR1 */
2390 "user defined signal 2", /* 17 SIGUSR2 */
2391 "death of a child", /* 18 SIGCLD */
2392 "power-fail restart", /* 19 SIGPWR */
2393 #endif /* not AIX */
2398 * Warning, this function may not duplicate 4.2 action properly
2399 * under error conditions.
2403 /* In 4.1, param.h fails to define this. */
2404 #define MAXPATHLEN 1024
2413 char *npath
, *spath
;
2414 extern char *getcwd ();
2416 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2417 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2418 up to first slash. Should be harmless on other systems. */
2419 while (*npath
&& *npath
!= '/')
2421 strcpy (pathname
, npath
);
2422 free (spath
); /* getcwd uses malloc */
2426 #endif /* HAVE_GETWD */
2429 * Emulate rename using unlink/link. Note that this is
2430 * only partially correct. Also, doesn't enforce restriction
2431 * that files be of same type (regular->regular, dir->dir, etc).
2438 if (access (from
, 0) == 0)
2441 if (link (from
, to
) == 0)
2442 if (unlink (from
) == 0)
2448 /* Set priority value to PRIO. */
2451 setpriority (which
, who
, prio
)
2452 int which
, who
, prio
;
2456 nice (prio
- nice (0));
2463 * Substitute fork for vfork on USG flavors.
2471 #endif /* not HAVE_VFORK */
2473 #ifdef MISSING_UTIMES
2475 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2484 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2485 utimbuf structure defined anywhere but in the man page. */
2495 struct timeval tvp
[];
2498 utb
.actime
= tvp
[0].tv_sec
;
2499 utb
.modtime
= tvp
[1].tv_sec
;
2502 #endif /* IRIS_UTIME */
2508 /* HPUX curses library references perror, but as far as we know
2509 it won't be called. Anyway this definition will do for now. */
2515 #endif /* not HAVE_PERROR */
2521 * Emulate BSD dup2. First close newd if it already exists.
2522 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2523 * until we are, then close the unsuccessful ones.
2530 register int fd
, ret
;
2535 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2537 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2544 ret
= dup2 (old
,new);
2550 #endif /* not HAVE_DUP2 */
2553 * Gettimeofday. Simulate as much as possible. Only accurate
2554 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2555 * Only needed when subprocesses are defined.
2560 #ifndef HAVE_GETTIMEOFDAY
2564 gettimeofday (tp
, tzp
)
2566 struct timezone
*tzp
;
2568 extern long time ();
2570 tp
->tv_sec
= time ((long *)0);
2572 tzp
->tz_minuteswest
= -1;
2578 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2581 * This function will go away as soon as all the stubs fixed. (fnf)
2587 printf ("%s not yet implemented\r\n", badfunc
);
2596 char *sys_siglist
[NSIG
+ 1] =
2598 "null signal", /* 0 SIGNULL */
2599 "hangup", /* 1 SIGHUP */
2600 "interrupt", /* 2 SIGINT */
2601 "quit", /* 3 SIGQUIT */
2602 "illegal instruction", /* 4 SIGILL */
2603 "trace trap", /* 5 SIGTRAP */
2604 "abort termination", /* 6 SIGABRT */
2605 "SIGEMT", /* 7 SIGEMT */
2606 "floating point exception", /* 8 SIGFPE */
2607 "kill", /* 9 SIGKILL */
2608 "bus error", /* 10 SIGBUS */
2609 "segmentation violation", /* 11 SIGSEGV */
2610 "bad argument to system call", /* 12 SIGSYS */
2611 "write on a pipe with no reader", /* 13 SIGPIPE */
2612 "alarm clock", /* 14 SIGALRM */
2613 "software termination signal", /* 15 SIGTERM */
2614 "user defined signal 1", /* 16 SIGUSR1 */
2615 "user defined signal 2", /* 17 SIGUSR2 */
2616 "child stopped or terminated", /* 18 SIGCLD */
2617 "power-fail restart", /* 19 SIGPWR */
2618 "window size changed", /* 20 SIGWINCH */
2619 "undefined", /* 21 */
2620 "pollable event occured", /* 22 SIGPOLL */
2621 "sendable stop signal not from tty", /* 23 SIGSTOP */
2622 "stop signal from tty", /* 24 SIGSTP */
2623 "continue a stopped process", /* 25 SIGCONT */
2624 "attempted background tty read", /* 26 SIGTTIN */
2625 "attempted background tty write", /* 27 SIGTTOU */
2626 "undefined", /* 28 */
2627 "undefined", /* 29 */
2628 "undefined", /* 30 */
2629 "undefined", /* 31 */
2630 "undefined", /* 32 */
2631 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2632 "I/O is possible", /* 34 SIGIO */
2633 "exceeded cpu time limit", /* 35 SIGXCPU */
2634 "exceeded file size limit", /* 36 SIGXFSZ */
2635 "virtual time alarm", /* 37 SIGVTALRM */
2636 "profiling time alarm", /* 38 SIGPROF */
2637 "undefined", /* 39 */
2638 "file record locks revoked", /* 40 SIGLOST */
2639 "undefined", /* 41 */
2640 "undefined", /* 42 */
2641 "undefined", /* 43 */
2642 "undefined", /* 44 */
2643 "undefined", /* 45 */
2644 "undefined", /* 46 */
2645 "undefined", /* 47 */
2646 "undefined", /* 48 */
2647 "undefined", /* 49 */
2648 "undefined", /* 50 */
2649 "undefined", /* 51 */
2650 "undefined", /* 52 */
2651 "undefined", /* 53 */
2652 "undefined", /* 54 */
2653 "undefined", /* 55 */
2654 "undefined", /* 56 */
2655 "undefined", /* 57 */
2656 "undefined", /* 58 */
2657 "undefined", /* 59 */
2658 "undefined", /* 60 */
2659 "undefined", /* 61 */
2660 "undefined", /* 62 */
2661 "undefined", /* 63 */
2662 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2668 /* Directory routines for systems that don't have them. */
2670 #ifdef SYSV_SYSTEM_DIR
2677 register DIR *dirp
; /* stream from opendir */
2679 sys_close (dirp
->dd_fd
);
2680 free ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2681 free ((char *) dirp
);
2683 #endif /* not AIX */
2684 #endif /* SYSV_SYSTEM_DIR */
2686 #ifdef NONSYSTEM_DIR_LIBRARY
2690 char *filename
; /* name of directory */
2692 register DIR *dirp
; /* -> malloc'ed storage */
2693 register int fd
; /* file descriptor for read */
2694 struct stat sbuf
; /* result of fstat */
2696 fd
= sys_open (filename
, 0);
2700 if (fstat (fd
, &sbuf
) < 0
2701 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2702 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2705 return 0; /* bad luck today */
2709 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2716 register DIR *dirp
; /* stream from opendir */
2718 sys_close (dirp
->dd_fd
);
2719 free ((char *) dirp
);
2727 ino_t od_ino
; /* inode */
2728 char od_name
[DIRSIZ
]; /* filename */
2730 #endif /* not VMS */
2732 struct direct dir_static
; /* simulated directory contents */
2737 register DIR *dirp
; /* stream from opendir */
2740 register struct olddir
*dp
; /* -> directory data */
2742 register struct dir$_name
*dp
; /* -> directory data */
2743 register struct dir$_version
*dv
; /* -> version data */
2748 if (dirp
->dd_loc
>= dirp
->dd_size
)
2749 dirp
->dd_loc
= dirp
->dd_size
= 0;
2751 if (dirp
->dd_size
== 0 /* refill buffer */
2752 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2756 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
2757 dirp
->dd_loc
+= sizeof (struct olddir
);
2759 if (dp
->od_ino
!= 0) /* not deleted entry */
2761 dir_static
.d_ino
= dp
->od_ino
;
2762 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
2763 dir_static
.d_name
[DIRSIZ
] = '\0';
2764 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2765 dir_static
.d_reclen
= sizeof (struct direct
)
2767 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2768 return &dir_static
; /* -> simulated structure */
2771 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2772 if (dirp
->dd_loc
== 0)
2773 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
2774 : dp
->dir$b_namecount
;
2775 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
2776 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2777 dir_static
.d_namlen
= dp
->dir$b_namecount
;
2778 dir_static
.d_reclen
= sizeof (struct direct
)
2780 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2781 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2782 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
2783 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
2790 /* readdirver is just like readdir except it returns all versions of a file
2791 as separate entries. */
2796 register DIR *dirp
; /* stream from opendir */
2798 register struct dir$_name
*dp
; /* -> directory data */
2799 register struct dir$_version
*dv
; /* -> version data */
2801 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
2802 dirp
->dd_loc
= dirp
->dd_size
= 0;
2804 if (dirp
->dd_size
== 0 /* refill buffer */
2805 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2808 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2809 if (dirp
->dd_loc
== 0)
2810 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
2811 : dp
->dir$b_namecount
;
2812 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
2813 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2814 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
2815 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2816 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2817 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
2818 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2819 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
2825 #endif /* NONSYSTEM_DIR_LIBRARY */
2827 /* Functions for VMS */
2834 /* Return as a string the VMS error string pertaining to STATUS.
2835 Reuses the same static buffer each time it is called. */
2839 int status
; /* VMS status code */
2843 static char buf
[257];
2845 bufadr
[0] = sizeof buf
- 1;
2846 bufadr
[1] = (int) buf
;
2847 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
2848 return "untranslatable VMS error status";
2856 /* The following is necessary because 'access' emulation by VMS C (2.0) does
2857 * not work correctly. (It also doesn't work well in version 2.3.)
2862 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
2863 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
2867 unsigned short s_buflen
;
2868 unsigned short s_code
;
2870 unsigned short *s_retlenadr
;
2874 #define buflen s.s_buflen
2875 #define code s.s_code
2876 #define bufadr s.s_bufadr
2877 #define retlenadr s.s_retlenadr
2879 #define R_OK 4 /* test for read permission */
2880 #define W_OK 2 /* test for write permission */
2881 #define X_OK 1 /* test for execute (search) permission */
2882 #define F_OK 0 /* test for presence of file */
2885 sys_access (path
, mode
)
2889 static char *user
= NULL
;
2892 /* translate possible directory spec into .DIR file name, so brain-dead
2893 * access can treat the directory like a file. */
2894 if (directory_file_name (path
, dir_fn
))
2898 return access (path
, mode
);
2899 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
2905 unsigned short int dummy
;
2907 static int constant
= ACL$C_FILE
;
2908 DESCRIPTOR (path_desc
, path
);
2909 DESCRIPTOR (user_desc
, user
);
2913 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
2916 acces
|= CHP$M_READ
;
2918 acces
|= CHP$M_WRITE
;
2919 itemlst
[0].buflen
= sizeof (int);
2920 itemlst
[0].code
= CHP$_FLAGS
;
2921 itemlst
[0].bufadr
= (char *) &flags
;
2922 itemlst
[0].retlenadr
= &dummy
;
2923 itemlst
[1].buflen
= sizeof (int);
2924 itemlst
[1].code
= CHP$_ACCESS
;
2925 itemlst
[1].bufadr
= (char *) &acces
;
2926 itemlst
[1].retlenadr
= &dummy
;
2927 itemlst
[2].end
= CHP$_END
;
2928 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
2929 return stat
== SS$_NORMAL
? 0 : -1;
2933 #else /* not VMS4_4 */
2936 #define ACE$M_WRITE 2
2937 #define ACE$C_KEYID 1
2939 static unsigned short memid
, grpid
;
2940 static unsigned int uic
;
2942 /* Called from init_sys_modes, so it happens not very often
2943 but at least each time Emacs is loaded. */
2944 sys_access_reinit ()
2950 sys_access (filename
, type
)
2956 int status
, size
, i
, typecode
, acl_controlled
;
2957 unsigned int *aclptr
, *aclend
, aclbuf
[60];
2958 union prvdef prvmask
;
2960 /* Get UIC and GRP values for protection checking. */
2963 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
2966 memid
= uic
& 0xFFFF;
2970 if (type
!= 2) /* not checking write access */
2971 return access (filename
, type
);
2973 /* Check write protection. */
2975 #define CHECKPRIV(bit) (prvmask.bit)
2976 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
2978 /* Find privilege bits */
2979 status
= sys$
setprv (0, 0, 0, prvmask
);
2981 error ("Unable to find privileges: %s", vmserrstr (status
));
2982 if (CHECKPRIV (PRV$V_BYPASS
))
2983 return 0; /* BYPASS enabled */
2985 fab
.fab$b_fac
= FAB$M_GET
;
2986 fab
.fab$l_fna
= filename
;
2987 fab
.fab$b_fns
= strlen (filename
);
2988 fab
.fab$l_xab
= &xab
;
2989 xab
= cc$rms_xabpro
;
2990 xab
.xab$l_aclbuf
= aclbuf
;
2991 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
2992 status
= sys$
open (&fab
, 0, 0);
2995 sys$
close (&fab
, 0, 0);
2996 /* Check system access */
2997 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
2999 /* Check ACL entries, if any */
3001 if (xab
.xab$w_acllen
> 0)
3004 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3005 while (*aclptr
&& aclptr
< aclend
)
3007 size
= (*aclptr
& 0xff) / 4;
3008 typecode
= (*aclptr
>> 8) & 0xff;
3009 if (typecode
== ACE$C_KEYID
)
3010 for (i
= size
- 1; i
> 1; i
--)
3011 if (aclptr
[i
] == uic
)
3014 if (aclptr
[1] & ACE$M_WRITE
)
3015 return 0; /* Write access through ACL */
3017 aclptr
= &aclptr
[size
];
3019 if (acl_controlled
) /* ACL specified, prohibits write access */
3022 /* No ACL entries specified, check normal protection */
3023 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3025 if (WRITEABLE (XAB$V_GRP
) &&
3026 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3027 return 0; /* Group writeable */
3028 if (WRITEABLE (XAB$V_OWN
) &&
3029 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3030 return 0; /* Owner writeable */
3032 return -1; /* Not writeable */
3034 #endif /* not VMS4_4 */
3037 static char vtbuf
[NAM$C_MAXRSS
+1];
3039 /* translate a vms file spec to a unix path */
3041 sys_translate_vms (vfile
)
3052 /* leading device or logical name is a root directory */
3053 if (p
= strchr (vfile
, ':'))
3062 if (*p
== '[' || *p
== '<')
3064 while (*++vfile
!= *p
+ 2)
3068 if (vfile
[-1] == *p
)
3091 static char utbuf
[NAM$C_MAXRSS
+1];
3093 /* translate a unix path to a VMS file spec */
3095 sys_translate_unix (ufile
)
3118 if (index (&ufile
[1], '/'))
3125 if (index (&ufile
[1], '/'))
3132 if (strncmp (ufile
, "./", 2) == 0)
3139 ufile
++; /* skip the dot */
3140 if (index (&ufile
[1], '/'))
3145 else if (strncmp (ufile
, "../", 3) == 0)
3153 ufile
+= 2; /* skip the dots */
3154 if (index (&ufile
[1], '/'))
3179 strcpy (pathname
, egetenv ("PATH"));
3184 if ('a' <= *ptr
&& *ptr
<= 'z')
3193 long item_code
= JPI$_OWNER
;
3194 unsigned long parent_id
;
3197 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3200 vaxc$errno
= status
;
3210 return (getgid () << 16) | getuid ();
3214 sys_read (fildes
, buf
, nbyte
)
3219 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3224 sys_write (fildes
, buf
, nbyte
)
3229 register int nwrote
, rtnval
= 0;
3231 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3237 return rtnval
? rtnval
: -1;
3238 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3239 return rtnval
? rtnval
: -1;
3240 return (rtnval
+ nwrote
);
3245 * VAX/VMS VAX C RTL really loses. It insists that records
3246 * end with a newline (carriage return) character, and if they
3247 * don't it adds one (nice of it isn't it!)
3249 * Thus we do this stupidity below.
3253 sys_write (fildes
, buf
, nbytes
)
3256 unsigned int nbytes
;
3263 fstat (fildes
, &st
);
3269 /* Handle fixed-length files with carriage control. */
3270 if (st
.st_fab_rfm
== FAB$C_FIX
3271 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3273 len
= st
.st_fab_mrs
;
3274 retval
= write (fildes
, p
, min (len
, nbytes
));
3277 retval
++; /* This skips the implied carriage control */
3281 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3282 while (*e
!= '\n' && e
> p
) e
--;
3283 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3284 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3286 retval
= write (fildes
, p
, len
);
3297 /* Create file NEW copying its attributes from file OLD. If
3298 OLD is 0 or does not exist, create based on the value of
3301 /* Protection value the file should ultimately have.
3302 Set by create_copy_attrs, and use by rename_sansversions. */
3303 static unsigned short int fab_final_pro
;
3306 creat_copy_attrs (old
, new)
3309 struct FAB fab
= cc$rms_fab
;
3310 struct XABPRO xabpro
;
3311 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3312 extern int vms_stmlf_recfm
;
3316 fab
.fab$b_fac
= FAB$M_GET
;
3317 fab
.fab$l_fna
= old
;
3318 fab
.fab$b_fns
= strlen (old
);
3319 fab
.fab$l_xab
= (char *) &xabpro
;
3320 xabpro
= cc$rms_xabpro
;
3321 xabpro
.xab$l_aclbuf
= aclbuf
;
3322 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3323 /* Call $OPEN to fill in the fab & xabpro fields. */
3324 if (sys$
open (&fab
, 0, 0) & 1)
3326 sys$
close (&fab
, 0, 0);
3327 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3328 if (xabpro
.xab$w_acllen
> 0)
3330 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3331 /* If the acl buffer was too short, redo open with longer one.
3332 Wouldn't need to do this if there were some system imposed
3333 limit on the size of an ACL, but I can't find any such. */
3335 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3336 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3337 if (sys$
open (&fab
, 0, 0) & 1)
3338 sys$
close (&fab
, 0, 0);
3344 xabpro
.xab$l_aclbuf
= 0;
3349 fab
.fab$l_fna
= new;
3350 fab
.fab$b_fns
= strlen (new);
3354 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3355 fab
.fab$b_rat
= FAB$M_CR
;
3358 /* Set the file protections such that we will be able to manipulate
3359 this file. Once we are done writing and renaming it, we will set
3360 the protections back. */
3362 fab_final_pro
= xabpro
.xab$w_pro
;
3364 sys$
setdfprot (0, &fab_final_pro
);
3365 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3367 /* Create the new file with either default attrs or attrs copied
3369 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3371 sys$
close (&fab
, 0, 0);
3372 /* As this is a "replacement" for creat, return a file descriptor
3373 opened for writing. */
3374 return open (new, O_WRONLY
);
3379 #include <varargs.h>
3382 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3386 sys_creat (va_alist
)
3389 va_list list_incrementor
;
3392 int rfd
; /* related file descriptor */
3393 int fd
; /* Our new file descriptor */
3400 extern int vms_stmlf_recfm
;
3403 va_start (list_incrementor
);
3404 name
= va_arg (list_incrementor
, char *);
3405 mode
= va_arg (list_incrementor
, int);
3407 rfd
= va_arg (list_incrementor
, int);
3408 va_end (list_incrementor
);
3411 /* Use information from the related file descriptor to set record
3412 format of the newly created file. */
3413 fstat (rfd
, &st_buf
);
3414 switch (st_buf
.st_fab_rfm
)
3417 strcpy (rfm
, "rfm = fix");
3418 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3419 strcpy (rat
, "rat = ");
3420 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3422 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3423 strcat (rat
, "ftn");
3424 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3425 strcat (rat
, "prn");
3426 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3427 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3428 strcat (rat
, ", blk");
3430 strcat (rat
, "blk");
3431 return creat (name
, 0, rfm
, rat
, mrs
);
3434 strcpy (rfm
, "rfm = vfc");
3435 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3436 strcpy (rat
, "rat = ");
3437 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3439 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3440 strcat (rat
, "ftn");
3441 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3442 strcat (rat
, "prn");
3443 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3444 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3445 strcat (rat
, ", blk");
3447 strcat (rat
, "blk");
3448 return creat (name
, 0, rfm
, rat
, fsz
);
3451 strcpy (rfm
, "rfm = stm");
3455 strcpy (rfm
, "rfm = stmcr");
3459 strcpy (rfm
, "rfm = stmlf");
3463 strcpy (rfm
, "rfm = udf");
3467 strcpy (rfm
, "rfm = var");
3470 strcpy (rat
, "rat = ");
3471 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3473 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3474 strcat (rat
, "ftn");
3475 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3476 strcat (rat
, "prn");
3477 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3478 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3479 strcat (rat
, ", blk");
3481 strcat (rat
, "blk");
3485 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3486 strcpy (rat
, "rat=cr");
3488 /* Until the VAX C RTL fixes the many bugs with modes, always use
3489 mode 0 to get the user's default protection. */
3490 fd
= creat (name
, 0, rfm
, rat
);
3491 if (fd
< 0 && errno
== EEXIST
)
3493 if (unlink (name
) < 0)
3494 report_file_error ("delete", build_string (name
));
3495 fd
= creat (name
, 0, rfm
, rat
);
3501 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3502 sys_fwrite (ptr
, size
, num
, fp
)
3503 register char * ptr
;
3506 register int tot
= num
* size
;
3513 * The VMS C library routine creat actually creates a new version of an
3514 * existing file rather than truncating the old version. There are times
3515 * when this is not the desired behavior, for instance, when writing an
3516 * auto save file (you only want one version), or when you don't have
3517 * write permission in the directory containing the file (but the file
3518 * itself is writable). Hence this routine, which is equivalent to
3519 * "close (creat (fn, 0));" on Unix if fn already exists.
3525 struct FAB xfab
= cc$rms_fab
;
3526 struct RAB xrab
= cc$rms_rab
;
3529 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3530 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3531 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3532 xfab
.fab$l_fna
= fn
;
3533 xfab
.fab$b_fns
= strlen (fn
);
3534 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3536 xrab
.rab$l_fab
= &xfab
;
3538 /* This gibberish opens the file, positions to the first record, and
3539 deletes all records from there until the end of file. */
3540 if ((sys$
open (&xfab
) & 01) == 01)
3542 if ((sys$
connect (&xrab
) & 01) == 01 &&
3543 (sys$
find (&xrab
) & 01) == 01 &&
3544 (sys$
truncate (&xrab
) & 01) == 01)
3555 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3556 SYSPRV or a readable SYSUAF.DAT. */
3562 * Routine to read the VMS User Authorization File and return
3563 * a specific user's record.
3566 static struct UAF retuaf
;
3569 get_uaf_name (uname
)
3576 uaf_fab
= cc$rms_fab
;
3577 uaf_rab
= cc$rms_rab
;
3578 /* initialize fab fields */
3579 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3580 uaf_fab
.fab$b_fns
= 21;
3581 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3582 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3583 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3584 /* initialize rab fields */
3585 uaf_rab
.rab$l_fab
= &uaf_fab
;
3586 /* open the User Authorization File */
3587 status
= sys$
open (&uaf_fab
);
3591 vaxc$errno
= status
;
3594 status
= sys$
connect (&uaf_rab
);
3598 vaxc$errno
= status
;
3601 /* read the requested record - index is in uname */
3602 uaf_rab
.rab$l_kbf
= uname
;
3603 uaf_rab
.rab$b_ksz
= strlen (uname
);
3604 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3605 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3606 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3607 status
= sys$
get (&uaf_rab
);
3611 vaxc$errno
= status
;
3614 /* close the User Authorization File */
3615 status
= sys$
disconnect (&uaf_rab
);
3619 vaxc$errno
= status
;
3622 status
= sys$
close (&uaf_fab
);
3626 vaxc$errno
= status
;
3640 uaf_fab
= cc$rms_fab
;
3641 uaf_rab
= cc$rms_rab
;
3642 /* initialize fab fields */
3643 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3644 uaf_fab
.fab$b_fns
= 21;
3645 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3646 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3647 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3648 /* initialize rab fields */
3649 uaf_rab
.rab$l_fab
= &uaf_fab
;
3650 /* open the User Authorization File */
3651 status
= sys$
open (&uaf_fab
);
3655 vaxc$errno
= status
;
3658 status
= sys$
connect (&uaf_rab
);
3662 vaxc$errno
= status
;
3665 /* read the requested record - index is in uic */
3666 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3667 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3668 uaf_rab
.rab$b_ksz
= sizeof uic
;
3669 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3670 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3671 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3672 status
= sys$
get (&uaf_rab
);
3676 vaxc$errno
= status
;
3679 /* close the User Authorization File */
3680 status
= sys$
disconnect (&uaf_rab
);
3684 vaxc$errno
= status
;
3687 status
= sys$
close (&uaf_fab
);
3691 vaxc$errno
= status
;
3697 static struct passwd retpw
;
3705 /* copy these out first because if the username is 32 chars, the next
3706 section will overwrite the first byte of the UIC */
3707 retpw
.pw_uid
= up
->uaf$w_mem
;
3708 retpw
.pw_gid
= up
->uaf$w_grp
;
3710 /* I suppose this is not the best sytle, to possibly overwrite one
3711 byte beyond the end of the field, but what the heck... */
3712 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3713 while (ptr
[-1] == ' ')
3716 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3718 /* the rest of these are counted ascii strings */
3719 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3720 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3721 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3722 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3723 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3724 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3725 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3726 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3730 #else /* not READ_SYSUAF */
3731 static struct passwd retpw
;
3732 #endif /* not READ_SYSUAF */
3743 unsigned char * full
;
3744 #endif /* READ_SYSUAF */
3749 if ('a' <= *ptr
&& *ptr
<= 'z')
3754 if (!(up
= get_uaf_name (name
)))
3756 return cnv_uaf_pw (up
);
3758 if (strcmp (name
, getenv ("USER")) == 0)
3760 retpw
.pw_uid
= getuid ();
3761 retpw
.pw_gid
= getgid ();
3762 strcpy (retpw
.pw_name
, name
);
3763 if (full
= egetenv ("FULLNAME"))
3764 strcpy (retpw
.pw_gecos
, full
);
3766 *retpw
.pw_gecos
= '\0';
3767 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
3768 *retpw
.pw_shell
= '\0';
3773 #endif /* not READ_SYSUAF */
3783 if (!(up
= get_uaf_uic (uid
)))
3785 return cnv_uaf_pw (up
);
3787 if (uid
== sys_getuid ())
3788 return getpwnam (egetenv ("USER"));
3791 #endif /* not READ_SYSUAF */
3794 /* return total address space available to the current process. This is
3795 the sum of the current p0 size, p1 size and free page table entries
3800 unsigned long free_pages
;
3801 unsigned long frep0va
;
3802 unsigned long frep1va
;
3805 item_code
= JPI$_FREPTECNT
;
3806 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
3809 vaxc$errno
= status
;
3814 item_code
= JPI$_FREP0VA
;
3815 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
3818 vaxc$errno
= status
;
3821 item_code
= JPI$_FREP1VA
;
3822 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
3825 vaxc$errno
= status
;
3829 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
3832 define_logical_name (varname
, string
)
3836 struct dsc$descriptor_s strdsc
=
3837 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
3838 struct dsc$descriptor_s envdsc
=
3839 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3840 struct dsc$descriptor_s lnmdsc
=
3841 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3843 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
3846 delete_logical_name (varname
)
3849 struct dsc$descriptor_s envdsc
=
3850 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3851 struct dsc$descriptor_s lnmdsc
=
3852 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3854 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
3868 error ("execvp system call not implemented");
3876 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
3877 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
3878 char from_esn
[NAM$C_MAXRSS
];
3879 char to_esn
[NAM$C_MAXRSS
];
3881 from_fab
.fab$l_fna
= from
;
3882 from_fab
.fab$b_fns
= strlen (from
);
3883 from_fab
.fab$l_nam
= &from_nam
;
3884 from_fab
.fab$l_fop
= FAB$M_NAM
;
3886 from_nam
.nam$l_esa
= from_esn
;
3887 from_nam
.nam$b_ess
= sizeof from_esn
;
3889 to_fab
.fab$l_fna
= to
;
3890 to_fab
.fab$b_fns
= strlen (to
);
3891 to_fab
.fab$l_nam
= &to_nam
;
3892 to_fab
.fab$l_fop
= FAB$M_NAM
;
3894 to_nam
.nam$l_esa
= to_esn
;
3895 to_nam
.nam$b_ess
= sizeof to_esn
;
3897 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
3903 if (status
== RMS$_DEV
)
3907 vaxc$errno
= status
;
3912 /* This function renames a file like `rename', but it strips
3913 the version number from the "to" filename, such that the "to" file is
3914 will always be a new version. It also sets the file protection once it is
3915 finished. The protection that we will use is stored in fab_final_pro,
3916 and was set when we did a creat_copy_attrs to create the file that we
3919 We could use the chmod function, but Eunichs uses 3 bits per user category
3920 to describe the protection, and VMS uses 4 (write and delete are seperate
3921 bits). To maintain portability, the VMS implementation of `chmod' wires
3922 the W and D bits together. */
3925 static struct fibdef fib
; /* We need this initialized to zero */
3926 char vms_file_written
[NAM$C_MAXRSS
];
3929 rename_sans_version (from
,to
)
3936 struct FAB to_fab
= cc$rms_fab
;
3937 struct NAM to_nam
= cc$rms_nam
;
3938 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
3939 struct dsc$descriptor fib_attr
[2]
3940 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
3941 char to_esn
[NAM$C_MAXRSS
];
3943 $
DESCRIPTOR (disk
,to_esn
);
3945 to_fab
.fab$l_fna
= to
;
3946 to_fab
.fab$b_fns
= strlen (to
);
3947 to_fab
.fab$l_nam
= &to_nam
;
3948 to_fab
.fab$l_fop
= FAB$M_NAM
;
3950 to_nam
.nam$l_esa
= to_esn
;
3951 to_nam
.nam$b_ess
= sizeof to_esn
;
3953 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
3955 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
3956 *(to_nam
.nam$l_ver
) = '\0';
3958 stat
= rename (from
, to_esn
);
3962 strcpy (vms_file_written
, to_esn
);
3964 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
3965 to_fab
.fab$b_fns
= strlen (vms_file_written
);
3967 /* Now set the file protection to the correct value */
3968 sys$
open (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
3970 /* Copy these fields into the fib */
3971 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
3972 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
3973 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
3975 sys$
close (&to_fab
, 0, 0);
3977 stat
= sys$
assign (&disk
, &chan
, 0, 0); /* open a channel to the disk */
3980 stat
= sys$
qiow (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
3981 0, 0, 0, &fib_attr
, 0);
3984 stat
= sys$
dassgn (chan
);
3987 strcpy (vms_file_written
, to_esn
); /* We will write this to the screen*/
3997 unsigned short fid
[3];
3998 char esa
[NAM$C_MAXRSS
];
4001 fab
.fab$l_fop
= FAB$M_OFP
;
4002 fab
.fab$l_fna
= file
;
4003 fab
.fab$b_fns
= strlen (file
);
4004 fab
.fab$l_nam
= &nam
;
4007 nam
.nam$l_esa
= esa
;
4008 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4010 status
= SYS$
PARSE (&fab
);
4011 if ((status
& 1) == 0)
4014 vaxc$errno
= status
;
4017 status
= SYS$
SEARCH (&fab
);
4018 if ((status
& 1) == 0)
4021 vaxc$errno
= status
;
4025 fid
[0] = nam
.nam$w_fid
[0];
4026 fid
[1] = nam
.nam$w_fid
[1];
4027 fid
[2] = nam
.nam$w_fid
[2];
4029 fab
.fab$l_fna
= new;
4030 fab
.fab$b_fns
= strlen (new);
4032 status
= SYS$
PARSE (&fab
);
4033 if ((status
& 1) == 0)
4036 vaxc$errno
= status
;
4040 nam
.nam$w_fid
[0] = fid
[0];
4041 nam
.nam$w_fid
[1] = fid
[1];
4042 nam
.nam$w_fid
[2] = fid
[2];
4044 nam
.nam$l_esa
= nam
.nam$l_name
;
4045 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4047 status
= SYS$
ENTER (&fab
);
4048 if ((status
& 1) == 0)
4051 vaxc$errno
= status
;
4061 printf ("%s not yet implemented\r\n", badfunc
);
4069 /* Arrange to return a range centered on zero. */
4070 return rand () - (1 << 30);
4081 /* Called from init_sys_modes. */
4086 /* If we're not on an HFT we shouldn't do any of this. We determine
4087 if we are on an HFT by trying to get an HFT error code. If this
4088 call fails, we're not on an HFT. */
4090 if (ioctl (0, HFQERROR
, &junk
) < 0)
4092 #else /* not IBMR2AIX */
4093 if (ioctl (0, HFQEIO
, 0) < 0)
4095 #endif /* not IBMR2AIX */
4097 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4098 as the rubout key's ASCII code. Here this is changed. The bug is that
4099 there's no way to determine the old mapping, so in reset_sys_modes
4100 we need to assume that the normal map had been present. Of course, this
4101 code also doesn't help if on a terminal emulator which doesn't understand
4105 struct hfkeymap keymap
;
4107 buf
.hf_bufp
= (char *)&keymap
;
4108 buf
.hf_buflen
= sizeof (keymap
);
4109 keymap
.hf_nkeys
= 2;
4110 keymap
.hfkey
[0].hf_kpos
= 15;
4111 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4113 keymap
.hfkey
[0].hf_keyidh
= '<';
4114 #else /* not IBMR2AIX */
4115 keymap
.hfkey
[0].hf_page
= '<';
4116 #endif /* not IBMR2AIX */
4117 keymap
.hfkey
[0].hf_char
= 127;
4118 keymap
.hfkey
[1].hf_kpos
= 15;
4119 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4121 keymap
.hfkey
[1].hf_keyidh
= '<';
4122 #else /* not IBMR2AIX */
4123 keymap
.hfkey
[1].hf_page
= '<';
4124 #endif /* not IBMR2AIX */
4125 keymap
.hfkey
[1].hf_char
= 127;
4126 hftctl (0, HFSKBD
, &buf
);
4128 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4130 line_ins_del_ok
= char_ins_del_ok
= 0;
4133 /* Reset the rubout key to backspace. */
4138 struct hfkeymap keymap
;
4142 if (ioctl (0, HFQERROR
, &junk
) < 0)
4144 #else /* not IBMR2AIX */
4145 if (ioctl (0, HFQEIO
, 0) < 0)
4147 #endif /* not IBMR2AIX */
4149 buf
.hf_bufp
= (char *)&keymap
;
4150 buf
.hf_buflen
= sizeof (keymap
);
4151 keymap
.hf_nkeys
= 2;
4152 keymap
.hfkey
[0].hf_kpos
= 15;
4153 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4155 keymap
.hfkey
[0].hf_keyidh
= '<';
4156 #else /* not IBMR2AIX */
4157 keymap
.hfkey
[0].hf_page
= '<';
4158 #endif /* not IBMR2AIX */
4159 keymap
.hfkey
[0].hf_char
= 8;
4160 keymap
.hfkey
[1].hf_kpos
= 15;
4161 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4163 keymap
.hfkey
[1].hf_keyidh
= '<';
4164 #else /* not IBMR2AIX */
4165 keymap
.hfkey
[1].hf_page
= '<';
4166 #endif /* not IBMR2AIX */
4167 keymap
.hfkey
[1].hf_char
= 8;
4168 hftctl (0, HFSKBD
, &buf
);