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 */
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>
109 #include <sys/wait.h>
113 #ifdef BROKEN_TIOCGWINSZ
118 #include <sys/utsname.h>
120 #ifndef MEMORY_IN_STRING_H
125 #include <sys/sioctl.h>
128 #include <sys/stream.h>
129 #include <sys/ptem.h>
131 #endif /* TIOCGWINSZ */
134 extern int quit_char
;
138 #include "termhooks.h"
139 #include "termchar.h"
140 #include "termopts.h"
141 #include "dispextern.h"
144 #ifdef NONSYSTEM_DIR_LIBRARY
146 #endif /* NONSYSTEM_DIR_LIBRARY */
148 #include "syssignal.h"
151 static int baud_convert
[] =
156 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
157 1800, 2400, 4800, 9600, 19200, 38400
163 /* The file descriptor for Emacs's input terminal.
164 Under Unix, this is always left zero;
165 under VMS, we place the input channel number here.
166 This allows us to write more code that works for both VMS and Unix. */
178 int kbd_input_ast ();
188 static $
DESCRIPTOR (input_dsc
, "TT");
189 static int terminator_mask
[2] = { 0, 0 };
191 static struct sensemode
{
193 unsigned char xmit_baud
;
194 unsigned char rcv_baud
;
195 unsigned char crfill
;
196 unsigned char lffill
;
197 unsigned char parity
;
198 unsigned char unused
;
202 unsigned long tt_char
: 24, scr_len
: 8;
203 unsigned long tt2_char
;
209 struct emacs_tty buf
;
214 /* Discarding input is not safe when the input could contain
215 replies from the X server. So don't do it. */
216 if (read_socket_hook
)
221 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
222 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
228 ioctl (0, TIOCFLUSH
, &zero
);
230 #else /* not Apollo */
231 EMACS_GET_TTY (input_fd
, &buf
);
232 EMACS_SET_TTY (input_fd
, &buf
, 0);
233 #endif /* not Apollo */
242 /* Should perhaps error if in batch mode */
244 ioctl (0, TIOCSTI
, &c
);
245 #else /* no TIOCSTI */
246 error ("Cannot stuff terminal input characters in this version of Unix.");
247 #endif /* no TIOCSTI */
261 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
262 &sg
.class, 12, 0, 0, 0, 0 );
263 ospeed
= sg
.xmit_baud
;
268 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
270 ospeed
= sg
.c_cflag
& CBAUD
;
271 #else /* neither VMS nor TERMIO */
275 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
277 ospeed
= sg
.c_cflag
& CBAUD
;
278 #else /* neither VMS nor TERMIO nor TERMIOS */
281 sg
.sg_ospeed
= B9600
;
282 ioctl (0, TIOCGETP
, &sg
);
283 ospeed
= sg
.sg_ospeed
;
284 #endif /* not HAVE_TERMIOS */
285 #endif /* not HAVE_TERMIO */
289 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
290 ? baud_convert
[ospeed
] : 9600);
296 set_exclusive_use (fd
)
300 ioctl (fd
, FIOCLEX
, 0);
302 /* Ok to do nothing if this feature does not exist */
307 wait_without_blocking ()
310 wait3 (0, WNOHANG
| WUNTRACED
, 0);
312 croak ("wait_without_blocking");
314 synch_process_alive
= 0;
317 #endif /* not subprocesses */
319 int wait_debugging
; /* Set nonzero to make following function work under dbx
320 (at least for bsd). */
323 wait_for_termination_signal ()
326 /* Wait for subprocess with process id `pid' to terminate and
327 make sure it will get eliminated (not remain forever as a zombie) */
329 wait_for_termination (pid
)
338 status
= sys$
forcex (&pid
, 0, 0);
342 /* Exit if the process has terminated. */
343 if (!synch_process_alive
)
345 /* Otherwise wait 1 second or until a signal comes in. */
346 signal (SIGALRM
, wait_for_termination_signal
);
350 signal (SIGALRM
, SIG_IGN
);
352 #else /* not subprocesses */
354 if (kill (pid
, 0) < 0)
360 if (status
== pid
|| status
== -1)
363 #endif /* not subprocesses */
370 * flush any pending output
371 * (may flush input as well; it does not matter the way we use it)
374 flush_pending_output (channel
)
378 /* If we try this, we get hit with SIGTTIN, because
379 the child's tty belongs to the child's pgrp. */
382 ioctl (channel
, TCFLSH
, 1);
386 /* 3rd arg should be ignored
387 but some 4.2 kernels actually want the address of an int
388 and nonzero means something different. */
389 ioctl (channel
, TIOCFLUSH
, &zero
);
396 /* Set up the terminal at the other end of a pseudo-terminal that
397 we will be controlling an inferior through.
398 It should not echo or do line-editing, since that is done
399 in Emacs. No padding needed for insertion into an Emacs buffer. */
401 child_setup_tty (out
)
406 EMACS_GET_TTY (out
, &s
);
409 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
410 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
411 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
412 /* No output delays */
413 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
414 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
415 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
417 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
420 /* Said to be unnecesary: */
421 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
422 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
425 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
426 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
427 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
428 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
431 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
435 /* AIX enhanced edit loses NULs, so disable it */
438 s
.main
.c_iflag
&= ~ASCEDIT
;
440 /* Also, PTY overloads NUL and BREAK.
441 don't ignore break, but don't signal either, so it looks like NUL. */
442 s
.main
.c_iflag
&= ~IGNBRK
;
443 s
.main
.c_iflag
&= ~BRKINT
;
444 /* QUIT and INTR work better as signals, so disable character forms */
445 s
.main
.c_cc
[VQUIT
] = 0377;
446 s
.main
.c_cc
[VINTR
] = 0377;
447 s
.main
.c_cc
[VEOL
] = 0377;
448 s
.main
.c_lflag
&= ~ISIG
;
449 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
452 #else /* not HAVE_TERMIO */
454 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
456 s
.main
.sg_erase
= 0377;
457 s
.main
.sg_kill
= 0377;
459 #endif /* not HAVE_TERMIO */
461 EMACS_SET_TTY (out
, &s
, 0);
470 ioctl (out
, FIOASYNC
, &zero
);
476 #endif /* subprocesses */
482 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
485 /* Record a signal code and the handler for it. */
489 SIGTYPE (*handler
) ();
492 /* Suspend the Emacs process; give terminal to its superior. */
497 unsigned long parent_id
;
499 parent_id
= getppid ();
500 if (parent_id
&& parent_id
!= 0xffffffff)
502 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
503 int status
= LIB$
ATTACH (&parent_id
) & 1;
504 signal (SIGINT
, oldsig
);
513 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
514 d_prompt
.a
= "Emacs: "; /* Just a reminder */
515 lib$
spawn (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
522 EMACS_KILLPG (getpgrp (0), SIGTSTP
);
524 #else /* No SIGTSTP */
525 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
526 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
527 kill (getpid (), SIGQUIT
);
529 #else /* No SIGTSTP or USG_JOBCTRL */
531 /* On a system where suspending is not implemented,
532 instead fork a subshell and let it talk directly to the terminal
535 struct save_signal saved_handlers
[5];
537 saved_handlers
[0].code
= SIGINT
;
538 saved_handlers
[1].code
= SIGQUIT
;
539 saved_handlers
[2].code
= SIGTERM
;
541 saved_handlers
[3].code
= SIGIO
;
542 saved_handlers
[4].code
= 0;
544 saved_handlers
[3].code
= 0;
548 error ("Can't spawn subshell");
553 sh
= (char *) egetenv ("SHELL");
556 /* Use our buffer's default directory for the subshell. */
562 /* mentioning current_buffer->buffer would mean including buffer.h,
563 which somehow wedges the hp compiler. So instead... */
565 dir
= intern ("default-directory");
567 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
569 dir
= Fsymbol_value (dir
);
570 if (XTYPE (dir
) != Lisp_String
)
573 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
574 len
= XSTRING (dir
)->size
;
575 bcopy (XSTRING (dir
)->data
, str
, len
);
576 if (str
[len
- 1] != '/') str
[len
++] = '/';
582 close_process_descs (); /* Close Emacs's pipes/ptys */
584 nice (-nice (0)); /* Give the new shell the default piority */
586 write (1, "Can't execute subshell", 22);
590 save_signal_handlers (saved_handlers
);
591 wait_for_termination (pid
);
592 restore_signal_handlers (saved_handlers
);
594 #endif /* no USG_JOBCTRL */
595 #endif /* no SIGTSTP */
599 save_signal_handlers (saved_handlers
)
600 struct save_signal
*saved_handlers
;
602 while (saved_handlers
->code
)
604 saved_handlers
->handler
= signal (saved_handlers
->code
, SIG_IGN
);
609 restore_signal_handlers (saved_handlers
)
610 struct save_signal
*saved_handlers
;
612 while (saved_handlers
->code
)
614 signal (saved_handlers
->code
, saved_handlers
->handler
);
626 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
636 #ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
641 sigunblock (sigmask (SIGWINCH
));
643 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
645 interrupts_deferred
= 0;
651 sigblock (sigmask (SIGWINCH
));
653 fcntl (0, F_SETFL
, old_fcntl_flags
);
654 interrupts_deferred
= 1;
657 #else /* no FASYNC */
658 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
663 ioctl (0, FIOASYNC
, &on
);
664 interrupts_deferred
= 0;
671 ioctl (0, FIOASYNC
, &off
);
672 interrupts_deferred
= 1;
675 #else /* not FASYNC, not STRIDE */
679 croak ("request_sigio");
684 croak ("unrequest_sigio");
691 /* The initial tty mode bits */
692 struct emacs_tty old_tty
;
694 int term_initted
; /* 1 if outer tty status has been recorded */
697 /* BSD 4.1 needs to keep track of the lmode bits in order to start
704 #endif /* F_SETOWN */
706 /* This may also be defined in stdio,
707 but if so, this does no harm,
708 and using the same name avoids wasting the other one's space. */
710 #if defined (USG) || defined (DGUX)
711 unsigned char _sobuf
[BUFSIZ
+8];
717 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
720 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
725 struct emacs_tty tty
;
729 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
730 extern int (*interrupt_signal
) ();
739 input_ef
= get_kbd_event_flag ();
740 /* LIB$GET_EF (&input_ef); */
741 SYS$
CLREF (input_ef
);
744 timer_ef
= get_timer_event_flag ();
745 /* LIB$GET_EF (&timer_ef); */
746 SYS$
CLREF (timer_ef
);
749 LIB$
GET_EF (&process_ef
);
750 SYS$
CLREF (process_ef
);
752 if (input_ef
/ 32 != process_ef
/ 32)
753 croak ("Input and process event flags in different clusters.");
754 if (input_ef
/ 32 != timer_ef
/ 32)
755 croak ("Input and process event flags in different clusters.");
756 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
757 ((unsigned) 1 << (process_ef
% 32));
758 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
759 ((unsigned) 1 << (timer_ef
% 32));
761 sys_access_reinit ();
765 EMACS_GET_TTY (input_fd
, &old_tty
);
767 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
772 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
773 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
775 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
777 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
778 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
779 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
782 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
784 tty
.main
.c_iflag
&= ~IXANY
;
788 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
789 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
791 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
795 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
796 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
799 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
800 /* Set up C-g for both SIGQUIT and SIGINT.
801 We don't know which we will get, but we handle both alike
802 so which one it really gives us does not matter. */
803 tty
.main
.c_cc
[VQUIT
] = quit_char
;
804 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
805 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
807 tty
.main
.c_cc
[VSWTCH
] = CDEL
; /* Turn off shell layering use
810 #if defined (mips) || defined (HAVE_TCATTR)
811 /* The following code looks like the right thing in general,
812 but it is said to cause a crash on USG V.4.
813 Let's play safe by turning it on only for the MIPS. */
815 tty
.main
.c_cc
[VSUSP
] = CDEL
; /* Turn off mips handling of C-z. */
818 tty
.main
.c_cc
[V_DSUSP
] = CDEL
; /* Turn off mips handling of C-y. */
820 #endif /* mips or HAVE_TCATTR */
823 /* AIX enhanced edit loses NULs, so disable it */
825 tty
.main
.c_iflag
&= ~ASCEDIT
;
827 tty
.main
.c_cc
[VSTRT
] = 255;
828 tty
.main
.c_cc
[VSTOP
] = 255;
829 tty
.main
.c_cc
[VSUSP
] = 255;
830 tty
.main
.c_cc
[VDSUSP
] = 255;
831 #endif /* IBMR2AIX */
832 /* Also, PTY overloads NUL and BREAK.
833 don't ignore break, but don't signal either, so it looks like NUL.
834 This really serves a purpose only if running in an XTERM window
835 or via TELNET or the like, but does no harm elsewhere. */
836 tty
.main
.c_iflag
&= ~IGNBRK
;
837 tty
.main
.c_iflag
&= ~BRKINT
;
839 #else /* if not HAVE_TERMIO */
841 tty
.main
.tt_char
|= TT$M_NOECHO
;
843 tty
.main
.tt_char
|= TT$M_EIGHTBIT
845 tty
.main
.tt_char
|= TT$M_TTSYNC
;
847 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
848 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
849 #else /* not VMS (BSD, that is) */
850 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
852 tty
.main
.sg_flags
|= ANYP
;
853 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
854 #endif /* not VMS (BSD, that is) */
855 #endif /* not HAVE_TERMIO */
857 /* If going to use CBREAK mode, we must request C-g to interrupt
858 and turn off start and stop chars, etc. If not going to use
859 CBREAK mode, do this anyway so as to turn off local flow
860 control for user coming over network on 4.2; in this case,
861 only t_stopc and t_startc really matter. */
864 /* Note: if not using CBREAK mode, it makes no difference how we
866 tty
.tchars
= new_tchars
;
867 tty
.tchars
.t_intrc
= quit_char
;
870 tty
.tchars
.t_startc
= '\021';
871 tty
.tchars
.t_stopc
= '\023';
874 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
880 #define LNOFLSH 0100000
883 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
889 #endif /* TIOCGETC */
890 #endif /* not HAVE_TERMIO */
893 tty
.ltchars
= new_ltchars
;
894 #endif /* TIOCGLTC */
896 EMACS_SET_TTY (input_fd
, &tty
, 0);
898 /* This code added to insure that, if flow-control is not to be used,
899 we have an unlocked screen at the start. */
902 if (!flow_control
) ioctl (0, TCXONC
, 1);
906 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
914 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
915 to be only LF. This is the way that is done. */
918 if (ioctl (1, HFTGETID
, &tty
) != -1)
919 write (1, "\033[20l", 5);
925 /* Appears to do nothing when in PASTHRU mode.
926 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
927 interrupt_signal, oob_chars, 0, 0, 0, 0);
934 #ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
937 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
938 fcntl (0, F_SETOWN
, getpid ());
941 #endif /* F_GETOWN */
949 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
953 /* This symbol is defined on recent USG systems.
954 Someone says without this call USG won't really buffer the file
955 even with a call to setbuf. */
956 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
958 setbuf (stdout
, _sobuf
);
960 set_terminal_modes ();
961 if (term_initted
&& no_redraw_on_reenter
)
963 if (display_completed
)
964 direct_output_forward_char (0);
970 if (SCREENP (Vterminal_screen
))
971 SCREEN_GARBAGED_P (XSCREEN (Vterminal_screen
)) = 1;
978 /* Return nonzero if safe to use tabs in output.
979 At the time this is called, init_sys_modes has not been done yet. */
983 struct emacs_tty tty
;
985 EMACS_GET_TTY (input_fd
, &tty
);
986 return EMACS_TTY_TABS_OK (&tty
);
989 /* Get terminal size from system.
990 Store number of lines into *heightp and width into *widthp.
991 If zero or a negative number is stored, the value is not valid. */
993 get_screen_size (widthp
, heightp
)
994 int *widthp
, *heightp
;
1000 struct winsize size
;
1002 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1003 *widthp
= *heightp
= 0;
1006 *widthp
= size
.ws_col
;
1007 *heightp
= size
.ws_row
;
1013 /* SunOS - style. */
1014 struct ttysize size
;
1016 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1017 *widthp
= *heightp
= 0;
1020 *widthp
= size
.ts_cols
;
1021 *heightp
= size
.ts_lines
;
1027 struct sensemode tty
;
1029 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1030 &tty
.class, 12, 0, 0, 0, 0);
1031 *widthp
= tty
.scr_wid
;
1032 *heightp
= tty
.scr_len
;
1034 #else /* system doesn't know size */
1039 #endif /* not VMS */
1040 #endif /* not SunOS-style */
1041 #endif /* not BSD-style */
1045 /* Prepare the terminal for exiting Emacs; move the cursor to the
1046 bottom of the screen, turn off interrupt-driven I/O, etc. */
1056 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1058 cursor_to (SCREEN_HEIGHT (selected_screen
) - 1, 0);
1059 clear_end_of_line (SCREEN_WIDTH (selected_screen
));
1060 /* clear_end_of_line may move the cursor */
1061 cursor_to (SCREEN_HEIGHT (selected_screen
) - 1, 0);
1064 /* HFT devices normally use ^J as a LF/CR. We forced it to
1065 do the LF only. Now, we need to reset it. */
1068 if (ioctl (1, HFTGETID
, &tty
) != -1)
1069 write (1, "\033[20h", 5);
1073 reset_terminal_modes ();
1077 /* Avoid possible loss of output when changing terminal modes. */
1078 fsync (fileno (stdout
));
1083 #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */
1084 if (interrupt_input
)
1087 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1089 #endif /* F_SETOWN */
1090 #endif /* F_SETFL */
1092 if (interrupt_input
)
1096 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1106 /* Set up the proper status flags for use of a pty. */
1111 /* I'm told that TOICREMOTE does not mean control chars
1112 "can't be sent" but rather that they don't have
1113 input-editing or signaling effects.
1114 That should be good, because we have other ways
1115 to do those things in Emacs.
1116 However, telnet mode seems not to work on 4.2.
1117 So TIOCREMOTE is turned off now. */
1119 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1120 will hang. In particular, the "timeout" feature (which
1121 causes a read to return if there is no data available)
1122 does this. Also it is known that telnet mode will hang
1123 in such a way that Emacs must be stopped (perhaps this
1124 is the same problem).
1126 If TIOCREMOTE is turned off, then there is a bug in
1127 hp-ux which sometimes loses data. Apparently the
1128 code which blocks the master process when the internal
1129 buffer fills up does not work. Other than this,
1130 though, everything else seems to work fine.
1132 Since the latter lossage is more benign, we may as well
1133 lose that way. -- cph */
1138 ioctl (fd
, FIONBIO
, &on
);
1143 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1144 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1145 /* cause EMACS not to die when it should, i.e., when its own controlling */
1146 /* tty goes away. I've complained to the AIX developers, and they may */
1147 /* change this behavior, but I'm not going to hold my breath. */
1148 signal (SIGHUP
, SIG_IGN
);
1151 #endif /* HAVE_PTYS */
1155 /* Assigning an input channel is done at the start of Emacs execution.
1156 This is called each time Emacs is resumed, also, but does nothing
1157 because input_chain is no longer zero. */
1165 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1171 /* Deassigning the input channel is done before exiting. */
1175 return SYS$
DASSGN (input_fd
);
1180 /* Request reading one character into the keyboard buffer.
1181 This is done as soon as the buffer becomes empty. */
1186 waiting_for_ast
= 0;
1188 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1189 &input_iosb
, kbd_input_ast
, 1,
1190 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1195 /* Ast routine that is called when keyboard input comes in
1196 in accord with the SYS$QIO above. */
1200 register int c
= -1;
1201 int old_errno
= errno
;
1202 extern EMACS_TIME
*input_available_clear_time
;
1204 if (waiting_for_ast
)
1205 SYS$
SETEF (input_ef
);
1206 waiting_for_ast
= 0;
1209 if (input_count
== 25)
1211 printf ("Ast # %d,", input_count
);
1212 printf (" iosb = %x, %x, %x, %x",
1213 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1216 if (input_iosb
.offset
)
1220 printf (", char = 0%o", c
);
1232 struct input_event e
;
1233 e
.kind
= ascii_keystroke
;
1234 XSET (buf
[i
].code
, Lisp_Int
, cbuf
[i
]);
1235 e
.screen
= selected_screen
;
1236 kbd_buffer_store_event (&e
);
1239 if (input_available_clear_time
)
1240 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1244 /* Wait until there is something in kbd_buffer. */
1246 wait_for_kbd_input ()
1248 extern int have_process_input
, process_exited
;
1250 /* If already something, avoid doing system calls. */
1251 if (detect_input_pending ())
1255 /* Clear a flag, and tell ast routine above to set it. */
1256 SYS$
CLREF (input_ef
);
1257 waiting_for_ast
= 1;
1258 /* Check for timing error: ast happened while we were doing that. */
1259 if (!detect_input_pending ())
1261 /* No timing error: wait for flag to be set. */
1262 set_waiting_for_input (0);
1263 SYS$
WFLOR (input_ef
, input_eflist
);
1264 clear_waiting_for_input (0);
1265 if (!detect_input_pending ())
1266 /* Check for subprocess input availability */
1268 int dsp
= have_process_input
|| process_exited
;
1270 SYS$
CLREF (process_ef
);
1271 if (have_process_input
)
1272 process_command_input ();
1277 update_mode_lines
++;
1278 redisplay_preserve_echo_area ();
1282 waiting_for_ast
= 0;
1285 /* Get rid of any pending QIO, when we are about to suspend
1286 or when we want to throw away pending input.
1287 We wait for a positive sign that the AST routine has run
1288 and therefore there is no I/O request queued when we return.
1289 SYS$SETAST is used to avoid a timing error. */
1294 printf ("At end_kbd_input.\n");
1298 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1300 SYS$
CANCEL (input_fd
);
1305 /* Clear a flag, and tell ast routine above to set it. */
1306 SYS$
CLREF (input_ef
);
1307 waiting_for_ast
= 1;
1309 SYS$
CANCEL (input_fd
);
1311 SYS$
WAITFR (input_ef
);
1312 waiting_for_ast
= 0;
1315 /* Wait for either input available or time interval expiry. */
1317 input_wait_timeout (timeval
)
1318 int timeval
; /* Time to wait, in seconds */
1321 static int zero
= 0;
1322 static int large
= -10000000;
1324 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1326 /* If already something, avoid doing system calls. */
1327 if (detect_input_pending ())
1331 /* Clear a flag, and tell ast routine above to set it. */
1332 SYS$
CLREF (input_ef
);
1333 waiting_for_ast
= 1;
1334 /* Check for timing error: ast happened while we were doing that. */
1335 if (!detect_input_pending ())
1337 /* No timing error: wait for flag to be set. */
1339 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1340 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1342 waiting_for_ast
= 0;
1345 /* The standard `sleep' routine works some other way
1346 and it stops working if you have ever quit out of it.
1347 This one continues to work. */
1353 static int zero
= 0;
1354 static int large
= -10000000;
1356 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1359 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1360 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1375 croak ("request sigio");
1380 croak ("unrequest sigio");
1385 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1390 #ifndef SYSTEM_MALLOC
1397 /* Some systems that cannot dump also cannot implement these. */
1400 * Return the address of the start of the text segment prior to
1401 * doing an unexec. After unexec the return value is undefined.
1402 * See crt0.c for further explanation and _start.
1406 #ifndef CANNOT_UNEXEC
1411 return ((char *) TEXT_START
);
1415 return ((char *) csrt
);
1416 #else /* not GOULD */
1417 extern int _start ();
1418 return ((char *) _start
);
1420 #endif /* TEXT_START */
1422 #endif /* not CANNOT_UNEXEC */
1425 * Return the address of the start of the data segment prior to
1426 * doing an unexec. After unexec the return value is undefined.
1427 * See crt0.c for further information and definition of data_start.
1429 * Apparently, on BSD systems this is etext at startup. On
1430 * USG systems (swapping) this is highly mmu dependent and
1431 * is also dependent on whether or not the program is running
1432 * with shared text. Generally there is a (possibly large)
1433 * gap between end of text and start of data with shared text.
1435 * On Uniplus+ systems with shared text, data starts at a
1436 * fixed address. Each port (from a given oem) is generally
1437 * different, and the specific value of the start of data can
1438 * be obtained via the UniPlus+ specific "uvar" system call,
1439 * however the method outlined in crt0.c seems to be more portable.
1441 * Probably what will have to happen when a USG unexec is available,
1442 * at least on UniPlus, is temacs will have to be made unshared so
1443 * that text and data are contiguous. Then once loadup is complete,
1444 * unexec will produce a shared executable where the data can be
1445 * at the normal shared text boundry and the startofdata variable
1446 * will be patched by unexec to the correct value.
1454 return ((char *) DATA_START
);
1456 extern int data_start
;
1457 return ((char *) &data_start
);
1460 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1463 /* Some systems that cannot dump also cannot implement these. */
1466 * Return the address of the end of the text segment prior to
1467 * doing an unexec. After unexec the return value is undefined.
1474 return ((char *) TEXT_END
);
1477 return ((char *) &etext
);
1482 * Return the address of the end of the data segment prior to
1483 * doing an unexec. After unexec the return value is undefined.
1490 return ((char *) DATA_END
);
1493 return ((char *) &edata
);
1497 #endif /* not CANNOT_DUMP */
1499 /* Get_system_name returns as its value
1500 a string for the Lisp function system-name to return. */
1507 /* Can't have this within the function since `static' is #defined to nothing */
1508 static struct utsname get_system_name_name
;
1515 uname (&get_system_name_name
);
1516 return (get_system_name_name
.nodename
);
1520 #else /* not USG, not 4.1 */
1521 static char system_name_saved
[32];
1524 if ((sp
= egetenv ("SYS$NODE")) == 0)
1530 if ((end
= index (sp
, ':')) != 0)
1533 strcpy (system_name_saved
, sp
);
1535 gethostname (system_name_saved
, sizeof (system_name_saved
));
1536 #endif /* not VMS */
1537 return system_name_saved
;
1538 #endif /* not USG, not 4.1 */
1539 #endif /* not USG */
1545 #ifdef HAVE_X_WINDOWS
1546 /* Cause explanatory error message at compile time,
1547 since the select emulation is not good enough for X. */
1548 int *x
= &x_windows_lose_if_no_select_system_call
;
1551 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1552 * Only checks read descriptors.
1554 /* How long to wait between checking fds in select */
1555 #define SELECT_PAUSE 1
1558 /* For longjmp'ing back to read_input_waiting. */
1560 jmp_buf read_alarm_throw
;
1562 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1563 The read_socket_hook function sets this to 1 while it is waiting. */
1565 int read_alarm_should_throw
;
1573 #else /* not BSD4_1 */
1574 signal (SIGALRM
, SIG_IGN
);
1575 #endif /* not BSD4_1 */
1576 if (read_alarm_should_throw
)
1577 longjmp (read_alarm_throw
, 1);
1580 /* Only rfds are checked. */
1582 select (nfds
, rfds
, wfds
, efds
, timeout
)
1584 int *rfds
, *wfds
, *efds
, *timeout
;
1586 int ravail
= 0, orfds
= 0, old_alarm
;
1587 int timeoutval
= timeout
? *timeout
: 100000;
1588 int *local_timeout
= &timeoutval
;
1589 extern int proc_buffered_char
[];
1590 #ifndef subprocesses
1591 int process_tick
= 0, update_tick
= 0;
1593 extern int process_tick
, update_tick
;
1595 SIGTYPE (*old_trap
) ();
1608 /* If we are looking only for the terminal, with no timeout,
1609 just read it and wait -- that's more efficient. */
1610 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1612 if (! detect_input_pending ())
1613 read_input_waiting ();
1618 /* Once a second, till the timer expires, check all the flagged read
1619 * descriptors to see if any input is available. If there is some then
1620 * set the corresponding bit in the return copy of rfds.
1624 register int to_check
, bit
, fd
;
1628 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1632 int avail
= 0, status
= 0;
1635 avail
= detect_input_pending (); /* Special keyboard handler */
1639 status
= ioctl (fd
, FIONREAD
, &avail
);
1640 #else /* no FIONREAD */
1641 /* Hoping it will return -1 if nothing available
1642 or 0 if all 0 chars requested are read. */
1643 if (proc_buffered_char
[fd
] >= 0)
1647 avail
= read (fd
, &buf
, 1);
1649 proc_buffered_char
[fd
] = buf
;
1651 #endif /* no FIONREAD */
1653 if (status
>= 0 && avail
> 0)
1661 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
1663 old_alarm
= alarm (0);
1664 old_trap
= (int (*)()) signal (SIGALRM
, select_alarm
);
1666 alarm (SELECT_PAUSE
);
1667 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1668 while (select_alarmed
== 0 && *local_timeout
!= 0
1669 && process_tick
== update_tick
)
1671 /* If we are interested in terminal input,
1672 wait by reading the terminal.
1673 That makes instant wakeup for terminal input at least. */
1676 read_input_waiting ();
1677 if (detect_input_pending ())
1683 (*local_timeout
) -= SELECT_PAUSE
;
1684 /* Reset the old alarm if there was one */
1686 signal (SIGALRM
, old_trap
);
1689 /* Reset or forge an interrupt for the original handler. */
1690 old_alarm
-= SELECT_PAUSE
;
1692 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
1696 if (*local_timeout
== 0) /* Stop on timer being cleared */
1702 /* Read keyboard input into the standard buffer,
1703 waiting for at least one character. */
1705 /* Make all keyboard buffers much bigger when using X windows. */
1706 #ifdef HAVE_X_WINDOWS
1707 #define BUFFER_SIZE_FACTOR 16
1709 #define BUFFER_SIZE_FACTOR 1
1712 read_input_waiting ()
1714 char buf
[256 * BUFFER_SIZE_FACTOR
];
1715 struct input_event e
;
1718 if (read_socket_hook
)
1720 read_alarm_should_throw
= 0;
1721 if (! setjmp (read_alarm_throw
))
1722 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
1727 nread
= read (fileno (stdin
), buf
, 1);
1729 /* Scan the chars for C-g and store them in kbd_buffer. */
1730 e
.kind
= ascii_keystroke
;
1731 e
.screen
= selected_screen
;
1732 for (i
= 0; i
< nread
; i
++)
1734 XSET (e
.code
, Lisp_Int
, buf
[i
]);
1735 kbd_buffer_store_event (&e
);
1736 /* Don't look at input that follows a C-g too closely.
1737 This reduces lossage due to autorepeat on C-g. */
1738 if (buf
[i
] == Ctl ('G'))
1743 #endif /* not HAVE_SELECT */
1744 #endif /* not VMS */
1754 * Partially emulate 4.2 open call.
1755 * open is defined as this in 4.1.
1757 * - added by Michael Bloom @ Citicorp/TTI
1762 sys_open (path
, oflag
, mode
)
1766 if (oflag
& O_CREAT
)
1767 return creat (path
, mode
);
1769 return open (path
, oflag
);
1776 lmode
= LINTRUP
| lmode
;
1777 ioctl (0, TIOCLSET
, &lmode
);
1784 lmode
= ~LINTRUP
& lmode
;
1785 ioctl (0, TIOCLSET
, &lmode
);
1792 interrupts_deferred
= 0;
1799 interrupts_deferred
= 1;
1802 /* still inside #ifdef BSD4_1 */
1805 int sigheld
; /* Mask of held signals */
1810 sigheld
|= sigbit (signum
);
1817 sigheld
|= sigbit (signum
);
1823 sigheld
&= ~sigbit (signum
);
1827 sigfree () /* Free all held signals */
1830 for (i
= 0; i
< NSIG
; i
++)
1831 if (sigheld
& sigbit (i
))
1838 return 1 << (i
- 1);
1840 #endif /* subprocesses */
1843 /* POSIX signals support - DJB */
1844 /* Anyone with POSIX signals should have ANSI C declarations */
1846 #ifdef POSIX_SIGNALS
1848 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
1849 static struct sigaction new_action
, old_action
;
1853 #ifdef POSIX_SIGNALS
1854 sigemptyset (&signal_empty_mask
);
1855 sigfillset (&signal_full_mask
);
1859 int (*signal_handler_t
) ();
1862 sys_signal (int signal_number
, signal_handler_t action
)
1865 /* This gets us restartable system calls for efficiency.
1866 The "else" code will works as well. */
1867 return (berk_signal (signal_number
, action
));
1869 sigemptyset (&new_action
.sa_mask
);
1870 new_action
.sa_handler
= action
;
1871 new_action
.sa_flags
= NULL
;
1872 new_action (signal_number
, &new_action
, &old_action
);
1873 return (old_action
.sa_handler
);
1878 /* If we're compiling with GCC, we don't need this function, since it
1879 can be written as a macro. */
1881 sys_sigmask (int sig
)
1884 sigemptyset (&mask
);
1885 sigaddset (&mask
, sig
);
1891 sys_sigpause (sigset_t new_mask
)
1893 /* pause emulating berk sigpause... */
1894 sigsuspend (&new_mask
);
1898 /* I'd like to have these guys return pointers to the mask storage in here,
1899 but there'd be trouble if the code was saving multiple masks. I'll be
1900 safe and pass the structure. It normally won't be more than 2 bytes
1904 sys_sigblock (sigset_t new_mask
)
1907 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
1912 sys_sigunblock (sigset_t new_mask
)
1915 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
1920 sys_sigsetmask (sigset_t new_mask
)
1923 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1927 #endif /* POSIX_SIGNALS */
1934 register int length
;
1938 long max_str
= 65535;
1940 while (length
> max_str
) {
1941 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1946 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1948 while (length
-- > 0)
1950 #endif /* not VMS */
1953 /* Saying `void' requires a declaration, above, where bcopy is used
1954 and that declaration causes pain for systems where bcopy is a macro. */
1955 bcopy (b1
, b2
, length
)
1958 register int length
;
1961 long max_str
= 65535;
1963 while (length
> max_str
) {
1964 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
1970 (void) LIB$
MOVC3 (&length
, b1
, b2
);
1972 while (length
-- > 0)
1974 #endif /* not VMS */
1978 bcmp (b1
, b2
, length
) /* This could be a macro! */
1981 register int length
;
1984 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
1985 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
1987 return STR$
COMPARE (&src1
, &src2
);
1989 while (length
-- > 0)
1994 #endif /* not VMS */
1996 #endif /* not BSTRING */
2000 * The BSD random returns numbers in the range of
2001 * 0 to 2e31 - 1. The USG rand returns numbers in the
2002 * range of 0 to 2e15 - 1. This is probably not significant
2009 /* Arrange to return a range centered on zero. */
2010 return (rand () << 15) + rand () - (1 << 29);
2024 /* Arrange to return a range centered on zero. */
2025 return (rand () << 15) + rand () - (1 << 29);
2035 #ifdef WRONG_NAME_INSQUE
2048 /* If any place else asks for the TERM variable,
2049 allow it to be overridden with the EMACS_TERM variable
2050 before attempting to translate the logical name TERM. As a last
2051 resort, ask for VAX C's special idea of the TERM variable. */
2058 static char buf
[256];
2059 static struct dsc$descriptor_s equiv
2060 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2061 static struct dsc$descriptor_s d_name
2062 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2065 if (!strcmp (name
, "TERM"))
2067 val
= (char *) getenv ("EMACS_TERM");
2072 d_name
.dsc$w_length
= strlen (name
);
2073 d_name
.dsc$a_pointer
= name
;
2074 if (lib$
sys_trnlog (&d_name
, &eqlen
, &equiv
) == 1)
2076 char *str
= (char *) xmalloc (eqlen
+ 1);
2077 bcopy (buf
, str
, eqlen
);
2079 /* This is a storage leak, but a pain to fix. With luck,
2080 no one will ever notice. */
2083 return (char *) getenv (name
);
2088 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2089 to force a call on the debugger from within the image. */
2094 LIB$
SIGNAL (SS$_DEBUG
);
2100 #ifdef LINK_CRTL_SHARE
2101 #ifdef SHAREABLE_LIB_BUG
2102 /* Variables declared noshare and initialized in shareable libraries
2103 cannot be shared. The VMS linker incorrectly forces you to use a private
2104 version which is uninitialized... If not for this "feature", we
2105 could use the C library definition of sys_nerr and sys_errlist. */
2107 char *sys_errlist
[] =
2111 "no such file or directory",
2113 "interrupted system call",
2115 "no such device or address",
2116 "argument list too long",
2117 "exec format error",
2120 "no more processes",
2121 "not enough memory",
2122 "permission denied",
2124 "block device required",
2125 "mount devices busy",
2127 "cross-device link",
2132 "file table overflow",
2133 "too many open files",
2137 "no space left on device",
2139 "read-only file system",
2145 "vax/vms specific error code nontranslatable error"
2147 #endif /* SHAREABLE_LIB_BUG */
2148 #endif /* LINK_CRTL_SHARE */
2151 #ifdef INTERRUPTIBLE_OPEN
2155 sys_open (path
, oflag
, mode
)
2159 register int rtnval
;
2161 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2162 && (errno
== EINTR
));
2166 #endif /* INTERRUPTIBLE_OPEN */
2168 #ifdef INTERRUPTIBLE_CLOSE
2173 register int rtnval
;
2175 while ((rtnval
= close (fd
)) == -1
2176 && (errno
== EINTR
));
2180 #endif /* INTERRUPTIBLE_CLOSE */
2182 #ifdef INTERRUPTIBLE_IO
2185 sys_read (fildes
, buf
, nbyte
)
2190 register int rtnval
;
2192 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2193 && (errno
== EINTR
));
2198 sys_write (fildes
, buf
, nbyte
)
2203 register int rtnval
;
2205 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2206 && (errno
== EINTR
));
2210 #endif /* INTERRUPTIBLE_IO */
2214 * All of the following are for USG.
2216 * On USG systems the system calls are INTERRUPTIBLE by signals
2217 * that the user program has elected to catch. Thus the system call
2218 * must be retried in these cases. To handle this without massive
2219 * changes in the source code, we remap the standard system call names
2220 * to names for our own functions in sysdep.c that do the system call
2221 * with retries. Actually, for portability reasons, it is good
2222 * programming practice, as this example shows, to limit all actual
2223 * system calls to a single occurance in the source. Sure, this
2224 * adds an extra level of function call overhead but it is almost
2225 * always negligible. Fred Fish, Unisoft Systems Inc.
2228 char *sys_siglist
[NSIG
+ 1] =
2231 /* AIX has changed the signals a bit */
2232 "bogus signal", /* 0 */
2233 "hangup", /* 1 SIGHUP */
2234 "interrupt", /* 2 SIGINT */
2235 "quit", /* 3 SIGQUIT */
2236 "illegal instruction", /* 4 SIGILL */
2237 "trace trap", /* 5 SIGTRAP */
2238 "IOT instruction", /* 6 SIGIOT */
2239 "crash likely", /* 7 SIGDANGER */
2240 "floating point exception", /* 8 SIGFPE */
2241 "kill", /* 9 SIGKILL */
2242 "bus error", /* 10 SIGBUS */
2243 "segmentation violation", /* 11 SIGSEGV */
2244 "bad argument to system call", /* 12 SIGSYS */
2245 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2246 "alarm clock", /* 14 SIGALRM */
2247 "software termination signum", /* 15 SIGTERM */
2248 "user defined signal 1", /* 16 SIGUSR1 */
2249 "user defined signal 2", /* 17 SIGUSR2 */
2250 "death of a child", /* 18 SIGCLD */
2251 "power-fail restart", /* 19 SIGPWR */
2252 "bogus signal", /* 20 */
2253 "bogus signal", /* 21 */
2254 "bogus signal", /* 22 */
2255 "bogus signal", /* 23 */
2256 "bogus signal", /* 24 */
2257 "LAN I/O interrupt", /* 25 SIGAIO */
2258 "PTY I/O interrupt", /* 26 SIGPTY */
2259 "I/O intervention required", /* 27 SIGIOINT */
2260 "HFT grant", /* 28 SIGGRANT */
2261 "HFT retract", /* 29 SIGRETRACT */
2262 "HFT sound done", /* 30 SIGSOUND */
2263 "HFT input ready", /* 31 SIGMSG */
2265 "bogus signal", /* 0 */
2266 "hangup", /* 1 SIGHUP */
2267 "interrupt", /* 2 SIGINT */
2268 "quit", /* 3 SIGQUIT */
2269 "illegal instruction", /* 4 SIGILL */
2270 "trace trap", /* 5 SIGTRAP */
2271 "IOT instruction", /* 6 SIGIOT */
2272 "EMT instruction", /* 7 SIGEMT */
2273 "floating point exception", /* 8 SIGFPE */
2274 "kill", /* 9 SIGKILL */
2275 "bus error", /* 10 SIGBUS */
2276 "segmentation violation", /* 11 SIGSEGV */
2277 "bad argument to system call", /* 12 SIGSYS */
2278 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2279 "alarm clock", /* 14 SIGALRM */
2280 "software termination signum", /* 15 SIGTERM */
2281 "user defined signal 1", /* 16 SIGUSR1 */
2282 "user defined signal 2", /* 17 SIGUSR2 */
2283 "death of a child", /* 18 SIGCLD */
2284 "power-fail restart", /* 19 SIGPWR */
2285 #endif /* not AIX */
2290 * Warning, this function may not duplicate 4.2 action properly
2291 * under error conditions.
2295 /* In 4.1, param.h fails to define this. */
2296 #define MAXPATHLEN 1024
2305 char *npath
, *spath
;
2306 extern char *getcwd ();
2308 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2309 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2310 up to first slash. Should be harmless on other systems. */
2311 while (*npath
&& *npath
!= '/')
2313 strcpy (pathname
, npath
);
2314 free (spath
); /* getcwd uses malloc */
2318 #endif /* HAVE_GETWD */
2321 * Emulate rename using unlink/link. Note that this is
2322 * only partially correct. Also, doesn't enforce restriction
2323 * that files be of same type (regular->regular, dir->dir, etc).
2332 if (access (from
, 0) == 0)
2335 if (link (from
, to
) == 0)
2336 if (unlink (from
) == 0)
2344 /* Set priority value to PRIO. */
2347 setpriority (which
, who
, prio
)
2348 int which
, who
, prio
;
2352 nice (prio
- nice (0));
2359 * Substitute fork for vfork on USG flavors.
2367 #endif /* not HAVE_VFORK */
2369 #ifdef MISSING_UTIMES
2371 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2380 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2381 utimbuf structure defined anywhere but in the man page. */
2391 struct timeval tvp
[];
2394 utb
.actime
= tvp
[0].tv_sec
;
2395 utb
.modtime
= tvp
[1].tv_sec
;
2398 #endif /* IRIS_UTIME */
2404 /* HPUX curses library references perror, but as far as we know
2405 it won't be called. Anyway this definition will do for now. */
2411 #endif /* not HAVE_PERROR */
2417 * Emulate BSD dup2. First close newd if it already exists.
2418 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2419 * until we are, then close the unsuccessful ones.
2426 register int fd
, ret
;
2431 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2433 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2440 ret
= dup2 (old
,new);
2446 #endif /* not HAVE_DUP2 */
2449 * Gettimeofday. Simulate as much as possible. Only accurate
2450 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2451 * Only needed when subprocesses are defined.
2456 #ifndef HAVE_GETTIMEOFDAY
2460 gettimeofday (tp
, tzp
)
2462 struct timezone
*tzp
;
2464 extern long time ();
2466 tp
->tv_sec
= time ((long *)0);
2468 tzp
->tz_minuteswest
= -1;
2474 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2477 * This function will go away as soon as all the stubs fixed. (fnf)
2483 printf ("%s not yet implemented\r\n", badfunc
);
2492 char *sys_siglist
[NSIG
+ 1] =
2494 "null signal", /* 0 SIGNULL */
2495 "hangup", /* 1 SIGHUP */
2496 "interrupt", /* 2 SIGINT */
2497 "quit", /* 3 SIGQUIT */
2498 "illegal instruction", /* 4 SIGILL */
2499 "trace trap", /* 5 SIGTRAP */
2500 "abort termination", /* 6 SIGABRT */
2501 "SIGEMT", /* 7 SIGEMT */
2502 "floating point exception", /* 8 SIGFPE */
2503 "kill", /* 9 SIGKILL */
2504 "bus error", /* 10 SIGBUS */
2505 "segmentation violation", /* 11 SIGSEGV */
2506 "bad argument to system call", /* 12 SIGSYS */
2507 "write on a pipe with no reader", /* 13 SIGPIPE */
2508 "alarm clock", /* 14 SIGALRM */
2509 "software termination signal", /* 15 SIGTERM */
2510 "user defined signal 1", /* 16 SIGUSR1 */
2511 "user defined signal 2", /* 17 SIGUSR2 */
2512 "child stopped or terminated", /* 18 SIGCLD */
2513 "power-fail restart", /* 19 SIGPWR */
2514 "window size changed", /* 20 SIGWINCH */
2515 "undefined", /* 21 */
2516 "pollable event occured", /* 22 SIGPOLL */
2517 "sendable stop signal not from tty", /* 23 SIGSTOP */
2518 "stop signal from tty", /* 24 SIGSTP */
2519 "continue a stopped process", /* 25 SIGCONT */
2520 "attempted background tty read", /* 26 SIGTTIN */
2521 "attempted background tty write", /* 27 SIGTTOU */
2522 "undefined", /* 28 */
2523 "undefined", /* 29 */
2524 "undefined", /* 30 */
2525 "undefined", /* 31 */
2526 "undefined", /* 32 */
2527 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2528 "I/O is possible", /* 34 SIGIO */
2529 "exceeded cpu time limit", /* 35 SIGXCPU */
2530 "exceeded file size limit", /* 36 SIGXFSZ */
2531 "virtual time alarm", /* 37 SIGVTALRM */
2532 "profiling time alarm", /* 38 SIGPROF */
2533 "undefined", /* 39 */
2534 "file record locks revoked", /* 40 SIGLOST */
2535 "undefined", /* 41 */
2536 "undefined", /* 42 */
2537 "undefined", /* 43 */
2538 "undefined", /* 44 */
2539 "undefined", /* 45 */
2540 "undefined", /* 46 */
2541 "undefined", /* 47 */
2542 "undefined", /* 48 */
2543 "undefined", /* 49 */
2544 "undefined", /* 50 */
2545 "undefined", /* 51 */
2546 "undefined", /* 52 */
2547 "undefined", /* 53 */
2548 "undefined", /* 54 */
2549 "undefined", /* 55 */
2550 "undefined", /* 56 */
2551 "undefined", /* 57 */
2552 "undefined", /* 58 */
2553 "undefined", /* 59 */
2554 "undefined", /* 60 */
2555 "undefined", /* 61 */
2556 "undefined", /* 62 */
2557 "undefined", /* 63 */
2558 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2564 /* Directory routines for systems that don't have them. */
2566 #ifdef SYSV_SYSTEM_DIR
2573 register DIR *dirp
; /* stream from opendir */
2575 sys_close (dirp
->dd_fd
);
2576 free ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2577 free ((char *) dirp
);
2579 #endif /* not AIX */
2580 #endif /* SYSV_SYSTEM_DIR */
2582 #ifdef NONSYSTEM_DIR_LIBRARY
2586 char *filename
; /* name of directory */
2588 register DIR *dirp
; /* -> malloc'ed storage */
2589 register int fd
; /* file descriptor for read */
2590 struct stat sbuf
; /* result of fstat */
2592 fd
= sys_open (filename
, 0);
2596 if (fstat (fd
, &sbuf
) < 0
2597 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2598 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2601 return 0; /* bad luck today */
2605 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2612 register DIR *dirp
; /* stream from opendir */
2614 sys_close (dirp
->dd_fd
);
2615 free ((char *) dirp
);
2623 ino_t od_ino
; /* inode */
2624 char od_name
[DIRSIZ
]; /* filename */
2626 #endif /* not VMS */
2628 struct direct dir_static
; /* simulated directory contents */
2633 register DIR *dirp
; /* stream from opendir */
2636 register struct olddir
*dp
; /* -> directory data */
2638 register struct dir$_name
*dp
; /* -> directory data */
2639 register struct dir$_version
*dv
; /* -> version data */
2644 if (dirp
->dd_loc
>= dirp
->dd_size
)
2645 dirp
->dd_loc
= dirp
->dd_size
= 0;
2647 if (dirp
->dd_size
== 0 /* refill buffer */
2648 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2652 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
2653 dirp
->dd_loc
+= sizeof (struct olddir
);
2655 if (dp
->od_ino
!= 0) /* not deleted entry */
2657 dir_static
.d_ino
= dp
->od_ino
;
2658 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
2659 dir_static
.d_name
[DIRSIZ
] = '\0';
2660 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2661 dir_static
.d_reclen
= sizeof (struct direct
)
2663 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2664 return &dir_static
; /* -> simulated structure */
2667 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2668 if (dirp
->dd_loc
== 0)
2669 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
2670 : dp
->dir$b_namecount
;
2671 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
2672 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2673 dir_static
.d_namlen
= dp
->dir$b_namecount
;
2674 dir_static
.d_reclen
= sizeof (struct direct
)
2676 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2677 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2678 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
2679 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
2686 /* readdirver is just like readdir except it returns all versions of a file
2687 as separate entries. */
2692 register DIR *dirp
; /* stream from opendir */
2694 register struct dir$_name
*dp
; /* -> directory data */
2695 register struct dir$_version
*dv
; /* -> version data */
2697 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
2698 dirp
->dd_loc
= dirp
->dd_size
= 0;
2700 if (dirp
->dd_size
== 0 /* refill buffer */
2701 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2704 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2705 if (dirp
->dd_loc
== 0)
2706 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
2707 : dp
->dir$b_namecount
;
2708 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
2709 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2710 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
2711 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2712 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2713 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
2714 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2715 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
2721 #endif /* NONSYSTEM_DIR_LIBRARY */
2723 /* Functions for VMS */
2725 #include "vms-pwd.h"
2730 /* Return as a string the VMS error string pertaining to STATUS.
2731 Reuses the same static buffer each time it is called. */
2735 int status
; /* VMS status code */
2739 static char buf
[257];
2741 bufadr
[0] = sizeof buf
- 1;
2742 bufadr
[1] = (int) buf
;
2743 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
2744 return "untranslatable VMS error status";
2752 /* The following is necessary because 'access' emulation by VMS C (2.0) does
2753 * not work correctly. (It also doesn't work well in version 2.3.)
2758 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
2759 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
2763 unsigned short s_buflen
;
2764 unsigned short s_code
;
2766 unsigned short *s_retlenadr
;
2770 #define buflen s.s_buflen
2771 #define code s.s_code
2772 #define bufadr s.s_bufadr
2773 #define retlenadr s.s_retlenadr
2775 #define R_OK 4 /* test for read permission */
2776 #define W_OK 2 /* test for write permission */
2777 #define X_OK 1 /* test for execute (search) permission */
2778 #define F_OK 0 /* test for presence of file */
2781 sys_access (path
, mode
)
2785 static char *user
= NULL
;
2788 /* translate possible directory spec into .DIR file name, so brain-dead
2789 * access can treat the directory like a file. */
2790 if (directory_file_name (path
, dir_fn
))
2794 return access (path
, mode
);
2795 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
2801 unsigned short int dummy
;
2803 static int constant
= ACL$C_FILE
;
2804 DESCRIPTOR (path_desc
, path
);
2805 DESCRIPTOR (user_desc
, user
);
2809 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
2812 acces
|= CHP$M_READ
;
2814 acces
|= CHP$M_WRITE
;
2815 itemlst
[0].buflen
= sizeof (int);
2816 itemlst
[0].code
= CHP$_FLAGS
;
2817 itemlst
[0].bufadr
= (char *) &flags
;
2818 itemlst
[0].retlenadr
= &dummy
;
2819 itemlst
[1].buflen
= sizeof (int);
2820 itemlst
[1].code
= CHP$_ACCESS
;
2821 itemlst
[1].bufadr
= (char *) &acces
;
2822 itemlst
[1].retlenadr
= &dummy
;
2823 itemlst
[2].end
= CHP$_END
;
2824 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
2825 return stat
== SS$_NORMAL
? 0 : -1;
2829 #else /* not VMS4_4 */
2832 #define ACE$M_WRITE 2
2833 #define ACE$C_KEYID 1
2835 static unsigned short memid
, grpid
;
2836 static unsigned int uic
;
2838 /* Called from init_sys_modes, so it happens not very often
2839 but at least each time Emacs is loaded. */
2840 sys_access_reinit ()
2846 sys_access (filename
, type
)
2852 int status
, size
, i
, typecode
, acl_controlled
;
2853 unsigned int *aclptr
, *aclend
, aclbuf
[60];
2854 union prvdef prvmask
;
2856 /* Get UIC and GRP values for protection checking. */
2859 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
2862 memid
= uic
& 0xFFFF;
2866 if (type
!= 2) /* not checking write access */
2867 return access (filename
, type
);
2869 /* Check write protection. */
2871 #define CHECKPRIV(bit) (prvmask.bit)
2872 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
2874 /* Find privilege bits */
2875 status
= sys$
setprv (0, 0, 0, prvmask
);
2877 error ("Unable to find privileges: %s", vmserrstr (status
));
2878 if (CHECKPRIV (PRV$V_BYPASS
))
2879 return 0; /* BYPASS enabled */
2881 fab
.fab$b_fac
= FAB$M_GET
;
2882 fab
.fab$l_fna
= filename
;
2883 fab
.fab$b_fns
= strlen (filename
);
2884 fab
.fab$l_xab
= &xab
;
2885 xab
= cc$rms_xabpro
;
2886 xab
.xab$l_aclbuf
= aclbuf
;
2887 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
2888 status
= sys$
open (&fab
, 0, 0);
2891 sys$
close (&fab
, 0, 0);
2892 /* Check system access */
2893 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
2895 /* Check ACL entries, if any */
2897 if (xab
.xab$w_acllen
> 0)
2900 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
2901 while (*aclptr
&& aclptr
< aclend
)
2903 size
= (*aclptr
& 0xff) / 4;
2904 typecode
= (*aclptr
>> 8) & 0xff;
2905 if (typecode
== ACE$C_KEYID
)
2906 for (i
= size
- 1; i
> 1; i
--)
2907 if (aclptr
[i
] == uic
)
2910 if (aclptr
[1] & ACE$M_WRITE
)
2911 return 0; /* Write access through ACL */
2913 aclptr
= &aclptr
[size
];
2915 if (acl_controlled
) /* ACL specified, prohibits write access */
2918 /* No ACL entries specified, check normal protection */
2919 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
2921 if (WRITEABLE (XAB$V_GRP
) &&
2922 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
2923 return 0; /* Group writeable */
2924 if (WRITEABLE (XAB$V_OWN
) &&
2925 (xab
.xab$l_uic
& 0xFFFF) == memid
)
2926 return 0; /* Owner writeable */
2928 return -1; /* Not writeable */
2930 #endif /* not VMS4_4 */
2933 static char vtbuf
[NAM$C_MAXRSS
+1];
2935 /* translate a vms file spec to a unix path */
2937 sys_translate_vms (vfile
)
2948 /* leading device or logical name is a root directory */
2949 if (p
= strchr (vfile
, ':'))
2958 if (*p
== '[' || *p
== '<')
2960 while (*++vfile
!= *p
+ 2)
2964 if (vfile
[-1] == *p
)
2987 static char utbuf
[NAM$C_MAXRSS
+1];
2989 /* translate a unix path to a VMS file spec */
2991 sys_translate_unix (ufile
)
3014 if (index (&ufile
[1], '/'))
3021 if (index (&ufile
[1], '/'))
3028 if (strncmp (ufile
, "./", 2) == 0)
3035 ufile
++; /* skip the dot */
3036 if (index (&ufile
[1], '/'))
3041 else if (strncmp (ufile
, "../", 3) == 0)
3049 ufile
+= 2; /* skip the dots */
3050 if (index (&ufile
[1], '/'))
3075 strcpy (pathname
, egetenv ("PATH"));
3080 if ('a' <= *ptr
&& *ptr
<= 'z')
3089 long item_code
= JPI$_OWNER
;
3090 unsigned long parent_id
;
3093 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3096 vaxc$errno
= status
;
3106 return (getgid () << 16) | getuid ();
3110 sys_read (fildes
, buf
, nbyte
)
3115 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3120 sys_write (fildes
, buf
, nbyte
)
3125 register int nwrote
, rtnval
= 0;
3127 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3133 return rtnval
? rtnval
: -1;
3134 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3135 return rtnval
? rtnval
: -1;
3136 return (rtnval
+ nwrote
);
3141 * VAX/VMS VAX C RTL really loses. It insists that records
3142 * end with a newline (carriage return) character, and if they
3143 * don't it adds one (nice of it isn't it!)
3145 * Thus we do this stupidity below.
3149 sys_write (fildes
, buf
, nbytes
)
3152 unsigned int nbytes
;
3159 fstat (fildes
, &st
);
3165 /* Handle fixed-length files with carriage control. */
3166 if (st
.st_fab_rfm
== FAB$C_FIX
3167 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3169 len
= st
.st_fab_mrs
;
3170 retval
= write (fildes
, p
, min (len
, nbytes
));
3173 retval
++; /* This skips the implied carriage control */
3177 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3178 while (*e
!= '\n' && e
> p
) e
--;
3179 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3180 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3182 retval
= write (fildes
, p
, len
);
3193 /* Create file NEW copying its attributes from file OLD. If
3194 OLD is 0 or does not exist, create based on the value of
3197 /* Protection value the file should ultimately have.
3198 Set by create_copy_attrs, and use by rename_sansversions. */
3199 static unsigned short int fab_final_pro
;
3202 creat_copy_attrs (old
, new)
3205 struct FAB fab
= cc$rms_fab
;
3206 struct XABPRO xabpro
;
3207 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3208 extern int vms_stmlf_recfm
;
3212 fab
.fab$b_fac
= FAB$M_GET
;
3213 fab
.fab$l_fna
= old
;
3214 fab
.fab$b_fns
= strlen (old
);
3215 fab
.fab$l_xab
= (char *) &xabpro
;
3216 xabpro
= cc$rms_xabpro
;
3217 xabpro
.xab$l_aclbuf
= aclbuf
;
3218 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3219 /* Call $OPEN to fill in the fab & xabpro fields. */
3220 if (sys$
open (&fab
, 0, 0) & 1)
3222 sys$
close (&fab
, 0, 0);
3223 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3224 if (xabpro
.xab$w_acllen
> 0)
3226 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3227 /* If the acl buffer was too short, redo open with longer one.
3228 Wouldn't need to do this if there were some system imposed
3229 limit on the size of an ACL, but I can't find any such. */
3231 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3232 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3233 if (sys$
open (&fab
, 0, 0) & 1)
3234 sys$
close (&fab
, 0, 0);
3240 xabpro
.xab$l_aclbuf
= 0;
3245 fab
.fab$l_fna
= new;
3246 fab
.fab$b_fns
= strlen (new);
3250 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3251 fab
.fab$b_rat
= FAB$M_CR
;
3254 /* Set the file protections such that we will be able to manipulate
3255 this file. Once we are done writing and renaming it, we will set
3256 the protections back. */
3258 fab_final_pro
= xabpro
.xab$w_pro
;
3260 sys$
setdfprot (0, &fab_final_pro
);
3261 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3263 /* Create the new file with either default attrs or attrs copied
3265 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3267 sys$
close (&fab
, 0, 0);
3268 /* As this is a "replacement" for creat, return a file descriptor
3269 opened for writing. */
3270 return open (new, O_WRONLY
);
3275 #include <varargs.h>
3278 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3282 sys_creat (va_alist
)
3285 va_list list_incrementor
;
3288 int rfd
; /* related file descriptor */
3289 int fd
; /* Our new file descriptor */
3296 extern int vms_stmlf_recfm
;
3299 va_start (list_incrementor
);
3300 name
= va_arg (list_incrementor
, char *);
3301 mode
= va_arg (list_incrementor
, int);
3303 rfd
= va_arg (list_incrementor
, int);
3304 va_end (list_incrementor
);
3307 /* Use information from the related file descriptor to set record
3308 format of the newly created file. */
3309 fstat (rfd
, &st_buf
);
3310 switch (st_buf
.st_fab_rfm
)
3313 strcpy (rfm
, "rfm = fix");
3314 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3315 strcpy (rat
, "rat = ");
3316 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3318 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3319 strcat (rat
, "ftn");
3320 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3321 strcat (rat
, "prn");
3322 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3323 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3324 strcat (rat
, ", blk");
3326 strcat (rat
, "blk");
3327 return creat (name
, 0, rfm
, rat
, mrs
);
3330 strcpy (rfm
, "rfm = vfc");
3331 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3332 strcpy (rat
, "rat = ");
3333 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3335 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3336 strcat (rat
, "ftn");
3337 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3338 strcat (rat
, "prn");
3339 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3340 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3341 strcat (rat
, ", blk");
3343 strcat (rat
, "blk");
3344 return creat (name
, 0, rfm
, rat
, fsz
);
3347 strcpy (rfm
, "rfm = stm");
3351 strcpy (rfm
, "rfm = stmcr");
3355 strcpy (rfm
, "rfm = stmlf");
3359 strcpy (rfm
, "rfm = udf");
3363 strcpy (rfm
, "rfm = var");
3366 strcpy (rat
, "rat = ");
3367 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3369 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3370 strcat (rat
, "ftn");
3371 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3372 strcat (rat
, "prn");
3373 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3374 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3375 strcat (rat
, ", blk");
3377 strcat (rat
, "blk");
3381 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3382 strcpy (rat
, "rat=cr");
3384 /* Until the VAX C RTL fixes the many bugs with modes, always use
3385 mode 0 to get the user's default protection. */
3386 fd
= creat (name
, 0, rfm
, rat
);
3387 if (fd
< 0 && errno
== EEXIST
)
3389 if (unlink (name
) < 0)
3390 report_file_error ("delete", build_string (name
));
3391 fd
= creat (name
, 0, rfm
, rat
);
3397 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3398 sys_fwrite (ptr
, size
, num
, fp
)
3399 register char * ptr
;
3402 register int tot
= num
* size
;
3409 * The VMS C library routine creat actually creates a new version of an
3410 * existing file rather than truncating the old version. There are times
3411 * when this is not the desired behavior, for instance, when writing an
3412 * auto save file (you only want one version), or when you don't have
3413 * write permission in the directory containing the file (but the file
3414 * itself is writable). Hence this routine, which is equivalent to
3415 * "close (creat (fn, 0));" on Unix if fn already exists.
3421 struct FAB xfab
= cc$rms_fab
;
3422 struct RAB xrab
= cc$rms_rab
;
3425 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3426 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3427 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3428 xfab
.fab$l_fna
= fn
;
3429 xfab
.fab$b_fns
= strlen (fn
);
3430 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3432 xrab
.rab$l_fab
= &xfab
;
3434 /* This gibberish opens the file, positions to the first record, and
3435 deletes all records from there until the end of file. */
3436 if ((sys$
open (&xfab
) & 01) == 01)
3438 if ((sys$
connect (&xrab
) & 01) == 01 &&
3439 (sys$
find (&xrab
) & 01) == 01 &&
3440 (sys$
truncate (&xrab
) & 01) == 01)
3451 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3452 SYSPRV or a readable SYSUAF.DAT. */
3458 * Routine to read the VMS User Authorization File and return
3459 * a specific user's record.
3462 static struct UAF retuaf
;
3465 get_uaf_name (uname
)
3472 uaf_fab
= cc$rms_fab
;
3473 uaf_rab
= cc$rms_rab
;
3474 /* initialize fab fields */
3475 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3476 uaf_fab
.fab$b_fns
= 21;
3477 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3478 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3479 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3480 /* initialize rab fields */
3481 uaf_rab
.rab$l_fab
= &uaf_fab
;
3482 /* open the User Authorization File */
3483 status
= sys$
open (&uaf_fab
);
3487 vaxc$errno
= status
;
3490 status
= sys$
connect (&uaf_rab
);
3494 vaxc$errno
= status
;
3497 /* read the requested record - index is in uname */
3498 uaf_rab
.rab$l_kbf
= uname
;
3499 uaf_rab
.rab$b_ksz
= strlen (uname
);
3500 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3501 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3502 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3503 status
= sys$
get (&uaf_rab
);
3507 vaxc$errno
= status
;
3510 /* close the User Authorization File */
3511 status
= sys$
disconnect (&uaf_rab
);
3515 vaxc$errno
= status
;
3518 status
= sys$
close (&uaf_fab
);
3522 vaxc$errno
= status
;
3536 uaf_fab
= cc$rms_fab
;
3537 uaf_rab
= cc$rms_rab
;
3538 /* initialize fab fields */
3539 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3540 uaf_fab
.fab$b_fns
= 21;
3541 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3542 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3543 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3544 /* initialize rab fields */
3545 uaf_rab
.rab$l_fab
= &uaf_fab
;
3546 /* open the User Authorization File */
3547 status
= sys$
open (&uaf_fab
);
3551 vaxc$errno
= status
;
3554 status
= sys$
connect (&uaf_rab
);
3558 vaxc$errno
= status
;
3561 /* read the requested record - index is in uic */
3562 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3563 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3564 uaf_rab
.rab$b_ksz
= sizeof uic
;
3565 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3566 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3567 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3568 status
= sys$
get (&uaf_rab
);
3572 vaxc$errno
= status
;
3575 /* close the User Authorization File */
3576 status
= sys$
disconnect (&uaf_rab
);
3580 vaxc$errno
= status
;
3583 status
= sys$
close (&uaf_fab
);
3587 vaxc$errno
= status
;
3593 static struct passwd retpw
;
3601 /* copy these out first because if the username is 32 chars, the next
3602 section will overwrite the first byte of the UIC */
3603 retpw
.pw_uid
= up
->uaf$w_mem
;
3604 retpw
.pw_gid
= up
->uaf$w_grp
;
3606 /* I suppose this is not the best sytle, to possibly overwrite one
3607 byte beyond the end of the field, but what the heck... */
3608 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3609 while (ptr
[-1] == ' ')
3612 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3614 /* the rest of these are counted ascii strings */
3615 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3616 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3617 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3618 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3619 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3620 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3621 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3622 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3626 #else /* not READ_SYSUAF */
3627 static struct passwd retpw
;
3628 #endif /* not READ_SYSUAF */
3639 unsigned char * full
;
3640 #endif /* READ_SYSUAF */
3645 if ('a' <= *ptr
&& *ptr
<= 'z')
3650 if (!(up
= get_uaf_name (name
)))
3652 return cnv_uaf_pw (up
);
3654 if (strcmp (name
, getenv ("USER")) == 0)
3656 retpw
.pw_uid
= getuid ();
3657 retpw
.pw_gid
= getgid ();
3658 strcpy (retpw
.pw_name
, name
);
3659 if (full
= egetenv ("FULLNAME"))
3660 strcpy (retpw
.pw_gecos
, full
);
3662 *retpw
.pw_gecos
= '\0';
3663 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
3664 *retpw
.pw_shell
= '\0';
3669 #endif /* not READ_SYSUAF */
3679 if (!(up
= get_uaf_uic (uid
)))
3681 return cnv_uaf_pw (up
);
3683 if (uid
== sys_getuid ())
3684 return getpwnam (egetenv ("USER"));
3687 #endif /* not READ_SYSUAF */
3690 /* return total address space available to the current process. This is
3691 the sum of the current p0 size, p1 size and free page table entries
3696 unsigned long free_pages
;
3697 unsigned long frep0va
;
3698 unsigned long frep1va
;
3701 item_code
= JPI$_FREPTECNT
;
3702 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
3705 vaxc$errno
= status
;
3710 item_code
= JPI$_FREP0VA
;
3711 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
3714 vaxc$errno
= status
;
3717 item_code
= JPI$_FREP1VA
;
3718 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
3721 vaxc$errno
= status
;
3725 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
3728 define_logical_name (varname
, string
)
3732 struct dsc$descriptor_s strdsc
=
3733 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
3734 struct dsc$descriptor_s envdsc
=
3735 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3736 struct dsc$descriptor_s lnmdsc
=
3737 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3739 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
3742 delete_logical_name (varname
)
3745 struct dsc$descriptor_s envdsc
=
3746 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3747 struct dsc$descriptor_s lnmdsc
=
3748 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3750 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
3764 error ("execvp system call not implemented");
3772 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
3773 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
3774 char from_esn
[NAM$C_MAXRSS
];
3775 char to_esn
[NAM$C_MAXRSS
];
3777 from_fab
.fab$l_fna
= from
;
3778 from_fab
.fab$b_fns
= strlen (from
);
3779 from_fab
.fab$l_nam
= &from_nam
;
3780 from_fab
.fab$l_fop
= FAB$M_NAM
;
3782 from_nam
.nam$l_esa
= from_esn
;
3783 from_nam
.nam$b_ess
= sizeof from_esn
;
3785 to_fab
.fab$l_fna
= to
;
3786 to_fab
.fab$b_fns
= strlen (to
);
3787 to_fab
.fab$l_nam
= &to_nam
;
3788 to_fab
.fab$l_fop
= FAB$M_NAM
;
3790 to_nam
.nam$l_esa
= to_esn
;
3791 to_nam
.nam$b_ess
= sizeof to_esn
;
3793 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
3799 if (status
== RMS$_DEV
)
3803 vaxc$errno
= status
;
3808 /* This function renames a file like `rename', but it strips
3809 the version number from the "to" filename, such that the "to" file is
3810 will always be a new version. It also sets the file protection once it is
3811 finished. The protection that we will use is stored in fab_final_pro,
3812 and was set when we did a creat_copy_attrs to create the file that we
3815 We could use the chmod function, but Eunichs uses 3 bits per user category
3816 to describe the protection, and VMS uses 4 (write and delete are seperate
3817 bits). To maintain portability, the VMS implementation of `chmod' wires
3818 the W and D bits together. */
3821 static struct fibdef fib
; /* We need this initialized to zero */
3822 char vms_file_written
[NAM$C_MAXRSS
];
3825 rename_sans_version (from
,to
)
3832 struct FAB to_fab
= cc$rms_fab
;
3833 struct NAM to_nam
= cc$rms_nam
;
3834 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
3835 struct dsc$descriptor fib_attr
[2]
3836 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
3837 char to_esn
[NAM$C_MAXRSS
];
3839 $
DESCRIPTOR (disk
,to_esn
);
3841 to_fab
.fab$l_fna
= to
;
3842 to_fab
.fab$b_fns
= strlen (to
);
3843 to_fab
.fab$l_nam
= &to_nam
;
3844 to_fab
.fab$l_fop
= FAB$M_NAM
;
3846 to_nam
.nam$l_esa
= to_esn
;
3847 to_nam
.nam$b_ess
= sizeof to_esn
;
3849 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
3851 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
3852 *(to_nam
.nam$l_ver
) = '\0';
3854 stat
= rename (from
, to_esn
);
3858 strcpy (vms_file_written
, to_esn
);
3860 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
3861 to_fab
.fab$b_fns
= strlen (vms_file_written
);
3863 /* Now set the file protection to the correct value */
3864 sys$
open (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
3866 /* Copy these fields into the fib */
3867 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
3868 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
3869 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
3871 sys$
close (&to_fab
, 0, 0);
3873 stat
= sys$
assign (&disk
, &chan
, 0, 0); /* open a channel to the disk */
3876 stat
= sys$
qiow (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
3877 0, 0, 0, &fib_attr
, 0);
3880 stat
= sys$
dassgn (chan
);
3883 strcpy (vms_file_written
, to_esn
); /* We will write this to the screen*/
3893 unsigned short fid
[3];
3894 char esa
[NAM$C_MAXRSS
];
3897 fab
.fab$l_fop
= FAB$M_OFP
;
3898 fab
.fab$l_fna
= file
;
3899 fab
.fab$b_fns
= strlen (file
);
3900 fab
.fab$l_nam
= &nam
;
3903 nam
.nam$l_esa
= esa
;
3904 nam
.nam$b_ess
= NAM$C_MAXRSS
;
3906 status
= SYS$
PARSE (&fab
);
3907 if ((status
& 1) == 0)
3910 vaxc$errno
= status
;
3913 status
= SYS$
SEARCH (&fab
);
3914 if ((status
& 1) == 0)
3917 vaxc$errno
= status
;
3921 fid
[0] = nam
.nam$w_fid
[0];
3922 fid
[1] = nam
.nam$w_fid
[1];
3923 fid
[2] = nam
.nam$w_fid
[2];
3925 fab
.fab$l_fna
= new;
3926 fab
.fab$b_fns
= strlen (new);
3928 status
= SYS$
PARSE (&fab
);
3929 if ((status
& 1) == 0)
3932 vaxc$errno
= status
;
3936 nam
.nam$w_fid
[0] = fid
[0];
3937 nam
.nam$w_fid
[1] = fid
[1];
3938 nam
.nam$w_fid
[2] = fid
[2];
3940 nam
.nam$l_esa
= nam
.nam$l_name
;
3941 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
3943 status
= SYS$
ENTER (&fab
);
3944 if ((status
& 1) == 0)
3947 vaxc$errno
= status
;
3957 printf ("%s not yet implemented\r\n", badfunc
);
3965 /* Arrange to return a range centered on zero. */
3966 return rand () - (1 << 30);
3977 /* Called from init_sys_modes. */
3982 /* If we're not on an HFT we shouldn't do any of this. We determine
3983 if we are on an HFT by trying to get an HFT error code. If this
3984 call fails, we're not on an HFT. */
3986 if (ioctl (0, HFQERROR
, &junk
) < 0)
3988 #else /* not IBMR2AIX */
3989 if (ioctl (0, HFQEIO
, 0) < 0)
3991 #endif /* not IBMR2AIX */
3993 /* On AIX the default hft keyboard mapping uses backspace rather than delete
3994 as the rubout key's ASCII code. Here this is changed. The bug is that
3995 there's no way to determine the old mapping, so in reset_sys_modes
3996 we need to assume that the normal map had been present. Of course, this
3997 code also doesn't help if on a terminal emulator which doesn't understand
4001 struct hfkeymap keymap
;
4003 buf
.hf_bufp
= (char *)&keymap
;
4004 buf
.hf_buflen
= sizeof (keymap
);
4005 keymap
.hf_nkeys
= 2;
4006 keymap
.hfkey
[0].hf_kpos
= 15;
4007 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4009 keymap
.hfkey
[0].hf_keyidh
= '<';
4010 #else /* not IBMR2AIX */
4011 keymap
.hfkey
[0].hf_page
= '<';
4012 #endif /* not IBMR2AIX */
4013 keymap
.hfkey
[0].hf_char
= 127;
4014 keymap
.hfkey
[1].hf_kpos
= 15;
4015 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4017 keymap
.hfkey
[1].hf_keyidh
= '<';
4018 #else /* not IBMR2AIX */
4019 keymap
.hfkey
[1].hf_page
= '<';
4020 #endif /* not IBMR2AIX */
4021 keymap
.hfkey
[1].hf_char
= 127;
4022 hftctl (0, HFSKBD
, &buf
);
4024 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4026 line_ins_del_ok
= char_ins_del_ok
= 0;
4029 /* Reset the rubout key to backspace. */
4034 struct hfkeymap keymap
;
4038 if (ioctl (0, HFQERROR
, &junk
) < 0)
4040 #else /* not IBMR2AIX */
4041 if (ioctl (0, HFQEIO
, 0) < 0)
4043 #endif /* not IBMR2AIX */
4045 buf
.hf_bufp
= (char *)&keymap
;
4046 buf
.hf_buflen
= sizeof (keymap
);
4047 keymap
.hf_nkeys
= 2;
4048 keymap
.hfkey
[0].hf_kpos
= 15;
4049 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4051 keymap
.hfkey
[0].hf_keyidh
= '<';
4052 #else /* not IBMR2AIX */
4053 keymap
.hfkey
[0].hf_page
= '<';
4054 #endif /* not IBMR2AIX */
4055 keymap
.hfkey
[0].hf_char
= 8;
4056 keymap
.hfkey
[1].hf_kpos
= 15;
4057 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4059 keymap
.hfkey
[1].hf_keyidh
= '<';
4060 #else /* not IBMR2AIX */
4061 keymap
.hfkey
[1].hf_page
= '<';
4062 #endif /* not IBMR2AIX */
4063 keymap
.hfkey
[1].hf_char
= 8;
4064 hftctl (0, HFSKBD
, &buf
);