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
605 = (SIGTYPE (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
610 restore_signal_handlers (saved_handlers
)
611 struct save_signal
*saved_handlers
;
613 while (saved_handlers
->code
)
615 signal (saved_handlers
->code
, saved_handlers
->handler
);
627 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
637 #ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
642 sigunblock (sigmask (SIGWINCH
));
644 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
646 interrupts_deferred
= 0;
652 sigblock (sigmask (SIGWINCH
));
654 fcntl (0, F_SETFL
, old_fcntl_flags
);
655 interrupts_deferred
= 1;
658 #else /* no FASYNC */
659 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
664 ioctl (0, FIOASYNC
, &on
);
665 interrupts_deferred
= 0;
672 ioctl (0, FIOASYNC
, &off
);
673 interrupts_deferred
= 1;
676 #else /* not FASYNC, not STRIDE */
680 croak ("request_sigio");
685 croak ("unrequest_sigio");
692 /* The initial tty mode bits */
693 struct emacs_tty old_tty
;
695 int term_initted
; /* 1 if outer tty status has been recorded */
698 /* BSD 4.1 needs to keep track of the lmode bits in order to start
705 #endif /* F_SETOWN */
707 /* This may also be defined in stdio,
708 but if so, this does no harm,
709 and using the same name avoids wasting the other one's space. */
711 #if defined (USG) || defined (DGUX)
712 unsigned char _sobuf
[BUFSIZ
+8];
718 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
721 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
726 struct emacs_tty tty
;
730 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
731 extern int (*interrupt_signal
) ();
740 input_ef
= get_kbd_event_flag ();
741 /* LIB$GET_EF (&input_ef); */
742 SYS$
CLREF (input_ef
);
745 timer_ef
= get_timer_event_flag ();
746 /* LIB$GET_EF (&timer_ef); */
747 SYS$
CLREF (timer_ef
);
750 LIB$
GET_EF (&process_ef
);
751 SYS$
CLREF (process_ef
);
753 if (input_ef
/ 32 != process_ef
/ 32)
754 croak ("Input and process event flags in different clusters.");
755 if (input_ef
/ 32 != timer_ef
/ 32)
756 croak ("Input and process event flags in different clusters.");
757 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
758 ((unsigned) 1 << (process_ef
% 32));
759 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
760 ((unsigned) 1 << (timer_ef
% 32));
762 sys_access_reinit ();
766 EMACS_GET_TTY (input_fd
, &old_tty
);
768 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
773 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
774 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
776 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
778 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
779 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
780 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
783 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
785 tty
.main
.c_iflag
&= ~IXANY
;
789 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
790 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
792 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
796 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
797 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
800 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
801 /* Set up C-g for both SIGQUIT and SIGINT.
802 We don't know which we will get, but we handle both alike
803 so which one it really gives us does not matter. */
804 tty
.main
.c_cc
[VQUIT
] = quit_char
;
805 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
806 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
808 tty
.main
.c_cc
[VSWTCH
] = CDEL
; /* Turn off shell layering use
811 #if defined (mips) || defined (HAVE_TCATTR)
812 /* The following code looks like the right thing in general,
813 but it is said to cause a crash on USG V.4.
814 Let's play safe by turning it on only for the MIPS. */
816 tty
.main
.c_cc
[VSUSP
] = CDEL
; /* Turn off mips handling of C-z. */
819 tty
.main
.c_cc
[V_DSUSP
] = CDEL
; /* Turn off mips handling of C-y. */
821 #endif /* mips or HAVE_TCATTR */
824 /* AIX enhanced edit loses NULs, so disable it */
826 tty
.main
.c_iflag
&= ~ASCEDIT
;
828 tty
.main
.c_cc
[VSTRT
] = 255;
829 tty
.main
.c_cc
[VSTOP
] = 255;
830 tty
.main
.c_cc
[VSUSP
] = 255;
831 tty
.main
.c_cc
[VDSUSP
] = 255;
832 #endif /* IBMR2AIX */
833 /* Also, PTY overloads NUL and BREAK.
834 don't ignore break, but don't signal either, so it looks like NUL.
835 This really serves a purpose only if running in an XTERM window
836 or via TELNET or the like, but does no harm elsewhere. */
837 tty
.main
.c_iflag
&= ~IGNBRK
;
838 tty
.main
.c_iflag
&= ~BRKINT
;
840 #else /* if not HAVE_TERMIO */
842 tty
.main
.tt_char
|= TT$M_NOECHO
;
844 tty
.main
.tt_char
|= TT$M_EIGHTBIT
846 tty
.main
.tt_char
|= TT$M_TTSYNC
;
848 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
849 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
850 #else /* not VMS (BSD, that is) */
851 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
853 tty
.main
.sg_flags
|= ANYP
;
854 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
855 #endif /* not VMS (BSD, that is) */
856 #endif /* not HAVE_TERMIO */
858 /* If going to use CBREAK mode, we must request C-g to interrupt
859 and turn off start and stop chars, etc. If not going to use
860 CBREAK mode, do this anyway so as to turn off local flow
861 control for user coming over network on 4.2; in this case,
862 only t_stopc and t_startc really matter. */
865 /* Note: if not using CBREAK mode, it makes no difference how we
867 tty
.tchars
= new_tchars
;
868 tty
.tchars
.t_intrc
= quit_char
;
871 tty
.tchars
.t_startc
= '\021';
872 tty
.tchars
.t_stopc
= '\023';
875 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
881 #define LNOFLSH 0100000
884 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
890 #endif /* TIOCGETC */
891 #endif /* not HAVE_TERMIO */
894 tty
.ltchars
= new_ltchars
;
895 #endif /* TIOCGLTC */
897 EMACS_SET_TTY (input_fd
, &tty
, 0);
899 /* This code added to insure that, if flow-control is not to be used,
900 we have an unlocked terminal at the start. */
903 if (!flow_control
) ioctl (0, TCXONC
, 1);
907 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
915 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
916 to be only LF. This is the way that is done. */
919 if (ioctl (1, HFTGETID
, &tty
) != -1)
920 write (1, "\033[20l", 5);
926 /* Appears to do nothing when in PASTHRU mode.
927 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
928 interrupt_signal, oob_chars, 0, 0, 0, 0);
935 #ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
938 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
939 fcntl (0, F_SETOWN
, getpid ());
942 #endif /* F_GETOWN */
950 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
954 /* This symbol is defined on recent USG systems.
955 Someone says without this call USG won't really buffer the file
956 even with a call to setbuf. */
957 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
959 setbuf (stdout
, _sobuf
);
961 set_terminal_modes ();
962 if (term_initted
&& no_redraw_on_reenter
)
964 if (display_completed
)
965 direct_output_forward_char (0);
971 if (FRAMEP (Vterminal_frame
))
972 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
979 /* Return nonzero if safe to use tabs in output.
980 At the time this is called, init_sys_modes has not been done yet. */
984 struct emacs_tty tty
;
986 EMACS_GET_TTY (input_fd
, &tty
);
987 return EMACS_TTY_TABS_OK (&tty
);
990 /* Get terminal size from system.
991 Store number of lines into *heightp and width into *widthp.
992 If zero or a negative number is stored, the value is not valid. */
994 get_frame_size (widthp
, heightp
)
995 int *widthp
, *heightp
;
1001 struct winsize size
;
1003 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1004 *widthp
= *heightp
= 0;
1007 *widthp
= size
.ws_col
;
1008 *heightp
= size
.ws_row
;
1014 /* SunOS - style. */
1015 struct ttysize size
;
1017 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1018 *widthp
= *heightp
= 0;
1021 *widthp
= size
.ts_cols
;
1022 *heightp
= size
.ts_lines
;
1028 struct sensemode tty
;
1030 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1031 &tty
.class, 12, 0, 0, 0, 0);
1032 *widthp
= tty
.scr_wid
;
1033 *heightp
= tty
.scr_len
;
1035 #else /* system doesn't know size */
1040 #endif /* not VMS */
1041 #endif /* not SunOS-style */
1042 #endif /* not BSD-style */
1046 /* Prepare the terminal for exiting Emacs; move the cursor to the
1047 bottom of the frame, turn off interrupt-driven I/O, etc. */
1057 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1059 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1060 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1061 /* clear_end_of_line may move the cursor */
1062 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1065 /* HFT devices normally use ^J as a LF/CR. We forced it to
1066 do the LF only. Now, we need to reset it. */
1069 if (ioctl (1, HFTGETID
, &tty
) != -1)
1070 write (1, "\033[20h", 5);
1074 reset_terminal_modes ();
1078 /* Avoid possible loss of output when changing terminal modes. */
1079 fsync (fileno (stdout
));
1084 #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */
1085 if (interrupt_input
)
1088 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1090 #endif /* F_SETOWN */
1091 #endif /* F_SETFL */
1093 if (interrupt_input
)
1097 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1107 /* Set up the proper status flags for use of a pty. */
1112 /* I'm told that TOICREMOTE does not mean control chars
1113 "can't be sent" but rather that they don't have
1114 input-editing or signaling effects.
1115 That should be good, because we have other ways
1116 to do those things in Emacs.
1117 However, telnet mode seems not to work on 4.2.
1118 So TIOCREMOTE is turned off now. */
1120 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1121 will hang. In particular, the "timeout" feature (which
1122 causes a read to return if there is no data available)
1123 does this. Also it is known that telnet mode will hang
1124 in such a way that Emacs must be stopped (perhaps this
1125 is the same problem).
1127 If TIOCREMOTE is turned off, then there is a bug in
1128 hp-ux which sometimes loses data. Apparently the
1129 code which blocks the master process when the internal
1130 buffer fills up does not work. Other than this,
1131 though, everything else seems to work fine.
1133 Since the latter lossage is more benign, we may as well
1134 lose that way. -- cph */
1139 ioctl (fd
, FIONBIO
, &on
);
1144 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1145 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1146 /* cause EMACS not to die when it should, i.e., when its own controlling */
1147 /* tty goes away. I've complained to the AIX developers, and they may */
1148 /* change this behavior, but I'm not going to hold my breath. */
1149 signal (SIGHUP
, SIG_IGN
);
1152 #endif /* HAVE_PTYS */
1156 /* Assigning an input channel is done at the start of Emacs execution.
1157 This is called each time Emacs is resumed, also, but does nothing
1158 because input_chain is no longer zero. */
1166 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1172 /* Deassigning the input channel is done before exiting. */
1176 return SYS$
DASSGN (input_fd
);
1181 /* Request reading one character into the keyboard buffer.
1182 This is done as soon as the buffer becomes empty. */
1187 waiting_for_ast
= 0;
1189 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1190 &input_iosb
, kbd_input_ast
, 1,
1191 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1196 /* Ast routine that is called when keyboard input comes in
1197 in accord with the SYS$QIO above. */
1201 register int c
= -1;
1202 int old_errno
= errno
;
1203 extern EMACS_TIME
*input_available_clear_time
;
1205 if (waiting_for_ast
)
1206 SYS$
SETEF (input_ef
);
1207 waiting_for_ast
= 0;
1210 if (input_count
== 25)
1212 printf ("Ast # %d,", input_count
);
1213 printf (" iosb = %x, %x, %x, %x",
1214 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1217 if (input_iosb
.offset
)
1221 printf (", char = 0%o", c
);
1233 struct input_event e
;
1234 e
.kind
= ascii_keystroke
;
1235 XSET (buf
[i
].code
, Lisp_Int
, cbuf
[i
]);
1236 e
.frame
= selected_frame
;
1237 kbd_buffer_store_event (&e
);
1240 if (input_available_clear_time
)
1241 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1245 /* Wait until there is something in kbd_buffer. */
1247 wait_for_kbd_input ()
1249 extern int have_process_input
, process_exited
;
1251 /* If already something, avoid doing system calls. */
1252 if (detect_input_pending ())
1256 /* Clear a flag, and tell ast routine above to set it. */
1257 SYS$
CLREF (input_ef
);
1258 waiting_for_ast
= 1;
1259 /* Check for timing error: ast happened while we were doing that. */
1260 if (!detect_input_pending ())
1262 /* No timing error: wait for flag to be set. */
1263 set_waiting_for_input (0);
1264 SYS$
WFLOR (input_ef
, input_eflist
);
1265 clear_waiting_for_input (0);
1266 if (!detect_input_pending ())
1267 /* Check for subprocess input availability */
1269 int dsp
= have_process_input
|| process_exited
;
1271 SYS$
CLREF (process_ef
);
1272 if (have_process_input
)
1273 process_command_input ();
1278 update_mode_lines
++;
1279 redisplay_preserve_echo_area ();
1283 waiting_for_ast
= 0;
1286 /* Get rid of any pending QIO, when we are about to suspend
1287 or when we want to throw away pending input.
1288 We wait for a positive sign that the AST routine has run
1289 and therefore there is no I/O request queued when we return.
1290 SYS$SETAST is used to avoid a timing error. */
1295 printf ("At end_kbd_input.\n");
1299 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1301 SYS$
CANCEL (input_fd
);
1306 /* Clear a flag, and tell ast routine above to set it. */
1307 SYS$
CLREF (input_ef
);
1308 waiting_for_ast
= 1;
1310 SYS$
CANCEL (input_fd
);
1312 SYS$
WAITFR (input_ef
);
1313 waiting_for_ast
= 0;
1316 /* Wait for either input available or time interval expiry. */
1318 input_wait_timeout (timeval
)
1319 int timeval
; /* Time to wait, in seconds */
1322 static int zero
= 0;
1323 static int large
= -10000000;
1325 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1327 /* If already something, avoid doing system calls. */
1328 if (detect_input_pending ())
1332 /* Clear a flag, and tell ast routine above to set it. */
1333 SYS$
CLREF (input_ef
);
1334 waiting_for_ast
= 1;
1335 /* Check for timing error: ast happened while we were doing that. */
1336 if (!detect_input_pending ())
1338 /* No timing error: wait for flag to be set. */
1340 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1341 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1343 waiting_for_ast
= 0;
1346 /* The standard `sleep' routine works some other way
1347 and it stops working if you have ever quit out of it.
1348 This one continues to work. */
1354 static int zero
= 0;
1355 static int large
= -10000000;
1357 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1360 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1361 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1376 croak ("request sigio");
1381 croak ("unrequest sigio");
1386 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1391 #ifndef SYSTEM_MALLOC
1398 /* Some systems that cannot dump also cannot implement these. */
1401 * Return the address of the start of the text segment prior to
1402 * doing an unexec. After unexec the return value is undefined.
1403 * See crt0.c for further explanation and _start.
1407 #ifndef CANNOT_UNEXEC
1412 return ((char *) TEXT_START
);
1416 return ((char *) csrt
);
1417 #else /* not GOULD */
1418 extern int _start ();
1419 return ((char *) _start
);
1421 #endif /* TEXT_START */
1423 #endif /* not CANNOT_UNEXEC */
1426 * Return the address of the start of the data segment prior to
1427 * doing an unexec. After unexec the return value is undefined.
1428 * See crt0.c for further information and definition of data_start.
1430 * Apparently, on BSD systems this is etext at startup. On
1431 * USG systems (swapping) this is highly mmu dependent and
1432 * is also dependent on whether or not the program is running
1433 * with shared text. Generally there is a (possibly large)
1434 * gap between end of text and start of data with shared text.
1436 * On Uniplus+ systems with shared text, data starts at a
1437 * fixed address. Each port (from a given oem) is generally
1438 * different, and the specific value of the start of data can
1439 * be obtained via the UniPlus+ specific "uvar" system call,
1440 * however the method outlined in crt0.c seems to be more portable.
1442 * Probably what will have to happen when a USG unexec is available,
1443 * at least on UniPlus, is temacs will have to be made unshared so
1444 * that text and data are contiguous. Then once loadup is complete,
1445 * unexec will produce a shared executable where the data can be
1446 * at the normal shared text boundry and the startofdata variable
1447 * will be patched by unexec to the correct value.
1455 return ((char *) DATA_START
);
1457 extern int data_start
;
1458 return ((char *) &data_start
);
1461 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1464 /* Some systems that cannot dump also cannot implement these. */
1467 * Return the address of the end of the text segment prior to
1468 * doing an unexec. After unexec the return value is undefined.
1475 return ((char *) TEXT_END
);
1478 return ((char *) &etext
);
1483 * Return the address of the end of the data segment prior to
1484 * doing an unexec. After unexec the return value is undefined.
1491 return ((char *) DATA_END
);
1494 return ((char *) &edata
);
1498 #endif /* not CANNOT_DUMP */
1500 /* Get_system_name returns as its value
1501 a string for the Lisp function system-name to return. */
1508 /* Can't have this within the function since `static' is #defined to nothing */
1509 static struct utsname get_system_name_name
;
1516 uname (&get_system_name_name
);
1517 return (get_system_name_name
.nodename
);
1521 #else /* not USG, not 4.1 */
1522 static char system_name_saved
[32];
1525 if ((sp
= egetenv ("SYS$NODE")) == 0)
1531 if ((end
= index (sp
, ':')) != 0)
1534 strcpy (system_name_saved
, sp
);
1536 gethostname (system_name_saved
, sizeof (system_name_saved
));
1537 #endif /* not VMS */
1538 return system_name_saved
;
1539 #endif /* not USG, not 4.1 */
1540 #endif /* not USG */
1546 #ifdef HAVE_X_WINDOWS
1547 /* Cause explanatory error message at compile time,
1548 since the select emulation is not good enough for X. */
1549 int *x
= &x_windows_lose_if_no_select_system_call
;
1552 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1553 * Only checks read descriptors.
1555 /* How long to wait between checking fds in select */
1556 #define SELECT_PAUSE 1
1559 /* For longjmp'ing back to read_input_waiting. */
1561 jmp_buf read_alarm_throw
;
1563 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1564 The read_socket_hook function sets this to 1 while it is waiting. */
1566 int read_alarm_should_throw
;
1574 #else /* not BSD4_1 */
1575 signal (SIGALRM
, SIG_IGN
);
1576 #endif /* not BSD4_1 */
1577 if (read_alarm_should_throw
)
1578 longjmp (read_alarm_throw
, 1);
1581 /* Only rfds are checked. */
1583 select (nfds
, rfds
, wfds
, efds
, timeout
)
1585 int *rfds
, *wfds
, *efds
, *timeout
;
1587 int ravail
= 0, orfds
= 0, old_alarm
;
1588 int timeoutval
= timeout
? *timeout
: 100000;
1589 int *local_timeout
= &timeoutval
;
1590 extern int proc_buffered_char
[];
1591 #ifndef subprocesses
1592 int process_tick
= 0, update_tick
= 0;
1594 extern int process_tick
, update_tick
;
1596 SIGTYPE (*old_trap
) ();
1609 /* If we are looking only for the terminal, with no timeout,
1610 just read it and wait -- that's more efficient. */
1611 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1613 if (! detect_input_pending ())
1614 read_input_waiting ();
1619 /* Once a second, till the timer expires, check all the flagged read
1620 * descriptors to see if any input is available. If there is some then
1621 * set the corresponding bit in the return copy of rfds.
1625 register int to_check
, bit
, fd
;
1629 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1633 int avail
= 0, status
= 0;
1636 avail
= detect_input_pending (); /* Special keyboard handler */
1640 status
= ioctl (fd
, FIONREAD
, &avail
);
1641 #else /* no FIONREAD */
1642 /* Hoping it will return -1 if nothing available
1643 or 0 if all 0 chars requested are read. */
1644 if (proc_buffered_char
[fd
] >= 0)
1648 avail
= read (fd
, &buf
, 1);
1650 proc_buffered_char
[fd
] = buf
;
1652 #endif /* no FIONREAD */
1654 if (status
>= 0 && avail
> 0)
1662 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
1664 old_alarm
= alarm (0);
1665 old_trap
= (int (*)()) signal (SIGALRM
, select_alarm
);
1667 alarm (SELECT_PAUSE
);
1668 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1669 while (select_alarmed
== 0 && *local_timeout
!= 0
1670 && process_tick
== update_tick
)
1672 /* If we are interested in terminal input,
1673 wait by reading the terminal.
1674 That makes instant wakeup for terminal input at least. */
1677 read_input_waiting ();
1678 if (detect_input_pending ())
1684 (*local_timeout
) -= SELECT_PAUSE
;
1685 /* Reset the old alarm if there was one */
1687 signal (SIGALRM
, old_trap
);
1690 /* Reset or forge an interrupt for the original handler. */
1691 old_alarm
-= SELECT_PAUSE
;
1693 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
1697 if (*local_timeout
== 0) /* Stop on timer being cleared */
1703 /* Read keyboard input into the standard buffer,
1704 waiting for at least one character. */
1706 /* Make all keyboard buffers much bigger when using X windows. */
1707 #ifdef HAVE_X_WINDOWS
1708 #define BUFFER_SIZE_FACTOR 16
1710 #define BUFFER_SIZE_FACTOR 1
1713 read_input_waiting ()
1715 char buf
[256 * BUFFER_SIZE_FACTOR
];
1716 struct input_event e
;
1719 if (read_socket_hook
)
1721 read_alarm_should_throw
= 0;
1722 if (! setjmp (read_alarm_throw
))
1723 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
1728 nread
= read (fileno (stdin
), buf
, 1);
1730 /* Scan the chars for C-g and store them in kbd_buffer. */
1731 e
.kind
= ascii_keystroke
;
1732 e
.frame
= selected_frame
;
1733 for (i
= 0; i
< nread
; i
++)
1735 XSET (e
.code
, Lisp_Int
, buf
[i
]);
1736 kbd_buffer_store_event (&e
);
1737 /* Don't look at input that follows a C-g too closely.
1738 This reduces lossage due to autorepeat on C-g. */
1739 if (buf
[i
] == Ctl ('G'))
1744 #endif /* not HAVE_SELECT */
1745 #endif /* not VMS */
1755 * Partially emulate 4.2 open call.
1756 * open is defined as this in 4.1.
1758 * - added by Michael Bloom @ Citicorp/TTI
1763 sys_open (path
, oflag
, mode
)
1767 if (oflag
& O_CREAT
)
1768 return creat (path
, mode
);
1770 return open (path
, oflag
);
1777 lmode
= LINTRUP
| lmode
;
1778 ioctl (0, TIOCLSET
, &lmode
);
1785 lmode
= ~LINTRUP
& lmode
;
1786 ioctl (0, TIOCLSET
, &lmode
);
1793 interrupts_deferred
= 0;
1800 interrupts_deferred
= 1;
1803 /* still inside #ifdef BSD4_1 */
1806 int sigheld
; /* Mask of held signals */
1811 sigheld
|= sigbit (signum
);
1818 sigheld
|= sigbit (signum
);
1824 sigheld
&= ~sigbit (signum
);
1828 sigfree () /* Free all held signals */
1831 for (i
= 0; i
< NSIG
; i
++)
1832 if (sigheld
& sigbit (i
))
1839 return 1 << (i
- 1);
1841 #endif /* subprocesses */
1844 /* POSIX signals support - DJB */
1845 /* Anyone with POSIX signals should have ANSI C declarations */
1847 #ifdef POSIX_SIGNALS
1849 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
1850 static struct sigaction new_action
, old_action
;
1854 #ifdef POSIX_SIGNALS
1855 sigemptyset (&signal_empty_mask
);
1856 sigfillset (&signal_full_mask
);
1860 int (*signal_handler_t
) ();
1863 sys_signal (int signal_number
, signal_handler_t action
)
1866 /* This gets us restartable system calls for efficiency.
1867 The "else" code will works as well. */
1868 return (berk_signal (signal_number
, action
));
1870 sigemptyset (&new_action
.sa_mask
);
1871 new_action
.sa_handler
= action
;
1872 new_action
.sa_flags
= NULL
;
1873 sigaction (signal_number
, &new_action
, &old_action
);
1874 return (old_action
.sa_handler
);
1879 /* If we're compiling with GCC, we don't need this function, since it
1880 can be written as a macro. */
1882 sys_sigmask (int sig
)
1885 sigemptyset (&mask
);
1886 sigaddset (&mask
, sig
);
1892 sys_sigpause (sigset_t new_mask
)
1894 /* pause emulating berk sigpause... */
1895 sigsuspend (&new_mask
);
1899 /* I'd like to have these guys return pointers to the mask storage in here,
1900 but there'd be trouble if the code was saving multiple masks. I'll be
1901 safe and pass the structure. It normally won't be more than 2 bytes
1905 sys_sigblock (sigset_t new_mask
)
1908 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
1913 sys_sigunblock (sigset_t new_mask
)
1916 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
1921 sys_sigsetmask (sigset_t new_mask
)
1924 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1928 #endif /* POSIX_SIGNALS */
1935 register int length
;
1939 long max_str
= 65535;
1941 while (length
> max_str
) {
1942 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1947 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1949 while (length
-- > 0)
1951 #endif /* not VMS */
1954 /* Saying `void' requires a declaration, above, where bcopy is used
1955 and that declaration causes pain for systems where bcopy is a macro. */
1956 bcopy (b1
, b2
, length
)
1959 register int length
;
1962 long max_str
= 65535;
1964 while (length
> max_str
) {
1965 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
1971 (void) LIB$
MOVC3 (&length
, b1
, b2
);
1973 while (length
-- > 0)
1975 #endif /* not VMS */
1979 bcmp (b1
, b2
, length
) /* This could be a macro! */
1982 register int length
;
1985 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
1986 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
1988 return STR$
COMPARE (&src1
, &src2
);
1990 while (length
-- > 0)
1995 #endif /* not VMS */
1997 #endif /* not BSTRING */
2001 * The BSD random returns numbers in the range of
2002 * 0 to 2e31 - 1. The USG rand returns numbers in the
2003 * range of 0 to 2e15 - 1. This is probably not significant
2010 /* Arrange to return a range centered on zero. */
2011 return (rand () << 15) + rand () - (1 << 29);
2025 /* Arrange to return a range centered on zero. */
2026 return (rand () << 15) + rand () - (1 << 29);
2036 #ifdef WRONG_NAME_INSQUE
2049 /* If any place else asks for the TERM variable,
2050 allow it to be overridden with the EMACS_TERM variable
2051 before attempting to translate the logical name TERM. As a last
2052 resort, ask for VAX C's special idea of the TERM variable. */
2059 static char buf
[256];
2060 static struct dsc$descriptor_s equiv
2061 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2062 static struct dsc$descriptor_s d_name
2063 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2066 if (!strcmp (name
, "TERM"))
2068 val
= (char *) getenv ("EMACS_TERM");
2073 d_name
.dsc$w_length
= strlen (name
);
2074 d_name
.dsc$a_pointer
= name
;
2075 if (lib$
sys_trnlog (&d_name
, &eqlen
, &equiv
) == 1)
2077 char *str
= (char *) xmalloc (eqlen
+ 1);
2078 bcopy (buf
, str
, eqlen
);
2080 /* This is a storage leak, but a pain to fix. With luck,
2081 no one will ever notice. */
2084 return (char *) getenv (name
);
2089 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2090 to force a call on the debugger from within the image. */
2095 LIB$
SIGNAL (SS$_DEBUG
);
2101 #ifdef LINK_CRTL_SHARE
2102 #ifdef SHAREABLE_LIB_BUG
2103 /* Variables declared noshare and initialized in shareable libraries
2104 cannot be shared. The VMS linker incorrectly forces you to use a private
2105 version which is uninitialized... If not for this "feature", we
2106 could use the C library definition of sys_nerr and sys_errlist. */
2108 char *sys_errlist
[] =
2112 "no such file or directory",
2114 "interrupted system call",
2116 "no such device or address",
2117 "argument list too long",
2118 "exec format error",
2121 "no more processes",
2122 "not enough memory",
2123 "permission denied",
2125 "block device required",
2126 "mount devices busy",
2128 "cross-device link",
2133 "file table overflow",
2134 "too many open files",
2138 "no space left on device",
2140 "read-only file system",
2146 "vax/vms specific error code nontranslatable error"
2148 #endif /* SHAREABLE_LIB_BUG */
2149 #endif /* LINK_CRTL_SHARE */
2152 #ifdef INTERRUPTIBLE_OPEN
2156 sys_open (path
, oflag
, mode
)
2160 register int rtnval
;
2162 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2163 && (errno
== EINTR
));
2167 #endif /* INTERRUPTIBLE_OPEN */
2169 #ifdef INTERRUPTIBLE_CLOSE
2174 register int rtnval
;
2176 while ((rtnval
= close (fd
)) == -1
2177 && (errno
== EINTR
));
2181 #endif /* INTERRUPTIBLE_CLOSE */
2183 #ifdef INTERRUPTIBLE_IO
2186 sys_read (fildes
, buf
, nbyte
)
2191 register int rtnval
;
2193 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2194 && (errno
== EINTR
));
2199 sys_write (fildes
, buf
, nbyte
)
2204 register int rtnval
;
2206 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2207 && (errno
== EINTR
));
2211 #endif /* INTERRUPTIBLE_IO */
2215 * All of the following are for USG.
2217 * On USG systems the system calls are INTERRUPTIBLE by signals
2218 * that the user program has elected to catch. Thus the system call
2219 * must be retried in these cases. To handle this without massive
2220 * changes in the source code, we remap the standard system call names
2221 * to names for our own functions in sysdep.c that do the system call
2222 * with retries. Actually, for portability reasons, it is good
2223 * programming practice, as this example shows, to limit all actual
2224 * system calls to a single occurance in the source. Sure, this
2225 * adds an extra level of function call overhead but it is almost
2226 * always negligible. Fred Fish, Unisoft Systems Inc.
2229 char *sys_siglist
[NSIG
+ 1] =
2232 /* AIX has changed the signals a bit */
2233 "bogus signal", /* 0 */
2234 "hangup", /* 1 SIGHUP */
2235 "interrupt", /* 2 SIGINT */
2236 "quit", /* 3 SIGQUIT */
2237 "illegal instruction", /* 4 SIGILL */
2238 "trace trap", /* 5 SIGTRAP */
2239 "IOT instruction", /* 6 SIGIOT */
2240 "crash likely", /* 7 SIGDANGER */
2241 "floating point exception", /* 8 SIGFPE */
2242 "kill", /* 9 SIGKILL */
2243 "bus error", /* 10 SIGBUS */
2244 "segmentation violation", /* 11 SIGSEGV */
2245 "bad argument to system call", /* 12 SIGSYS */
2246 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2247 "alarm clock", /* 14 SIGALRM */
2248 "software termination signum", /* 15 SIGTERM */
2249 "user defined signal 1", /* 16 SIGUSR1 */
2250 "user defined signal 2", /* 17 SIGUSR2 */
2251 "death of a child", /* 18 SIGCLD */
2252 "power-fail restart", /* 19 SIGPWR */
2253 "bogus signal", /* 20 */
2254 "bogus signal", /* 21 */
2255 "bogus signal", /* 22 */
2256 "bogus signal", /* 23 */
2257 "bogus signal", /* 24 */
2258 "LAN I/O interrupt", /* 25 SIGAIO */
2259 "PTY I/O interrupt", /* 26 SIGPTY */
2260 "I/O intervention required", /* 27 SIGIOINT */
2261 "HFT grant", /* 28 SIGGRANT */
2262 "HFT retract", /* 29 SIGRETRACT */
2263 "HFT sound done", /* 30 SIGSOUND */
2264 "HFT input ready", /* 31 SIGMSG */
2266 "bogus signal", /* 0 */
2267 "hangup", /* 1 SIGHUP */
2268 "interrupt", /* 2 SIGINT */
2269 "quit", /* 3 SIGQUIT */
2270 "illegal instruction", /* 4 SIGILL */
2271 "trace trap", /* 5 SIGTRAP */
2272 "IOT instruction", /* 6 SIGIOT */
2273 "EMT instruction", /* 7 SIGEMT */
2274 "floating point exception", /* 8 SIGFPE */
2275 "kill", /* 9 SIGKILL */
2276 "bus error", /* 10 SIGBUS */
2277 "segmentation violation", /* 11 SIGSEGV */
2278 "bad argument to system call", /* 12 SIGSYS */
2279 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2280 "alarm clock", /* 14 SIGALRM */
2281 "software termination signum", /* 15 SIGTERM */
2282 "user defined signal 1", /* 16 SIGUSR1 */
2283 "user defined signal 2", /* 17 SIGUSR2 */
2284 "death of a child", /* 18 SIGCLD */
2285 "power-fail restart", /* 19 SIGPWR */
2286 #endif /* not AIX */
2291 * Warning, this function may not duplicate 4.2 action properly
2292 * under error conditions.
2296 /* In 4.1, param.h fails to define this. */
2297 #define MAXPATHLEN 1024
2306 char *npath
, *spath
;
2307 extern char *getcwd ();
2309 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2310 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2311 up to first slash. Should be harmless on other systems. */
2312 while (*npath
&& *npath
!= '/')
2314 strcpy (pathname
, npath
);
2315 free (spath
); /* getcwd uses malloc */
2319 #endif /* HAVE_GETWD */
2322 * Emulate rename using unlink/link. Note that this is
2323 * only partially correct. Also, doesn't enforce restriction
2324 * that files be of same type (regular->regular, dir->dir, etc).
2333 if (access (from
, 0) == 0)
2336 if (link (from
, to
) == 0)
2337 if (unlink (from
) == 0)
2345 /* Set priority value to PRIO. */
2348 setpriority (which
, who
, prio
)
2349 int which
, who
, prio
;
2353 nice (prio
- nice (0));
2360 * Substitute fork for vfork on USG flavors.
2368 #endif /* not HAVE_VFORK */
2370 #ifdef MISSING_UTIMES
2372 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2381 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2382 utimbuf structure defined anywhere but in the man page. */
2392 struct timeval tvp
[];
2395 utb
.actime
= tvp
[0].tv_sec
;
2396 utb
.modtime
= tvp
[1].tv_sec
;
2399 #endif /* IRIS_UTIME */
2405 /* HPUX curses library references perror, but as far as we know
2406 it won't be called. Anyway this definition will do for now. */
2412 #endif /* not HAVE_PERROR */
2418 * Emulate BSD dup2. First close newd if it already exists.
2419 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2420 * until we are, then close the unsuccessful ones.
2427 register int fd
, ret
;
2432 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2434 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2441 ret
= dup2 (old
,new);
2447 #endif /* not HAVE_DUP2 */
2450 * Gettimeofday. Simulate as much as possible. Only accurate
2451 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2452 * Only needed when subprocesses are defined.
2457 #ifndef HAVE_GETTIMEOFDAY
2461 gettimeofday (tp
, tzp
)
2463 struct timezone
*tzp
;
2465 extern long time ();
2467 tp
->tv_sec
= time ((long *)0);
2469 tzp
->tz_minuteswest
= -1;
2475 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2478 * This function will go away as soon as all the stubs fixed. (fnf)
2484 printf ("%s not yet implemented\r\n", badfunc
);
2493 char *sys_siglist
[NSIG
+ 1] =
2495 "null signal", /* 0 SIGNULL */
2496 "hangup", /* 1 SIGHUP */
2497 "interrupt", /* 2 SIGINT */
2498 "quit", /* 3 SIGQUIT */
2499 "illegal instruction", /* 4 SIGILL */
2500 "trace trap", /* 5 SIGTRAP */
2501 "abort termination", /* 6 SIGABRT */
2502 "SIGEMT", /* 7 SIGEMT */
2503 "floating point exception", /* 8 SIGFPE */
2504 "kill", /* 9 SIGKILL */
2505 "bus error", /* 10 SIGBUS */
2506 "segmentation violation", /* 11 SIGSEGV */
2507 "bad argument to system call", /* 12 SIGSYS */
2508 "write on a pipe with no reader", /* 13 SIGPIPE */
2509 "alarm clock", /* 14 SIGALRM */
2510 "software termination signal", /* 15 SIGTERM */
2511 "user defined signal 1", /* 16 SIGUSR1 */
2512 "user defined signal 2", /* 17 SIGUSR2 */
2513 "child stopped or terminated", /* 18 SIGCLD */
2514 "power-fail restart", /* 19 SIGPWR */
2515 "window size changed", /* 20 SIGWINCH */
2516 "undefined", /* 21 */
2517 "pollable event occured", /* 22 SIGPOLL */
2518 "sendable stop signal not from tty", /* 23 SIGSTOP */
2519 "stop signal from tty", /* 24 SIGSTP */
2520 "continue a stopped process", /* 25 SIGCONT */
2521 "attempted background tty read", /* 26 SIGTTIN */
2522 "attempted background tty write", /* 27 SIGTTOU */
2523 "undefined", /* 28 */
2524 "undefined", /* 29 */
2525 "undefined", /* 30 */
2526 "undefined", /* 31 */
2527 "undefined", /* 32 */
2528 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2529 "I/O is possible", /* 34 SIGIO */
2530 "exceeded cpu time limit", /* 35 SIGXCPU */
2531 "exceeded file size limit", /* 36 SIGXFSZ */
2532 "virtual time alarm", /* 37 SIGVTALRM */
2533 "profiling time alarm", /* 38 SIGPROF */
2534 "undefined", /* 39 */
2535 "file record locks revoked", /* 40 SIGLOST */
2536 "undefined", /* 41 */
2537 "undefined", /* 42 */
2538 "undefined", /* 43 */
2539 "undefined", /* 44 */
2540 "undefined", /* 45 */
2541 "undefined", /* 46 */
2542 "undefined", /* 47 */
2543 "undefined", /* 48 */
2544 "undefined", /* 49 */
2545 "undefined", /* 50 */
2546 "undefined", /* 51 */
2547 "undefined", /* 52 */
2548 "undefined", /* 53 */
2549 "undefined", /* 54 */
2550 "undefined", /* 55 */
2551 "undefined", /* 56 */
2552 "undefined", /* 57 */
2553 "undefined", /* 58 */
2554 "undefined", /* 59 */
2555 "undefined", /* 60 */
2556 "undefined", /* 61 */
2557 "undefined", /* 62 */
2558 "undefined", /* 63 */
2559 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2565 /* Directory routines for systems that don't have them. */
2567 #ifdef SYSV_SYSTEM_DIR
2574 register DIR *dirp
; /* stream from opendir */
2576 sys_close (dirp
->dd_fd
);
2577 free ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2578 free ((char *) dirp
);
2580 #endif /* not AIX */
2581 #endif /* SYSV_SYSTEM_DIR */
2583 #ifdef NONSYSTEM_DIR_LIBRARY
2587 char *filename
; /* name of directory */
2589 register DIR *dirp
; /* -> malloc'ed storage */
2590 register int fd
; /* file descriptor for read */
2591 struct stat sbuf
; /* result of fstat */
2593 fd
= sys_open (filename
, 0);
2597 if (fstat (fd
, &sbuf
) < 0
2598 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2599 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2602 return 0; /* bad luck today */
2606 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2613 register DIR *dirp
; /* stream from opendir */
2615 sys_close (dirp
->dd_fd
);
2616 free ((char *) dirp
);
2624 ino_t od_ino
; /* inode */
2625 char od_name
[DIRSIZ
]; /* filename */
2627 #endif /* not VMS */
2629 struct direct dir_static
; /* simulated directory contents */
2634 register DIR *dirp
; /* stream from opendir */
2637 register struct olddir
*dp
; /* -> directory data */
2639 register struct dir$_name
*dp
; /* -> directory data */
2640 register struct dir$_version
*dv
; /* -> version data */
2645 if (dirp
->dd_loc
>= dirp
->dd_size
)
2646 dirp
->dd_loc
= dirp
->dd_size
= 0;
2648 if (dirp
->dd_size
== 0 /* refill buffer */
2649 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2653 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
2654 dirp
->dd_loc
+= sizeof (struct olddir
);
2656 if (dp
->od_ino
!= 0) /* not deleted entry */
2658 dir_static
.d_ino
= dp
->od_ino
;
2659 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
2660 dir_static
.d_name
[DIRSIZ
] = '\0';
2661 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2662 dir_static
.d_reclen
= sizeof (struct direct
)
2664 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2665 return &dir_static
; /* -> simulated structure */
2668 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2669 if (dirp
->dd_loc
== 0)
2670 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
2671 : dp
->dir$b_namecount
;
2672 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
2673 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2674 dir_static
.d_namlen
= dp
->dir$b_namecount
;
2675 dir_static
.d_reclen
= sizeof (struct direct
)
2677 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2678 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2679 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
2680 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
2687 /* readdirver is just like readdir except it returns all versions of a file
2688 as separate entries. */
2693 register DIR *dirp
; /* stream from opendir */
2695 register struct dir$_name
*dp
; /* -> directory data */
2696 register struct dir$_version
*dv
; /* -> version data */
2698 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
2699 dirp
->dd_loc
= dirp
->dd_size
= 0;
2701 if (dirp
->dd_size
== 0 /* refill buffer */
2702 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2705 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2706 if (dirp
->dd_loc
== 0)
2707 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
2708 : dp
->dir$b_namecount
;
2709 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
2710 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2711 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
2712 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2713 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2714 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
2715 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2716 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
2722 #endif /* NONSYSTEM_DIR_LIBRARY */
2724 /* Functions for VMS */
2726 #include "vms-pwd.h"
2731 /* Return as a string the VMS error string pertaining to STATUS.
2732 Reuses the same static buffer each time it is called. */
2736 int status
; /* VMS status code */
2740 static char buf
[257];
2742 bufadr
[0] = sizeof buf
- 1;
2743 bufadr
[1] = (int) buf
;
2744 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
2745 return "untranslatable VMS error status";
2753 /* The following is necessary because 'access' emulation by VMS C (2.0) does
2754 * not work correctly. (It also doesn't work well in version 2.3.)
2759 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
2760 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
2764 unsigned short s_buflen
;
2765 unsigned short s_code
;
2767 unsigned short *s_retlenadr
;
2771 #define buflen s.s_buflen
2772 #define code s.s_code
2773 #define bufadr s.s_bufadr
2774 #define retlenadr s.s_retlenadr
2776 #define R_OK 4 /* test for read permission */
2777 #define W_OK 2 /* test for write permission */
2778 #define X_OK 1 /* test for execute (search) permission */
2779 #define F_OK 0 /* test for presence of file */
2782 sys_access (path
, mode
)
2786 static char *user
= NULL
;
2789 /* translate possible directory spec into .DIR file name, so brain-dead
2790 * access can treat the directory like a file. */
2791 if (directory_file_name (path
, dir_fn
))
2795 return access (path
, mode
);
2796 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
2802 unsigned short int dummy
;
2804 static int constant
= ACL$C_FILE
;
2805 DESCRIPTOR (path_desc
, path
);
2806 DESCRIPTOR (user_desc
, user
);
2810 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
2813 acces
|= CHP$M_READ
;
2815 acces
|= CHP$M_WRITE
;
2816 itemlst
[0].buflen
= sizeof (int);
2817 itemlst
[0].code
= CHP$_FLAGS
;
2818 itemlst
[0].bufadr
= (char *) &flags
;
2819 itemlst
[0].retlenadr
= &dummy
;
2820 itemlst
[1].buflen
= sizeof (int);
2821 itemlst
[1].code
= CHP$_ACCESS
;
2822 itemlst
[1].bufadr
= (char *) &acces
;
2823 itemlst
[1].retlenadr
= &dummy
;
2824 itemlst
[2].end
= CHP$_END
;
2825 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
2826 return stat
== SS$_NORMAL
? 0 : -1;
2830 #else /* not VMS4_4 */
2833 #define ACE$M_WRITE 2
2834 #define ACE$C_KEYID 1
2836 static unsigned short memid
, grpid
;
2837 static unsigned int uic
;
2839 /* Called from init_sys_modes, so it happens not very often
2840 but at least each time Emacs is loaded. */
2841 sys_access_reinit ()
2847 sys_access (filename
, type
)
2853 int status
, size
, i
, typecode
, acl_controlled
;
2854 unsigned int *aclptr
, *aclend
, aclbuf
[60];
2855 union prvdef prvmask
;
2857 /* Get UIC and GRP values for protection checking. */
2860 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
2863 memid
= uic
& 0xFFFF;
2867 if (type
!= 2) /* not checking write access */
2868 return access (filename
, type
);
2870 /* Check write protection. */
2872 #define CHECKPRIV(bit) (prvmask.bit)
2873 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
2875 /* Find privilege bits */
2876 status
= sys$
setprv (0, 0, 0, prvmask
);
2878 error ("Unable to find privileges: %s", vmserrstr (status
));
2879 if (CHECKPRIV (PRV$V_BYPASS
))
2880 return 0; /* BYPASS enabled */
2882 fab
.fab$b_fac
= FAB$M_GET
;
2883 fab
.fab$l_fna
= filename
;
2884 fab
.fab$b_fns
= strlen (filename
);
2885 fab
.fab$l_xab
= &xab
;
2886 xab
= cc$rms_xabpro
;
2887 xab
.xab$l_aclbuf
= aclbuf
;
2888 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
2889 status
= sys$
open (&fab
, 0, 0);
2892 sys$
close (&fab
, 0, 0);
2893 /* Check system access */
2894 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
2896 /* Check ACL entries, if any */
2898 if (xab
.xab$w_acllen
> 0)
2901 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
2902 while (*aclptr
&& aclptr
< aclend
)
2904 size
= (*aclptr
& 0xff) / 4;
2905 typecode
= (*aclptr
>> 8) & 0xff;
2906 if (typecode
== ACE$C_KEYID
)
2907 for (i
= size
- 1; i
> 1; i
--)
2908 if (aclptr
[i
] == uic
)
2911 if (aclptr
[1] & ACE$M_WRITE
)
2912 return 0; /* Write access through ACL */
2914 aclptr
= &aclptr
[size
];
2916 if (acl_controlled
) /* ACL specified, prohibits write access */
2919 /* No ACL entries specified, check normal protection */
2920 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
2922 if (WRITEABLE (XAB$V_GRP
) &&
2923 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
2924 return 0; /* Group writeable */
2925 if (WRITEABLE (XAB$V_OWN
) &&
2926 (xab
.xab$l_uic
& 0xFFFF) == memid
)
2927 return 0; /* Owner writeable */
2929 return -1; /* Not writeable */
2931 #endif /* not VMS4_4 */
2934 static char vtbuf
[NAM$C_MAXRSS
+1];
2936 /* translate a vms file spec to a unix path */
2938 sys_translate_vms (vfile
)
2949 /* leading device or logical name is a root directory */
2950 if (p
= strchr (vfile
, ':'))
2959 if (*p
== '[' || *p
== '<')
2961 while (*++vfile
!= *p
+ 2)
2965 if (vfile
[-1] == *p
)
2988 static char utbuf
[NAM$C_MAXRSS
+1];
2990 /* translate a unix path to a VMS file spec */
2992 sys_translate_unix (ufile
)
3015 if (index (&ufile
[1], '/'))
3022 if (index (&ufile
[1], '/'))
3029 if (strncmp (ufile
, "./", 2) == 0)
3036 ufile
++; /* skip the dot */
3037 if (index (&ufile
[1], '/'))
3042 else if (strncmp (ufile
, "../", 3) == 0)
3050 ufile
+= 2; /* skip the dots */
3051 if (index (&ufile
[1], '/'))
3076 strcpy (pathname
, egetenv ("PATH"));
3081 if ('a' <= *ptr
&& *ptr
<= 'z')
3090 long item_code
= JPI$_OWNER
;
3091 unsigned long parent_id
;
3094 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3097 vaxc$errno
= status
;
3107 return (getgid () << 16) | getuid ();
3111 sys_read (fildes
, buf
, nbyte
)
3116 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3121 sys_write (fildes
, buf
, nbyte
)
3126 register int nwrote
, rtnval
= 0;
3128 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3134 return rtnval
? rtnval
: -1;
3135 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3136 return rtnval
? rtnval
: -1;
3137 return (rtnval
+ nwrote
);
3142 * VAX/VMS VAX C RTL really loses. It insists that records
3143 * end with a newline (carriage return) character, and if they
3144 * don't it adds one (nice of it isn't it!)
3146 * Thus we do this stupidity below.
3150 sys_write (fildes
, buf
, nbytes
)
3153 unsigned int nbytes
;
3160 fstat (fildes
, &st
);
3166 /* Handle fixed-length files with carriage control. */
3167 if (st
.st_fab_rfm
== FAB$C_FIX
3168 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3170 len
= st
.st_fab_mrs
;
3171 retval
= write (fildes
, p
, min (len
, nbytes
));
3174 retval
++; /* This skips the implied carriage control */
3178 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3179 while (*e
!= '\n' && e
> p
) e
--;
3180 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3181 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3183 retval
= write (fildes
, p
, len
);
3194 /* Create file NEW copying its attributes from file OLD. If
3195 OLD is 0 or does not exist, create based on the value of
3198 /* Protection value the file should ultimately have.
3199 Set by create_copy_attrs, and use by rename_sansversions. */
3200 static unsigned short int fab_final_pro
;
3203 creat_copy_attrs (old
, new)
3206 struct FAB fab
= cc$rms_fab
;
3207 struct XABPRO xabpro
;
3208 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3209 extern int vms_stmlf_recfm
;
3213 fab
.fab$b_fac
= FAB$M_GET
;
3214 fab
.fab$l_fna
= old
;
3215 fab
.fab$b_fns
= strlen (old
);
3216 fab
.fab$l_xab
= (char *) &xabpro
;
3217 xabpro
= cc$rms_xabpro
;
3218 xabpro
.xab$l_aclbuf
= aclbuf
;
3219 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3220 /* Call $OPEN to fill in the fab & xabpro fields. */
3221 if (sys$
open (&fab
, 0, 0) & 1)
3223 sys$
close (&fab
, 0, 0);
3224 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3225 if (xabpro
.xab$w_acllen
> 0)
3227 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3228 /* If the acl buffer was too short, redo open with longer one.
3229 Wouldn't need to do this if there were some system imposed
3230 limit on the size of an ACL, but I can't find any such. */
3232 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3233 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3234 if (sys$
open (&fab
, 0, 0) & 1)
3235 sys$
close (&fab
, 0, 0);
3241 xabpro
.xab$l_aclbuf
= 0;
3246 fab
.fab$l_fna
= new;
3247 fab
.fab$b_fns
= strlen (new);
3251 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3252 fab
.fab$b_rat
= FAB$M_CR
;
3255 /* Set the file protections such that we will be able to manipulate
3256 this file. Once we are done writing and renaming it, we will set
3257 the protections back. */
3259 fab_final_pro
= xabpro
.xab$w_pro
;
3261 sys$
setdfprot (0, &fab_final_pro
);
3262 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3264 /* Create the new file with either default attrs or attrs copied
3266 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3268 sys$
close (&fab
, 0, 0);
3269 /* As this is a "replacement" for creat, return a file descriptor
3270 opened for writing. */
3271 return open (new, O_WRONLY
);
3276 #include <varargs.h>
3279 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3283 sys_creat (va_alist
)
3286 va_list list_incrementor
;
3289 int rfd
; /* related file descriptor */
3290 int fd
; /* Our new file descriptor */
3297 extern int vms_stmlf_recfm
;
3300 va_start (list_incrementor
);
3301 name
= va_arg (list_incrementor
, char *);
3302 mode
= va_arg (list_incrementor
, int);
3304 rfd
= va_arg (list_incrementor
, int);
3305 va_end (list_incrementor
);
3308 /* Use information from the related file descriptor to set record
3309 format of the newly created file. */
3310 fstat (rfd
, &st_buf
);
3311 switch (st_buf
.st_fab_rfm
)
3314 strcpy (rfm
, "rfm = fix");
3315 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3316 strcpy (rat
, "rat = ");
3317 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3319 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3320 strcat (rat
, "ftn");
3321 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3322 strcat (rat
, "prn");
3323 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3324 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3325 strcat (rat
, ", blk");
3327 strcat (rat
, "blk");
3328 return creat (name
, 0, rfm
, rat
, mrs
);
3331 strcpy (rfm
, "rfm = vfc");
3332 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3333 strcpy (rat
, "rat = ");
3334 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3336 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3337 strcat (rat
, "ftn");
3338 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3339 strcat (rat
, "prn");
3340 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3341 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3342 strcat (rat
, ", blk");
3344 strcat (rat
, "blk");
3345 return creat (name
, 0, rfm
, rat
, fsz
);
3348 strcpy (rfm
, "rfm = stm");
3352 strcpy (rfm
, "rfm = stmcr");
3356 strcpy (rfm
, "rfm = stmlf");
3360 strcpy (rfm
, "rfm = udf");
3364 strcpy (rfm
, "rfm = var");
3367 strcpy (rat
, "rat = ");
3368 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3370 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3371 strcat (rat
, "ftn");
3372 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3373 strcat (rat
, "prn");
3374 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3375 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3376 strcat (rat
, ", blk");
3378 strcat (rat
, "blk");
3382 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3383 strcpy (rat
, "rat=cr");
3385 /* Until the VAX C RTL fixes the many bugs with modes, always use
3386 mode 0 to get the user's default protection. */
3387 fd
= creat (name
, 0, rfm
, rat
);
3388 if (fd
< 0 && errno
== EEXIST
)
3390 if (unlink (name
) < 0)
3391 report_file_error ("delete", build_string (name
));
3392 fd
= creat (name
, 0, rfm
, rat
);
3398 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3399 sys_fwrite (ptr
, size
, num
, fp
)
3400 register char * ptr
;
3403 register int tot
= num
* size
;
3410 * The VMS C library routine creat actually creates a new version of an
3411 * existing file rather than truncating the old version. There are times
3412 * when this is not the desired behavior, for instance, when writing an
3413 * auto save file (you only want one version), or when you don't have
3414 * write permission in the directory containing the file (but the file
3415 * itself is writable). Hence this routine, which is equivalent to
3416 * "close (creat (fn, 0));" on Unix if fn already exists.
3422 struct FAB xfab
= cc$rms_fab
;
3423 struct RAB xrab
= cc$rms_rab
;
3426 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3427 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3428 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3429 xfab
.fab$l_fna
= fn
;
3430 xfab
.fab$b_fns
= strlen (fn
);
3431 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3433 xrab
.rab$l_fab
= &xfab
;
3435 /* This gibberish opens the file, positions to the first record, and
3436 deletes all records from there until the end of file. */
3437 if ((sys$
open (&xfab
) & 01) == 01)
3439 if ((sys$
connect (&xrab
) & 01) == 01 &&
3440 (sys$
find (&xrab
) & 01) == 01 &&
3441 (sys$
truncate (&xrab
) & 01) == 01)
3452 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3453 SYSPRV or a readable SYSUAF.DAT. */
3459 * Routine to read the VMS User Authorization File and return
3460 * a specific user's record.
3463 static struct UAF retuaf
;
3466 get_uaf_name (uname
)
3473 uaf_fab
= cc$rms_fab
;
3474 uaf_rab
= cc$rms_rab
;
3475 /* initialize fab fields */
3476 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3477 uaf_fab
.fab$b_fns
= 21;
3478 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3479 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3480 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3481 /* initialize rab fields */
3482 uaf_rab
.rab$l_fab
= &uaf_fab
;
3483 /* open the User Authorization File */
3484 status
= sys$
open (&uaf_fab
);
3488 vaxc$errno
= status
;
3491 status
= sys$
connect (&uaf_rab
);
3495 vaxc$errno
= status
;
3498 /* read the requested record - index is in uname */
3499 uaf_rab
.rab$l_kbf
= uname
;
3500 uaf_rab
.rab$b_ksz
= strlen (uname
);
3501 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3502 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3503 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3504 status
= sys$
get (&uaf_rab
);
3508 vaxc$errno
= status
;
3511 /* close the User Authorization File */
3512 status
= sys$
disconnect (&uaf_rab
);
3516 vaxc$errno
= status
;
3519 status
= sys$
close (&uaf_fab
);
3523 vaxc$errno
= status
;
3537 uaf_fab
= cc$rms_fab
;
3538 uaf_rab
= cc$rms_rab
;
3539 /* initialize fab fields */
3540 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3541 uaf_fab
.fab$b_fns
= 21;
3542 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3543 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3544 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3545 /* initialize rab fields */
3546 uaf_rab
.rab$l_fab
= &uaf_fab
;
3547 /* open the User Authorization File */
3548 status
= sys$
open (&uaf_fab
);
3552 vaxc$errno
= status
;
3555 status
= sys$
connect (&uaf_rab
);
3559 vaxc$errno
= status
;
3562 /* read the requested record - index is in uic */
3563 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3564 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3565 uaf_rab
.rab$b_ksz
= sizeof uic
;
3566 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3567 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3568 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3569 status
= sys$
get (&uaf_rab
);
3573 vaxc$errno
= status
;
3576 /* close the User Authorization File */
3577 status
= sys$
disconnect (&uaf_rab
);
3581 vaxc$errno
= status
;
3584 status
= sys$
close (&uaf_fab
);
3588 vaxc$errno
= status
;
3594 static struct passwd retpw
;
3602 /* copy these out first because if the username is 32 chars, the next
3603 section will overwrite the first byte of the UIC */
3604 retpw
.pw_uid
= up
->uaf$w_mem
;
3605 retpw
.pw_gid
= up
->uaf$w_grp
;
3607 /* I suppose this is not the best sytle, to possibly overwrite one
3608 byte beyond the end of the field, but what the heck... */
3609 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3610 while (ptr
[-1] == ' ')
3613 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3615 /* the rest of these are counted ascii strings */
3616 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3617 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3618 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3619 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3620 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3621 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3622 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3623 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3627 #else /* not READ_SYSUAF */
3628 static struct passwd retpw
;
3629 #endif /* not READ_SYSUAF */
3640 unsigned char * full
;
3641 #endif /* READ_SYSUAF */
3646 if ('a' <= *ptr
&& *ptr
<= 'z')
3651 if (!(up
= get_uaf_name (name
)))
3653 return cnv_uaf_pw (up
);
3655 if (strcmp (name
, getenv ("USER")) == 0)
3657 retpw
.pw_uid
= getuid ();
3658 retpw
.pw_gid
= getgid ();
3659 strcpy (retpw
.pw_name
, name
);
3660 if (full
= egetenv ("FULLNAME"))
3661 strcpy (retpw
.pw_gecos
, full
);
3663 *retpw
.pw_gecos
= '\0';
3664 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
3665 *retpw
.pw_shell
= '\0';
3670 #endif /* not READ_SYSUAF */
3680 if (!(up
= get_uaf_uic (uid
)))
3682 return cnv_uaf_pw (up
);
3684 if (uid
== sys_getuid ())
3685 return getpwnam (egetenv ("USER"));
3688 #endif /* not READ_SYSUAF */
3691 /* return total address space available to the current process. This is
3692 the sum of the current p0 size, p1 size and free page table entries
3697 unsigned long free_pages
;
3698 unsigned long frep0va
;
3699 unsigned long frep1va
;
3702 item_code
= JPI$_FREPTECNT
;
3703 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
3706 vaxc$errno
= status
;
3711 item_code
= JPI$_FREP0VA
;
3712 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
3715 vaxc$errno
= status
;
3718 item_code
= JPI$_FREP1VA
;
3719 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
3722 vaxc$errno
= status
;
3726 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
3729 define_logical_name (varname
, string
)
3733 struct dsc$descriptor_s strdsc
=
3734 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
3735 struct dsc$descriptor_s envdsc
=
3736 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3737 struct dsc$descriptor_s lnmdsc
=
3738 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3740 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
3743 delete_logical_name (varname
)
3746 struct dsc$descriptor_s envdsc
=
3747 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3748 struct dsc$descriptor_s lnmdsc
=
3749 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3751 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
3765 error ("execvp system call not implemented");
3773 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
3774 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
3775 char from_esn
[NAM$C_MAXRSS
];
3776 char to_esn
[NAM$C_MAXRSS
];
3778 from_fab
.fab$l_fna
= from
;
3779 from_fab
.fab$b_fns
= strlen (from
);
3780 from_fab
.fab$l_nam
= &from_nam
;
3781 from_fab
.fab$l_fop
= FAB$M_NAM
;
3783 from_nam
.nam$l_esa
= from_esn
;
3784 from_nam
.nam$b_ess
= sizeof from_esn
;
3786 to_fab
.fab$l_fna
= to
;
3787 to_fab
.fab$b_fns
= strlen (to
);
3788 to_fab
.fab$l_nam
= &to_nam
;
3789 to_fab
.fab$l_fop
= FAB$M_NAM
;
3791 to_nam
.nam$l_esa
= to_esn
;
3792 to_nam
.nam$b_ess
= sizeof to_esn
;
3794 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
3800 if (status
== RMS$_DEV
)
3804 vaxc$errno
= status
;
3809 /* This function renames a file like `rename', but it strips
3810 the version number from the "to" filename, such that the "to" file is
3811 will always be a new version. It also sets the file protection once it is
3812 finished. The protection that we will use is stored in fab_final_pro,
3813 and was set when we did a creat_copy_attrs to create the file that we
3816 We could use the chmod function, but Eunichs uses 3 bits per user category
3817 to describe the protection, and VMS uses 4 (write and delete are seperate
3818 bits). To maintain portability, the VMS implementation of `chmod' wires
3819 the W and D bits together. */
3822 static struct fibdef fib
; /* We need this initialized to zero */
3823 char vms_file_written
[NAM$C_MAXRSS
];
3826 rename_sans_version (from
,to
)
3833 struct FAB to_fab
= cc$rms_fab
;
3834 struct NAM to_nam
= cc$rms_nam
;
3835 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
3836 struct dsc$descriptor fib_attr
[2]
3837 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
3838 char to_esn
[NAM$C_MAXRSS
];
3840 $
DESCRIPTOR (disk
,to_esn
);
3842 to_fab
.fab$l_fna
= to
;
3843 to_fab
.fab$b_fns
= strlen (to
);
3844 to_fab
.fab$l_nam
= &to_nam
;
3845 to_fab
.fab$l_fop
= FAB$M_NAM
;
3847 to_nam
.nam$l_esa
= to_esn
;
3848 to_nam
.nam$b_ess
= sizeof to_esn
;
3850 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
3852 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
3853 *(to_nam
.nam$l_ver
) = '\0';
3855 stat
= rename (from
, to_esn
);
3859 strcpy (vms_file_written
, to_esn
);
3861 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
3862 to_fab
.fab$b_fns
= strlen (vms_file_written
);
3864 /* Now set the file protection to the correct value */
3865 sys$
open (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
3867 /* Copy these fields into the fib */
3868 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
3869 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
3870 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
3872 sys$
close (&to_fab
, 0, 0);
3874 stat
= sys$
assign (&disk
, &chan
, 0, 0); /* open a channel to the disk */
3877 stat
= sys$
qiow (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
3878 0, 0, 0, &fib_attr
, 0);
3881 stat
= sys$
dassgn (chan
);
3884 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
3894 unsigned short fid
[3];
3895 char esa
[NAM$C_MAXRSS
];
3898 fab
.fab$l_fop
= FAB$M_OFP
;
3899 fab
.fab$l_fna
= file
;
3900 fab
.fab$b_fns
= strlen (file
);
3901 fab
.fab$l_nam
= &nam
;
3904 nam
.nam$l_esa
= esa
;
3905 nam
.nam$b_ess
= NAM$C_MAXRSS
;
3907 status
= SYS$
PARSE (&fab
);
3908 if ((status
& 1) == 0)
3911 vaxc$errno
= status
;
3914 status
= SYS$
SEARCH (&fab
);
3915 if ((status
& 1) == 0)
3918 vaxc$errno
= status
;
3922 fid
[0] = nam
.nam$w_fid
[0];
3923 fid
[1] = nam
.nam$w_fid
[1];
3924 fid
[2] = nam
.nam$w_fid
[2];
3926 fab
.fab$l_fna
= new;
3927 fab
.fab$b_fns
= strlen (new);
3929 status
= SYS$
PARSE (&fab
);
3930 if ((status
& 1) == 0)
3933 vaxc$errno
= status
;
3937 nam
.nam$w_fid
[0] = fid
[0];
3938 nam
.nam$w_fid
[1] = fid
[1];
3939 nam
.nam$w_fid
[2] = fid
[2];
3941 nam
.nam$l_esa
= nam
.nam$l_name
;
3942 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
3944 status
= SYS$
ENTER (&fab
);
3945 if ((status
& 1) == 0)
3948 vaxc$errno
= status
;
3958 printf ("%s not yet implemented\r\n", badfunc
);
3966 /* Arrange to return a range centered on zero. */
3967 return rand () - (1 << 30);
3978 /* Called from init_sys_modes. */
3983 /* If we're not on an HFT we shouldn't do any of this. We determine
3984 if we are on an HFT by trying to get an HFT error code. If this
3985 call fails, we're not on an HFT. */
3987 if (ioctl (0, HFQERROR
, &junk
) < 0)
3989 #else /* not IBMR2AIX */
3990 if (ioctl (0, HFQEIO
, 0) < 0)
3992 #endif /* not IBMR2AIX */
3994 /* On AIX the default hft keyboard mapping uses backspace rather than delete
3995 as the rubout key's ASCII code. Here this is changed. The bug is that
3996 there's no way to determine the old mapping, so in reset_sys_modes
3997 we need to assume that the normal map had been present. Of course, this
3998 code also doesn't help if on a terminal emulator which doesn't understand
4002 struct hfkeymap keymap
;
4004 buf
.hf_bufp
= (char *)&keymap
;
4005 buf
.hf_buflen
= sizeof (keymap
);
4006 keymap
.hf_nkeys
= 2;
4007 keymap
.hfkey
[0].hf_kpos
= 15;
4008 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4010 keymap
.hfkey
[0].hf_keyidh
= '<';
4011 #else /* not IBMR2AIX */
4012 keymap
.hfkey
[0].hf_page
= '<';
4013 #endif /* not IBMR2AIX */
4014 keymap
.hfkey
[0].hf_char
= 127;
4015 keymap
.hfkey
[1].hf_kpos
= 15;
4016 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4018 keymap
.hfkey
[1].hf_keyidh
= '<';
4019 #else /* not IBMR2AIX */
4020 keymap
.hfkey
[1].hf_page
= '<';
4021 #endif /* not IBMR2AIX */
4022 keymap
.hfkey
[1].hf_char
= 127;
4023 hftctl (0, HFSKBD
, &buf
);
4025 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4027 line_ins_del_ok
= char_ins_del_ok
= 0;
4030 /* Reset the rubout key to backspace. */
4035 struct hfkeymap keymap
;
4039 if (ioctl (0, HFQERROR
, &junk
) < 0)
4041 #else /* not IBMR2AIX */
4042 if (ioctl (0, HFQEIO
, 0) < 0)
4044 #endif /* not IBMR2AIX */
4046 buf
.hf_bufp
= (char *)&keymap
;
4047 buf
.hf_buflen
= sizeof (keymap
);
4048 keymap
.hf_nkeys
= 2;
4049 keymap
.hfkey
[0].hf_kpos
= 15;
4050 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4052 keymap
.hfkey
[0].hf_keyidh
= '<';
4053 #else /* not IBMR2AIX */
4054 keymap
.hfkey
[0].hf_page
= '<';
4055 #endif /* not IBMR2AIX */
4056 keymap
.hfkey
[0].hf_char
= 8;
4057 keymap
.hfkey
[1].hf_kpos
= 15;
4058 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4060 keymap
.hfkey
[1].hf_keyidh
= '<';
4061 #else /* not IBMR2AIX */
4062 keymap
.hfkey
[1].hf_page
= '<';
4063 #endif /* not IBMR2AIX */
4064 keymap
.hfkey
[1].hf_char
= 8;
4065 hftctl (0, HFSKBD
, &buf
);