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>
114 /* Get files for keyboard remapping */
117 #include <sys/devinfo.h>
120 /* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs. */
126 #ifdef BROKEN_TIOCGWINSZ
131 #include <sys/utsname.h>
133 #ifndef MEMORY_IN_STRING_H
138 #include <sys/sioctl.h>
141 #include <sys/stream.h>
142 #include <sys/ptem.h>
144 #endif /* TIOCGWINSZ */
148 #include <sys/bsdtty.h>
151 #if defined (HPUX) && defined (HAVE_PTYS)
152 #include <sys/ptyio.h>
165 /* saka@pfu.fujitsu.co.JP writes:
166 FASYNC defined in this file. But, FASYNC don't working.
167 so no problem, because unrequest_sigio only need. */
169 #include <sys/file.h>
172 extern int quit_char
;
176 #include "termhooks.h"
177 #include "termchar.h"
178 #include "termopts.h"
179 #include "dispextern.h"
182 #ifdef NONSYSTEM_DIR_LIBRARY
184 #endif /* NONSYSTEM_DIR_LIBRARY */
186 #include "syssignal.h"
189 static int baud_convert
[] =
194 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
195 1800, 2400, 4800, 9600, 19200, 38400
201 /* The file descriptor for Emacs's input terminal.
202 Under Unix, this is always left zero;
203 under VMS, we place the input channel number here.
204 This allows us to write more code that works for both VMS and Unix. */
216 int kbd_input_ast ();
226 static $
DESCRIPTOR (input_dsc
, "TT");
227 static int terminator_mask
[2] = { 0, 0 };
229 static struct sensemode
{
231 unsigned char xmit_baud
;
232 unsigned char rcv_baud
;
233 unsigned char crfill
;
234 unsigned char lffill
;
235 unsigned char parity
;
236 unsigned char unused
;
240 unsigned long tt_char
: 24, scr_len
: 8;
241 unsigned long tt2_char
;
247 struct emacs_tty buf
;
252 /* Discarding input is not safe when the input could contain
253 replies from the X server. So don't do it. */
254 if (read_socket_hook
)
259 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
260 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
266 ioctl (0, TIOCFLUSH
, &zero
);
268 #else /* not Apollo */
269 EMACS_GET_TTY (input_fd
, &buf
);
270 EMACS_SET_TTY (input_fd
, &buf
, 0);
271 #endif /* not Apollo */
280 /* Should perhaps error if in batch mode */
282 ioctl (0, TIOCSTI
, &c
);
283 #else /* no TIOCSTI */
284 error ("Cannot stuff terminal input characters in this version of Unix.");
285 #endif /* no TIOCSTI */
299 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
300 &sg
.class, 12, 0, 0, 0, 0 );
301 ospeed
= sg
.xmit_baud
;
306 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
308 ospeed
= sg
.c_cflag
& CBAUD
;
309 #else /* neither VMS nor TERMIO */
313 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
315 ospeed
= sg
.c_cflag
& CBAUD
;
316 #else /* neither VMS nor TERMIO nor TERMIOS */
319 sg
.sg_ospeed
= B9600
;
320 ioctl (0, TIOCGETP
, &sg
);
321 ospeed
= sg
.sg_ospeed
;
322 #endif /* not HAVE_TERMIOS */
323 #endif /* not HAVE_TERMIO */
327 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
328 ? baud_convert
[ospeed
] : 9600);
334 set_exclusive_use (fd
)
338 ioctl (fd
, FIOCLEX
, 0);
340 /* Ok to do nothing if this feature does not exist */
345 wait_without_blocking ()
348 wait3 (0, WNOHANG
| WUNTRACED
, 0);
350 croak ("wait_without_blocking");
352 synch_process_alive
= 0;
355 #endif /* not subprocesses */
357 int wait_debugging
; /* Set nonzero to make following function work under dbx
358 (at least for bsd). */
361 wait_for_termination_signal ()
364 /* Wait for subprocess with process id `pid' to terminate and
365 make sure it will get eliminated (not remain forever as a zombie) */
367 wait_for_termination (pid
)
376 status
= sys$
forcex (&pid
, 0, 0);
380 /* Exit if the process has terminated. */
381 if (!synch_process_alive
)
383 /* Otherwise wait 1 second or until a signal comes in. */
384 signal (SIGALRM
, wait_for_termination_signal
);
388 signal (SIGALRM
, SIG_IGN
);
390 #else /* not subprocesses */
392 if (kill (pid
, 0) < 0)
398 if (status
== pid
|| status
== -1)
401 #endif /* not subprocesses */
408 * flush any pending output
409 * (may flush input as well; it does not matter the way we use it)
412 flush_pending_output (channel
)
416 /* If we try this, we get hit with SIGTTIN, because
417 the child's tty belongs to the child's pgrp. */
420 ioctl (channel
, TCFLSH
, 1);
424 /* 3rd arg should be ignored
425 but some 4.2 kernels actually want the address of an int
426 and nonzero means something different. */
427 ioctl (channel
, TIOCFLUSH
, &zero
);
434 /* Set up the terminal at the other end of a pseudo-terminal that
435 we will be controlling an inferior through.
436 It should not echo or do line-editing, since that is done
437 in Emacs. No padding needed for insertion into an Emacs buffer. */
439 child_setup_tty (out
)
444 EMACS_GET_TTY (out
, &s
);
447 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
448 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
449 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
450 /* No output delays */
451 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
452 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
453 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
455 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
458 /* Said to be unnecesary: */
459 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
460 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
463 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
464 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
465 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
466 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
469 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
473 /* AIX enhanced edit loses NULs, so disable it */
476 s
.main
.c_iflag
&= ~ASCEDIT
;
478 /* Also, PTY overloads NUL and BREAK.
479 don't ignore break, but don't signal either, so it looks like NUL. */
480 s
.main
.c_iflag
&= ~IGNBRK
;
481 s
.main
.c_iflag
&= ~BRKINT
;
482 /* QUIT and INTR work better as signals, so disable character forms */
483 s
.main
.c_cc
[VQUIT
] = 0377;
484 s
.main
.c_cc
[VINTR
] = 0377;
485 s
.main
.c_cc
[VEOL
] = 0377;
486 s
.main
.c_lflag
&= ~ISIG
;
487 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
490 #else /* not HAVE_TERMIO */
492 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
494 s
.main
.sg_erase
= 0377;
495 s
.main
.sg_kill
= 0377;
497 #endif /* not HAVE_TERMIO */
499 EMACS_SET_TTY (out
, &s
, 0);
508 ioctl (out
, FIOASYNC
, &zero
);
514 #endif /* subprocesses */
520 EMACS_SET_TTY_PGRP (input_fd
, pid
);
523 /* Record a signal code and the handler for it. */
527 SIGTYPE (*handler
) ();
530 /* Suspend the Emacs process; give terminal to its superior. */
535 unsigned long parent_id
;
537 parent_id
= getppid ();
538 if (parent_id
&& parent_id
!= 0xffffffff)
540 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
541 int status
= LIB$
ATTACH (&parent_id
) & 1;
542 signal (SIGINT
, oldsig
);
551 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
552 d_prompt
.a
= "Emacs: "; /* Just a reminder */
553 lib$
spawn (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
560 EMACS_KILLPG (getpgrp (0), SIGTSTP
);
562 #else /* No SIGTSTP */
563 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
564 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
565 kill (getpid (), SIGQUIT
);
567 #else /* No SIGTSTP or USG_JOBCTRL */
569 /* On a system where suspending is not implemented,
570 instead fork a subshell and let it talk directly to the terminal
573 struct save_signal saved_handlers
[5];
575 saved_handlers
[0].code
= SIGINT
;
576 saved_handlers
[1].code
= SIGQUIT
;
577 saved_handlers
[2].code
= SIGTERM
;
579 saved_handlers
[3].code
= SIGIO
;
580 saved_handlers
[4].code
= 0;
582 saved_handlers
[3].code
= 0;
586 error ("Can't spawn subshell");
591 sh
= (char *) egetenv ("SHELL");
594 /* Use our buffer's default directory for the subshell. */
600 /* mentioning current_buffer->buffer would mean including buffer.h,
601 which somehow wedges the hp compiler. So instead... */
603 dir
= intern ("default-directory");
605 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
607 dir
= Fsymbol_value (dir
);
608 if (XTYPE (dir
) != Lisp_String
)
611 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
612 len
= XSTRING (dir
)->size
;
613 bcopy (XSTRING (dir
)->data
, str
, len
);
614 if (str
[len
- 1] != '/') str
[len
++] = '/';
620 close_process_descs (); /* Close Emacs's pipes/ptys */
622 nice (-nice (0)); /* Give the new shell the default piority */
624 write (1, "Can't execute subshell", 22);
628 save_signal_handlers (saved_handlers
);
629 wait_for_termination (pid
);
630 restore_signal_handlers (saved_handlers
);
632 #endif /* no USG_JOBCTRL */
633 #endif /* no SIGTSTP */
637 save_signal_handlers (saved_handlers
)
638 struct save_signal
*saved_handlers
;
640 while (saved_handlers
->code
)
642 saved_handlers
->handler
= signal (saved_handlers
->code
, SIG_IGN
);
647 restore_signal_handlers (saved_handlers
)
648 struct save_signal
*saved_handlers
;
650 while (saved_handlers
->code
)
652 signal (saved_handlers
->code
, saved_handlers
->handler
);
664 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
674 #ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
679 sigunblock (sigmask (SIGWINCH
));
681 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
683 interrupts_deferred
= 0;
689 sigblock (sigmask (SIGWINCH
));
691 fcntl (0, F_SETFL
, old_fcntl_flags
);
692 interrupts_deferred
= 1;
695 #else /* no FASYNC */
696 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
701 ioctl (0, FIOASYNC
, &on
);
702 interrupts_deferred
= 0;
709 ioctl (0, FIOASYNC
, &off
);
710 interrupts_deferred
= 1;
713 #else /* not FASYNC, not STRIDE */
717 croak ("request_sigio");
722 croak ("unrequest_sigio");
729 /* The initial tty mode bits */
730 struct emacs_tty old_tty
;
732 int term_initted
; /* 1 if outer tty status has been recorded */
735 /* BSD 4.1 needs to keep track of the lmode bits in order to start
742 #endif /* F_SETOWN */
744 /* This may also be defined in stdio,
745 but if so, this does no harm,
746 and using the same name avoids wasting the other one's space. */
748 #if defined (USG) || defined (DGUX)
749 unsigned char _sobuf
[BUFSIZ
+8];
755 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
758 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
763 struct emacs_tty tty
;
767 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
768 extern int (*interrupt_signal
) ();
777 input_ef
= get_kbd_event_flag ();
778 /* LIB$GET_EF (&input_ef); */
779 SYS$
CLREF (input_ef
);
782 timer_ef
= get_timer_event_flag ();
783 /* LIB$GET_EF (&timer_ef); */
784 SYS$
CLREF (timer_ef
);
787 LIB$
GET_EF (&process_ef
);
788 SYS$
CLREF (process_ef
);
790 if (input_ef
/ 32 != process_ef
/ 32)
791 croak ("Input and process event flags in different clusters.");
792 if (input_ef
/ 32 != timer_ef
/ 32)
793 croak ("Input and process event flags in different clusters.");
794 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
795 ((unsigned) 1 << (process_ef
% 32));
796 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
797 ((unsigned) 1 << (timer_ef
% 32));
799 sys_access_reinit ();
803 EMACS_GET_TTY (input_fd
, &old_tty
);
805 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
810 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
811 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
813 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
815 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
816 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
817 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
820 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
822 tty
.main
.c_iflag
&= ~IXANY
;
826 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
827 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
829 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
833 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
834 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
837 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
838 /* Set up C-g for both SIGQUIT and SIGINT.
839 We don't know which we will get, but we handle both alike
840 so which one it really gives us does not matter. */
841 tty
.main
.c_cc
[VQUIT
] = quit_char
;
842 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
843 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
845 tty
.main
.c_cc
[VSWTCH
] = CDEL
; /* Turn off shell layering use
848 #if defined (mips) || defined (HAVE_TCATTR)
849 /* The following code looks like the right thing in general,
850 but it is said to cause a crash on USG V.4.
851 Let's play safe by turning it on only for the MIPS. */
853 tty
.main
.c_cc
[VSUSP
] = CDEL
; /* Turn off mips handling of C-z. */
856 tty
.main
.c_cc
[V_DSUSP
] = CDEL
; /* Turn off mips handling of C-y. */
858 #endif /* mips or HAVE_TCATTR */
861 /* AIX enhanced edit loses NULs, so disable it */
863 tty
.main
.c_iflag
&= ~ASCEDIT
;
865 tty
.main
.c_cc
[VSTRT
] = 255;
866 tty
.main
.c_cc
[VSTOP
] = 255;
867 tty
.main
.c_cc
[VSUSP
] = 255;
868 tty
.main
.c_cc
[VDSUSP
] = 255;
869 #endif /* IBMR2AIX */
870 /* Also, PTY overloads NUL and BREAK.
871 don't ignore break, but don't signal either, so it looks like NUL.
872 This really serves a purpose only if running in an XTERM window
873 or via TELNET or the like, but does no harm elsewhere. */
874 tty
.main
.c_iflag
&= ~IGNBRK
;
875 tty
.main
.c_iflag
&= ~BRKINT
;
877 #else /* if not HAVE_TERMIO */
879 tty
.main
.tt_char
|= TT$M_NOECHO
;
881 tty
.main
.tt_char
|= TT$M_EIGHTBIT
883 tty
.main
.tt_char
|= TT$M_TTSYNC
;
885 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
886 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
887 #else /* not VMS (BSD, that is) */
888 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
890 tty
.main
.sg_flags
|= ANYP
;
891 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
892 #endif /* not VMS (BSD, that is) */
893 #endif /* not HAVE_TERMIO */
895 /* If going to use CBREAK mode, we must request C-g to interrupt
896 and turn off start and stop chars, etc. If not going to use
897 CBREAK mode, do this anyway so as to turn off local flow
898 control for user coming over network on 4.2; in this case,
899 only t_stopc and t_startc really matter. */
902 /* Note: if not using CBREAK mode, it makes no difference how we
904 tty
.tchars
= new_tchars
;
905 tty
.tchars
.t_intrc
= quit_char
;
908 tty
.tchars
.t_startc
= '\021';
909 tty
.tchars
.t_stopc
= '\023';
912 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
918 #define LNOFLSH 0100000
921 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
927 #endif /* TIOCGETC */
928 #endif /* not HAVE_TERMIO */
931 tty
.ltchars
= new_ltchars
;
932 #endif /* TIOCGLTC */
934 EMACS_SET_TTY (input_fd
, &tty
, 0);
936 /* This code added to insure that, if flow-control is not to be used,
937 we have an unlocked screen at the start. */
940 if (!flow_control
) ioctl (0, TCXONC
, 1);
944 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
952 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
953 to be only LF. This is the way that is done. */
956 if (ioctl (1, HFTGETID
, &tty
) != -1)
957 write (1, "\033[20l", 5);
963 /* Appears to do nothing when in PASTHRU mode.
964 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
965 interrupt_signal, oob_chars, 0, 0, 0, 0);
972 #ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
975 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
976 fcntl (0, F_SETOWN
, getpid ());
979 #endif /* F_GETOWN */
987 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
991 /* This symbol is defined on recent USG systems.
992 Someone says without this call USG won't really buffer the file
993 even with a call to setbuf. */
994 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
996 setbuf (stdout
, _sobuf
);
998 set_terminal_modes ();
999 if (term_initted
&& no_redraw_on_reenter
)
1001 if (display_completed
)
1002 direct_output_forward_char (0);
1006 screen_garbaged
= 1;
1008 if (SCREENP (Vterminal_screen
))
1009 SCREEN_GARBAGED_P (XSCREEN (Vterminal_screen
)) = 1;
1016 /* Return nonzero if safe to use tabs in output.
1017 At the time this is called, init_sys_modes has not been done yet. */
1021 struct emacs_tty tty
;
1023 EMACS_GET_TTY (input_fd
, &tty
);
1024 return EMACS_TTY_TABS_OK (&tty
);
1027 /* Get terminal size from system.
1028 Store number of lines into *heightp and width into *widthp.
1029 If zero or a negative number is stored, the value is not valid. */
1031 get_screen_size (widthp
, heightp
)
1032 int *widthp
, *heightp
;
1038 struct winsize size
;
1040 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1041 *widthp
= *heightp
= 0;
1044 *widthp
= size
.ws_col
;
1045 *heightp
= size
.ws_row
;
1051 /* SunOS - style. */
1052 struct ttysize size
;
1054 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1055 *widthp
= *heightp
= 0;
1058 *widthp
= size
.ts_cols
;
1059 *heightp
= size
.ts_lines
;
1065 struct sensemode tty
;
1067 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1068 &tty
.class, 12, 0, 0, 0, 0);
1069 *widthp
= tty
.scr_wid
;
1070 *heightp
= tty
.scr_len
;
1072 #else /* system doesn't know size */
1077 #endif /* not VMS */
1078 #endif /* not SunOS-style */
1079 #endif /* not BSD-style */
1083 /* Prepare the terminal for exiting Emacs; move the cursor to the
1084 bottom of the screen, turn off interrupt-driven I/O, etc. */
1094 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1096 cursor_to (SCREEN_HEIGHT (selected_screen
) - 1, 0);
1097 clear_end_of_line (SCREEN_WIDTH (selected_screen
));
1098 /* clear_end_of_line may move the cursor */
1099 cursor_to (SCREEN_HEIGHT (selected_screen
) - 1, 0);
1102 /* HFT devices normally use ^J as a LF/CR. We forced it to
1103 do the LF only. Now, we need to reset it. */
1106 if (ioctl (1, HFTGETID
, &tty
) != -1)
1107 write (1, "\033[20h", 5);
1111 reset_terminal_modes ();
1115 /* Avoid possible loss of output when changing terminal modes. */
1116 fsync (fileno (stdout
));
1121 #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */
1122 if (interrupt_input
)
1125 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1127 #endif /* F_SETOWN */
1128 #endif /* F_SETFL */
1130 if (interrupt_input
)
1134 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1144 /* Set up the proper status flags for use of a pty. */
1149 /* I'm told that TOICREMOTE does not mean control chars
1150 "can't be sent" but rather that they don't have
1151 input-editing or signaling effects.
1152 That should be good, because we have other ways
1153 to do those things in Emacs.
1154 However, telnet mode seems not to work on 4.2.
1155 So TIOCREMOTE is turned off now. */
1157 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1158 will hang. In particular, the "timeout" feature (which
1159 causes a read to return if there is no data available)
1160 does this. Also it is known that telnet mode will hang
1161 in such a way that Emacs must be stopped (perhaps this
1162 is the same problem).
1164 If TIOCREMOTE is turned off, then there is a bug in
1165 hp-ux which sometimes loses data. Apparently the
1166 code which blocks the master process when the internal
1167 buffer fills up does not work. Other than this,
1168 though, everything else seems to work fine.
1170 Since the latter lossage is more benign, we may as well
1171 lose that way. -- cph */
1176 ioctl (fd
, FIONBIO
, &on
);
1181 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1182 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1183 /* cause EMACS not to die when it should, i.e., when its own controlling */
1184 /* tty goes away. I've complained to the AIX developers, and they may */
1185 /* change this behavior, but I'm not going to hold my breath. */
1186 signal (SIGHUP
, SIG_IGN
);
1189 #endif /* HAVE_PTYS */
1193 /* Assigning an input channel is done at the start of Emacs execution.
1194 This is called each time Emacs is resumed, also, but does nothing
1195 because input_chain is no longer zero. */
1203 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1209 /* Deassigning the input channel is done before exiting. */
1213 return SYS$
DASSGN (input_fd
);
1218 /* Request reading one character into the keyboard buffer.
1219 This is done as soon as the buffer becomes empty. */
1224 waiting_for_ast
= 0;
1226 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1227 &input_iosb
, kbd_input_ast
, 1,
1228 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1233 /* Ast routine that is called when keyboard input comes in
1234 in accord with the SYS$QIO above. */
1238 register int c
= -1;
1239 int old_errno
= errno
;
1240 extern int *input_available_clear_word
;
1242 if (waiting_for_ast
)
1243 SYS$
SETEF (input_ef
);
1244 waiting_for_ast
= 0;
1247 if (input_count
== 25)
1249 printf ("Ast # %d,", input_count
);
1250 printf (" iosb = %x, %x, %x, %x",
1251 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1254 if (input_iosb
.offset
)
1258 printf (", char = 0%o", c
);
1270 struct input_event e
;
1271 e
.kind
= ascii_keystroke
;
1272 XSET (buf
[i
].code
, Lisp_Int
, cbuf
[i
]);
1273 e
.screen
= selected_screen
;
1274 kbd_buffer_store_event (&e
);
1277 if (input_available_clear_word
)
1278 *input_available_clear_word
= 0;
1282 /* Wait until there is something in kbd_buffer. */
1284 wait_for_kbd_input ()
1286 extern int have_process_input
, process_exited
;
1288 /* If already something, avoid doing system calls. */
1289 if (detect_input_pending ())
1293 /* Clear a flag, and tell ast routine above to set it. */
1294 SYS$
CLREF (input_ef
);
1295 waiting_for_ast
= 1;
1296 /* Check for timing error: ast happened while we were doing that. */
1297 if (!detect_input_pending ())
1299 /* No timing error: wait for flag to be set. */
1300 set_waiting_for_input (0);
1301 SYS$
WFLOR (input_ef
, input_eflist
);
1302 clear_waiting_for_input (0);
1303 if (!detect_input_pending ())
1304 /* Check for subprocess input availability */
1306 int dsp
= have_process_input
|| process_exited
;
1308 SYS$
CLREF (process_ef
);
1309 if (have_process_input
)
1310 process_command_input ();
1315 update_mode_lines
++;
1316 redisplay_preserve_echo_area ();
1320 waiting_for_ast
= 0;
1323 /* Get rid of any pending QIO, when we are about to suspend
1324 or when we want to throw away pending input.
1325 We wait for a positive sign that the AST routine has run
1326 and therefore there is no I/O request queued when we return.
1327 SYS$SETAST is used to avoid a timing error. */
1332 printf ("At end_kbd_input.\n");
1336 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1338 SYS$
CANCEL (input_fd
);
1343 /* Clear a flag, and tell ast routine above to set it. */
1344 SYS$
CLREF (input_ef
);
1345 waiting_for_ast
= 1;
1347 SYS$
CANCEL (input_fd
);
1349 SYS$
WAITFR (input_ef
);
1350 waiting_for_ast
= 0;
1353 /* Wait for either input available or time interval expiry. */
1355 input_wait_timeout (timeval
)
1356 int timeval
; /* Time to wait, in seconds */
1359 static int zero
= 0;
1360 static int large
= -10000000;
1362 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1364 /* If already something, avoid doing system calls. */
1365 if (detect_input_pending ())
1369 /* Clear a flag, and tell ast routine above to set it. */
1370 SYS$
CLREF (input_ef
);
1371 waiting_for_ast
= 1;
1372 /* Check for timing error: ast happened while we were doing that. */
1373 if (!detect_input_pending ())
1375 /* No timing error: wait for flag to be set. */
1377 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1378 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1380 waiting_for_ast
= 0;
1383 /* The standard `sleep' routine works some other way
1384 and it stops working if you have ever quit out of it.
1385 This one continues to work. */
1391 static int zero
= 0;
1392 static int large
= -10000000;
1394 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1397 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1398 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1413 croak ("request sigio");
1418 croak ("unrequest sigio");
1423 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1428 #ifndef SYSTEM_MALLOC
1435 /* Some systems that cannot dump also cannot implement these. */
1438 * Return the address of the start of the text segment prior to
1439 * doing an unexec. After unexec the return value is undefined.
1440 * See crt0.c for further explanation and _start.
1444 #ifndef CANNOT_UNEXEC
1449 return ((char *) TEXT_START
);
1453 return ((char *) csrt
);
1454 #else /* not GOULD */
1455 extern int _start ();
1456 return ((char *) _start
);
1458 #endif /* TEXT_START */
1460 #endif /* not CANNOT_UNEXEC */
1463 * Return the address of the start of the data segment prior to
1464 * doing an unexec. After unexec the return value is undefined.
1465 * See crt0.c for further information and definition of data_start.
1467 * Apparently, on BSD systems this is etext at startup. On
1468 * USG systems (swapping) this is highly mmu dependent and
1469 * is also dependent on whether or not the program is running
1470 * with shared text. Generally there is a (possibly large)
1471 * gap between end of text and start of data with shared text.
1473 * On Uniplus+ systems with shared text, data starts at a
1474 * fixed address. Each port (from a given oem) is generally
1475 * different, and the specific value of the start of data can
1476 * be obtained via the UniPlus+ specific "uvar" system call,
1477 * however the method outlined in crt0.c seems to be more portable.
1479 * Probably what will have to happen when a USG unexec is available,
1480 * at least on UniPlus, is temacs will have to be made unshared so
1481 * that text and data are contiguous. Then once loadup is complete,
1482 * unexec will produce a shared executable where the data can be
1483 * at the normal shared text boundry and the startofdata variable
1484 * will be patched by unexec to the correct value.
1492 return ((char *) DATA_START
);
1494 extern int data_start
;
1495 return ((char *) &data_start
);
1498 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1501 /* Some systems that cannot dump also cannot implement these. */
1504 * Return the address of the end of the text segment prior to
1505 * doing an unexec. After unexec the return value is undefined.
1512 return ((char *) TEXT_END
);
1515 return ((char *) &etext
);
1520 * Return the address of the end of the data segment prior to
1521 * doing an unexec. After unexec the return value is undefined.
1528 return ((char *) DATA_END
);
1531 return ((char *) &edata
);
1535 #endif /* not CANNOT_DUMP */
1537 /* Get_system_name returns as its value
1538 a string for the Lisp function system-name to return. */
1545 /* Can't have this within the function since `static' is #defined to nothing */
1546 static struct utsname get_system_name_name
;
1553 uname (&get_system_name_name
);
1554 return (get_system_name_name
.nodename
);
1558 #else /* not USG, not 4.1 */
1559 static char system_name_saved
[32];
1562 if ((sp
= egetenv ("SYS$NODE")) == 0)
1568 if ((end
= index (sp
, ':')) != 0)
1571 strcpy (system_name_saved
, sp
);
1573 gethostname (system_name_saved
, sizeof (system_name_saved
));
1574 #endif /* not VMS */
1575 return system_name_saved
;
1576 #endif /* not USG, not 4.1 */
1577 #endif /* not USG */
1583 #ifdef HAVE_X_WINDOWS
1584 /* Cause explanatory error message at compile time,
1585 since the select emulation is not good enough for X. */
1586 int *x
= &x_windows_lose_if_no_select_system_call
;
1589 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1590 * Only checks read descriptors.
1592 /* How long to wait between checking fds in select */
1593 #define SELECT_PAUSE 1
1596 /* For longjmp'ing back to read_input_waiting. */
1598 jmp_buf read_alarm_throw
;
1600 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1601 The read_socket_hook function sets this to 1 while it is waiting. */
1603 int read_alarm_should_throw
;
1611 #else /* not BSD4_1 */
1612 signal (SIGALRM
, SIG_IGN
);
1613 #endif /* not BSD4_1 */
1614 if (read_alarm_should_throw
)
1615 longjmp (read_alarm_throw
, 1);
1618 /* Only rfds are checked. */
1620 select (nfds
, rfds
, wfds
, efds
, timeout
)
1622 int *rfds
, *wfds
, *efds
, *timeout
;
1624 int ravail
= 0, orfds
= 0, old_alarm
;
1625 int timeoutval
= timeout
? *timeout
: 100000;
1626 int *local_timeout
= &timeoutval
;
1627 extern int proc_buffered_char
[];
1628 #ifndef subprocesses
1629 int process_tick
= 0, update_tick
= 0;
1631 extern int process_tick
, update_tick
;
1633 SIGTYPE (*old_trap
) ();
1646 /* If we are looking only for the terminal, with no timeout,
1647 just read it and wait -- that's more efficient. */
1648 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1650 if (! detect_input_pending ())
1651 read_input_waiting ();
1656 /* Once a second, till the timer expires, check all the flagged read
1657 * descriptors to see if any input is available. If there is some then
1658 * set the corresponding bit in the return copy of rfds.
1662 register int to_check
, bit
, fd
;
1666 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1670 int avail
= 0, status
= 0;
1673 avail
= detect_input_pending (); /* Special keyboard handler */
1677 status
= ioctl (fd
, FIONREAD
, &avail
);
1678 #else /* no FIONREAD */
1679 /* Hoping it will return -1 if nothing available
1680 or 0 if all 0 chars requested are read. */
1681 if (proc_buffered_char
[fd
] >= 0)
1685 avail
= read (fd
, &buf
, 1);
1687 proc_buffered_char
[fd
] = buf
;
1689 #endif /* no FIONREAD */
1691 if (status
>= 0 && avail
> 0)
1699 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
1701 old_alarm
= alarm (0);
1702 old_trap
= (int (*)()) signal (SIGALRM
, select_alarm
);
1704 alarm (SELECT_PAUSE
);
1705 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1706 while (select_alarmed
== 0 && *local_timeout
!= 0
1707 && process_tick
== update_tick
)
1709 /* If we are interested in terminal input,
1710 wait by reading the terminal.
1711 That makes instant wakeup for terminal input at least. */
1714 read_input_waiting ();
1715 if (detect_input_pending ())
1721 (*local_timeout
) -= SELECT_PAUSE
;
1722 /* Reset the old alarm if there was one */
1724 signal (SIGALRM
, old_trap
);
1727 /* Reset or forge an interrupt for the original handler. */
1728 old_alarm
-= SELECT_PAUSE
;
1730 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
1734 if (*local_timeout
== 0) /* Stop on timer being cleared */
1740 /* Read keyboard input into the standard buffer,
1741 waiting for at least one character. */
1743 /* Make all keyboard buffers much bigger when using X windows. */
1744 #ifdef HAVE_X_WINDOWS
1745 #define BUFFER_SIZE_FACTOR 16
1747 #define BUFFER_SIZE_FACTOR 1
1750 read_input_waiting ()
1752 char buf
[256 * BUFFER_SIZE_FACTOR
];
1753 struct input_event e
;
1756 if (read_socket_hook
)
1758 read_alarm_should_throw
= 0;
1759 if (! setjmp (read_alarm_throw
))
1760 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
1765 nread
= read (fileno (stdin
), buf
, 1);
1767 /* Scan the chars for C-g and store them in kbd_buffer. */
1768 e
.kind
= ascii_keystroke
;
1769 e
.screen
= selected_screen
;
1770 for (i
= 0; i
< nread
; i
++)
1772 XSET (e
.code
, Lisp_Int
, buf
[i
]);
1773 kbd_buffer_store_event (&e
);
1774 /* Don't look at input that follows a C-g too closely.
1775 This reduces lossage due to autorepeat on C-g. */
1776 if (buf
[i
] == Ctl ('G'))
1781 #endif /* not HAVE_SELECT */
1782 #endif /* not VMS */
1792 * Partially emulate 4.2 open call.
1793 * open is defined as this in 4.1.
1795 * - added by Michael Bloom @ Citicorp/TTI
1800 sys_open (path
, oflag
, mode
)
1804 if (oflag
& O_CREAT
)
1805 return creat (path
, mode
);
1807 return open (path
, oflag
);
1814 lmode
= LINTRUP
| lmode
;
1815 ioctl (0, TIOCLSET
, &lmode
);
1822 lmode
= ~LINTRUP
& lmode
;
1823 ioctl (0, TIOCLSET
, &lmode
);
1830 interrupts_deferred
= 0;
1837 interrupts_deferred
= 1;
1840 /* still inside #ifdef BSD4_1 */
1843 int sigheld
; /* Mask of held signals */
1848 sigheld
|= sigbit (signum
);
1855 sigheld
|= sigbit (signum
);
1861 sigheld
&= ~sigbit (signum
);
1865 sigfree () /* Free all held signals */
1868 for (i
= 0; i
< NSIG
; i
++)
1869 if (sigheld
& sigbit (i
))
1876 return 1 << (i
- 1);
1878 #endif /* subprocesses */
1881 /* POSIX signals support - DJB */
1882 /* Anyone with POSIX signals should have ANSI C declarations */
1884 #ifdef POSIX_SIGNALS
1886 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
1887 static struct sigaction new_action
, old_action
;
1891 #ifdef POSIX_SIGNALS
1892 sigemptyset (&signal_empty_mask
);
1893 sigfillset (&signal_full_mask
);
1897 int (*signal_handler_t
) ();
1900 sys_signal (int signal_number
, signal_handler_t action
)
1903 /* This gets us restartable system calls for efficiency.
1904 The "else" code will works as well. */
1905 return (berk_signal (signal_number
, action
));
1907 sigemptyset (&new_action
.sa_mask
);
1908 new_action
.sa_handler
= action
;
1909 new_action
.sa_flags
= NULL
;
1910 new_action (signal_number
, &new_action
, &old_action
);
1911 return (old_action
.sa_handler
);
1916 sys_sigpause (sigset_t new_mask
)
1918 /* pause emulating berk sigpause... */
1919 sigsuspend (&new_mask
);
1923 /* I'd like to have these guys return pointers to the mask storage in here,
1924 but there'd be trouble if the code was saving multiple masks. I'll be
1925 safe and pass the structure. It normally won't be more than 2 bytes
1929 sys_sigblock (sigset_t new_mask
)
1932 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
1937 sys_sigunblock (sigset_t new_mask
)
1940 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
1945 sys_sigsetmask (sigset_t new_mask
)
1948 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1952 #endif /* POSIX_SIGNALS */
1959 register int length
;
1963 long max_str
= 65535;
1965 while (length
> max_str
) {
1966 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1971 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
1973 while (length
-- > 0)
1975 #endif /* not VMS */
1978 /* Saying `void' requires a declaration, above, where bcopy is used
1979 and that declaration causes pain for systems where bcopy is a macro. */
1980 bcopy (b1
, b2
, length
)
1983 register int length
;
1986 long max_str
= 65535;
1988 while (length
> max_str
) {
1989 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
1995 (void) LIB$
MOVC3 (&length
, b1
, b2
);
1997 while (length
-- > 0)
1999 #endif /* not VMS */
2003 bcmp (b1
, b2
, length
) /* This could be a macro! */
2006 register int length
;
2009 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2010 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2012 return STR$
COMPARE (&src1
, &src2
);
2014 while (length
-- > 0)
2019 #endif /* not VMS */
2021 #endif /* not BSTRING */
2025 * The BSD random returns numbers in the range of
2026 * 0 to 2e31 - 1. The USG rand returns numbers in the
2027 * range of 0 to 2e15 - 1. This is probably not significant
2034 /* Arrange to return a range centered on zero. */
2035 return (rand () << 15) + rand () - (1 << 29);
2049 /* Arrange to return a range centered on zero. */
2050 return (rand () << 15) + rand () - (1 << 29);
2060 #ifdef WRONG_NAME_INSQUE
2073 /* If any place else asks for the TERM variable,
2074 allow it to be overridden with the EMACS_TERM variable
2075 before attempting to translate the logical name TERM. As a last
2076 resort, ask for VAX C's special idea of the TERM variable. */
2083 static char buf
[256];
2084 static struct dsc$descriptor_s equiv
2085 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2086 static struct dsc$descriptor_s d_name
2087 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2090 if (!strcmp (name
, "TERM"))
2092 val
= (char *) getenv ("EMACS_TERM");
2097 d_name
.dsc$w_length
= strlen (name
);
2098 d_name
.dsc$a_pointer
= name
;
2099 if (lib$
sys_trnlog (&d_name
, &eqlen
, &equiv
) == 1)
2101 char *str
= (char *) xmalloc (eqlen
+ 1);
2102 bcopy (buf
, str
, eqlen
);
2104 /* This is a storage leak, but a pain to fix. With luck,
2105 no one will ever notice. */
2108 return (char *) getenv (name
);
2113 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2114 to force a call on the debugger from within the image. */
2119 LIB$
SIGNAL (SS$_DEBUG
);
2125 #ifdef LINK_CRTL_SHARE
2126 #ifdef SHAREABLE_LIB_BUG
2127 /* Variables declared noshare and initialized in shareable libraries
2128 cannot be shared. The VMS linker incorrectly forces you to use a private
2129 version which is uninitialized... If not for this "feature", we
2130 could use the C library definition of sys_nerr and sys_errlist. */
2132 char *sys_errlist
[] =
2136 "no such file or directory",
2138 "interrupted system call",
2140 "no such device or address",
2141 "argument list too long",
2142 "exec format error",
2145 "no more processes",
2146 "not enough memory",
2147 "permission denied",
2149 "block device required",
2150 "mount devices busy",
2152 "cross-device link",
2157 "file table overflow",
2158 "too many open files",
2162 "no space left on device",
2164 "read-only file system",
2170 "vax/vms specific error code nontranslatable error"
2172 #endif /* SHAREABLE_LIB_BUG */
2173 #endif /* LINK_CRTL_SHARE */
2176 #ifdef INTERRUPTIBLE_OPEN
2180 sys_open (path
, oflag
, mode
)
2184 register int rtnval
;
2186 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2187 && (errno
== EINTR
));
2191 #endif /* INTERRUPTIBLE_OPEN */
2193 #ifdef INTERRUPTIBLE_CLOSE
2198 register int rtnval
;
2200 while ((rtnval
= close (fd
)) == -1
2201 && (errno
== EINTR
));
2205 #endif /* INTERRUPTIBLE_CLOSE */
2207 #ifdef INTERRUPTIBLE_IO
2210 sys_read (fildes
, buf
, nbyte
)
2215 register int rtnval
;
2217 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2218 && (errno
== EINTR
));
2223 sys_write (fildes
, buf
, nbyte
)
2228 register int rtnval
;
2230 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2231 && (errno
== EINTR
));
2235 #endif /* INTERRUPTIBLE_IO */
2239 * All of the following are for USG.
2241 * On USG systems the system calls are INTERRUPTIBLE by signals
2242 * that the user program has elected to catch. Thus the system call
2243 * must be retried in these cases. To handle this without massive
2244 * changes in the source code, we remap the standard system call names
2245 * to names for our own functions in sysdep.c that do the system call
2246 * with retries. Actually, for portability reasons, it is good
2247 * programming practice, as this example shows, to limit all actual
2248 * system calls to a single occurance in the source. Sure, this
2249 * adds an extra level of function call overhead but it is almost
2250 * always negligible. Fred Fish, Unisoft Systems Inc.
2253 char *sys_siglist
[NSIG
+ 1] =
2256 /* AIX has changed the signals a bit */
2257 "bogus signal", /* 0 */
2258 "hangup", /* 1 SIGHUP */
2259 "interrupt", /* 2 SIGINT */
2260 "quit", /* 3 SIGQUIT */
2261 "illegal instruction", /* 4 SIGILL */
2262 "trace trap", /* 5 SIGTRAP */
2263 "IOT instruction", /* 6 SIGIOT */
2264 "crash likely", /* 7 SIGDANGER */
2265 "floating point exception", /* 8 SIGFPE */
2266 "kill", /* 9 SIGKILL */
2267 "bus error", /* 10 SIGBUS */
2268 "segmentation violation", /* 11 SIGSEGV */
2269 "bad argument to system call", /* 12 SIGSYS */
2270 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2271 "alarm clock", /* 14 SIGALRM */
2272 "software termination signum", /* 15 SIGTERM */
2273 "user defined signal 1", /* 16 SIGUSR1 */
2274 "user defined signal 2", /* 17 SIGUSR2 */
2275 "death of a child", /* 18 SIGCLD */
2276 "power-fail restart", /* 19 SIGPWR */
2277 "bogus signal", /* 20 */
2278 "bogus signal", /* 21 */
2279 "bogus signal", /* 22 */
2280 "bogus signal", /* 23 */
2281 "bogus signal", /* 24 */
2282 "LAN I/O interrupt", /* 25 SIGAIO */
2283 "PTY I/O interrupt", /* 26 SIGPTY */
2284 "I/O intervention required", /* 27 SIGIOINT */
2285 "HFT grant", /* 28 SIGGRANT */
2286 "HFT retract", /* 29 SIGRETRACT */
2287 "HFT sound done", /* 30 SIGSOUND */
2288 "HFT input ready", /* 31 SIGMSG */
2290 "bogus signal", /* 0 */
2291 "hangup", /* 1 SIGHUP */
2292 "interrupt", /* 2 SIGINT */
2293 "quit", /* 3 SIGQUIT */
2294 "illegal instruction", /* 4 SIGILL */
2295 "trace trap", /* 5 SIGTRAP */
2296 "IOT instruction", /* 6 SIGIOT */
2297 "EMT instruction", /* 7 SIGEMT */
2298 "floating point exception", /* 8 SIGFPE */
2299 "kill", /* 9 SIGKILL */
2300 "bus error", /* 10 SIGBUS */
2301 "segmentation violation", /* 11 SIGSEGV */
2302 "bad argument to system call", /* 12 SIGSYS */
2303 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2304 "alarm clock", /* 14 SIGALRM */
2305 "software termination signum", /* 15 SIGTERM */
2306 "user defined signal 1", /* 16 SIGUSR1 */
2307 "user defined signal 2", /* 17 SIGUSR2 */
2308 "death of a child", /* 18 SIGCLD */
2309 "power-fail restart", /* 19 SIGPWR */
2310 #endif /* not AIX */
2315 * Warning, this function may not duplicate 4.2 action properly
2316 * under error conditions.
2320 /* In 4.1, param.h fails to define this. */
2321 #define MAXPATHLEN 1024
2330 char *npath
, *spath
;
2331 extern char *getcwd ();
2333 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2334 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2335 up to first slash. Should be harmless on other systems. */
2336 while (*npath
&& *npath
!= '/')
2338 strcpy (pathname
, npath
);
2339 free (spath
); /* getcwd uses malloc */
2343 #endif /* HAVE_GETWD */
2346 * Emulate rename using unlink/link. Note that this is
2347 * only partially correct. Also, doesn't enforce restriction
2348 * that files be of same type (regular->regular, dir->dir, etc).
2355 if (access (from
, 0) == 0)
2358 if (link (from
, to
) == 0)
2359 if (unlink (from
) == 0)
2365 /* Set priority value to PRIO. */
2368 setpriority (which
, who
, prio
)
2369 int which
, who
, prio
;
2373 nice (prio
- nice (0));
2380 * Substitute fork for vfork on USG flavors.
2388 #endif /* not HAVE_VFORK */
2390 #ifdef MISSING_UTIMES
2392 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2401 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2402 utimbuf structure defined anywhere but in the man page. */
2412 struct timeval tvp
[];
2415 utb
.actime
= tvp
[0].tv_sec
;
2416 utb
.modtime
= tvp
[1].tv_sec
;
2419 #endif /* IRIS_UTIME */
2425 /* HPUX curses library references perror, but as far as we know
2426 it won't be called. Anyway this definition will do for now. */
2432 #endif /* not HAVE_PERROR */
2438 * Emulate BSD dup2. First close newd if it already exists.
2439 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2440 * until we are, then close the unsuccessful ones.
2447 register int fd
, ret
;
2452 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2454 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2461 ret
= dup2 (old
,new);
2467 #endif /* not HAVE_DUP2 */
2470 * Gettimeofday. Simulate as much as possible. Only accurate
2471 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2472 * Only needed when subprocesses are defined.
2477 #ifndef HAVE_GETTIMEOFDAY
2481 gettimeofday (tp
, tzp
)
2483 struct timezone
*tzp
;
2485 extern long time ();
2487 tp
->tv_sec
= time ((long *)0);
2489 tzp
->tz_minuteswest
= -1;
2495 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2498 * This function will go away as soon as all the stubs fixed. (fnf)
2504 printf ("%s not yet implemented\r\n", badfunc
);
2513 char *sys_siglist
[NSIG
+ 1] =
2515 "null signal", /* 0 SIGNULL */
2516 "hangup", /* 1 SIGHUP */
2517 "interrupt", /* 2 SIGINT */
2518 "quit", /* 3 SIGQUIT */
2519 "illegal instruction", /* 4 SIGILL */
2520 "trace trap", /* 5 SIGTRAP */
2521 "abort termination", /* 6 SIGABRT */
2522 "SIGEMT", /* 7 SIGEMT */
2523 "floating point exception", /* 8 SIGFPE */
2524 "kill", /* 9 SIGKILL */
2525 "bus error", /* 10 SIGBUS */
2526 "segmentation violation", /* 11 SIGSEGV */
2527 "bad argument to system call", /* 12 SIGSYS */
2528 "write on a pipe with no reader", /* 13 SIGPIPE */
2529 "alarm clock", /* 14 SIGALRM */
2530 "software termination signal", /* 15 SIGTERM */
2531 "user defined signal 1", /* 16 SIGUSR1 */
2532 "user defined signal 2", /* 17 SIGUSR2 */
2533 "child stopped or terminated", /* 18 SIGCLD */
2534 "power-fail restart", /* 19 SIGPWR */
2535 "window size changed", /* 20 SIGWINCH */
2536 "undefined", /* 21 */
2537 "pollable event occured", /* 22 SIGPOLL */
2538 "sendable stop signal not from tty", /* 23 SIGSTOP */
2539 "stop signal from tty", /* 24 SIGSTP */
2540 "continue a stopped process", /* 25 SIGCONT */
2541 "attempted background tty read", /* 26 SIGTTIN */
2542 "attempted background tty write", /* 27 SIGTTOU */
2543 "undefined", /* 28 */
2544 "undefined", /* 29 */
2545 "undefined", /* 30 */
2546 "undefined", /* 31 */
2547 "undefined", /* 32 */
2548 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2549 "I/O is possible", /* 34 SIGIO */
2550 "exceeded cpu time limit", /* 35 SIGXCPU */
2551 "exceeded file size limit", /* 36 SIGXFSZ */
2552 "virtual time alarm", /* 37 SIGVTALRM */
2553 "profiling time alarm", /* 38 SIGPROF */
2554 "undefined", /* 39 */
2555 "file record locks revoked", /* 40 SIGLOST */
2556 "undefined", /* 41 */
2557 "undefined", /* 42 */
2558 "undefined", /* 43 */
2559 "undefined", /* 44 */
2560 "undefined", /* 45 */
2561 "undefined", /* 46 */
2562 "undefined", /* 47 */
2563 "undefined", /* 48 */
2564 "undefined", /* 49 */
2565 "undefined", /* 50 */
2566 "undefined", /* 51 */
2567 "undefined", /* 52 */
2568 "undefined", /* 53 */
2569 "undefined", /* 54 */
2570 "undefined", /* 55 */
2571 "undefined", /* 56 */
2572 "undefined", /* 57 */
2573 "undefined", /* 58 */
2574 "undefined", /* 59 */
2575 "undefined", /* 60 */
2576 "undefined", /* 61 */
2577 "undefined", /* 62 */
2578 "undefined", /* 63 */
2579 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2585 /* Directory routines for systems that don't have them. */
2587 #ifdef SYSV_SYSTEM_DIR
2594 register DIR *dirp
; /* stream from opendir */
2596 sys_close (dirp
->dd_fd
);
2597 free ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2598 free ((char *) dirp
);
2600 #endif /* not AIX */
2601 #endif /* SYSV_SYSTEM_DIR */
2603 #ifdef NONSYSTEM_DIR_LIBRARY
2607 char *filename
; /* name of directory */
2609 register DIR *dirp
; /* -> malloc'ed storage */
2610 register int fd
; /* file descriptor for read */
2611 struct stat sbuf
; /* result of fstat */
2613 fd
= sys_open (filename
, 0);
2617 if (fstat (fd
, &sbuf
) < 0
2618 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2619 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2622 return 0; /* bad luck today */
2626 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2633 register DIR *dirp
; /* stream from opendir */
2635 sys_close (dirp
->dd_fd
);
2636 free ((char *) dirp
);
2644 ino_t od_ino
; /* inode */
2645 char od_name
[DIRSIZ
]; /* filename */
2647 #endif /* not VMS */
2649 struct direct dir_static
; /* simulated directory contents */
2654 register DIR *dirp
; /* stream from opendir */
2657 register struct olddir
*dp
; /* -> directory data */
2659 register struct dir$_name
*dp
; /* -> directory data */
2660 register struct dir$_version
*dv
; /* -> version data */
2665 if (dirp
->dd_loc
>= dirp
->dd_size
)
2666 dirp
->dd_loc
= dirp
->dd_size
= 0;
2668 if (dirp
->dd_size
== 0 /* refill buffer */
2669 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2673 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
2674 dirp
->dd_loc
+= sizeof (struct olddir
);
2676 if (dp
->od_ino
!= 0) /* not deleted entry */
2678 dir_static
.d_ino
= dp
->od_ino
;
2679 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
2680 dir_static
.d_name
[DIRSIZ
] = '\0';
2681 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2682 dir_static
.d_reclen
= sizeof (struct direct
)
2684 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2685 return &dir_static
; /* -> simulated structure */
2688 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2689 if (dirp
->dd_loc
== 0)
2690 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
2691 : dp
->dir$b_namecount
;
2692 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
2693 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2694 dir_static
.d_namlen
= dp
->dir$b_namecount
;
2695 dir_static
.d_reclen
= sizeof (struct direct
)
2697 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2698 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2699 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
2700 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
2707 /* readdirver is just like readdir except it returns all versions of a file
2708 as separate entries. */
2713 register DIR *dirp
; /* stream from opendir */
2715 register struct dir$_name
*dp
; /* -> directory data */
2716 register struct dir$_version
*dv
; /* -> version data */
2718 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
2719 dirp
->dd_loc
= dirp
->dd_size
= 0;
2721 if (dirp
->dd_size
== 0 /* refill buffer */
2722 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2725 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2726 if (dirp
->dd_loc
== 0)
2727 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
2728 : dp
->dir$b_namecount
;
2729 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
2730 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2731 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
2732 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2733 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2734 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
2735 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2736 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
2742 #endif /* NONSYSTEM_DIR_LIBRARY */
2744 /* Functions for VMS */
2746 #include "vms-pwd.h"
2751 /* Return as a string the VMS error string pertaining to STATUS.
2752 Reuses the same static buffer each time it is called. */
2756 int status
; /* VMS status code */
2760 static char buf
[257];
2762 bufadr
[0] = sizeof buf
- 1;
2763 bufadr
[1] = (int) buf
;
2764 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
2765 return "untranslatable VMS error status";
2773 /* The following is necessary because 'access' emulation by VMS C (2.0) does
2774 * not work correctly. (It also doesn't work well in version 2.3.)
2779 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
2780 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
2784 unsigned short s_buflen
;
2785 unsigned short s_code
;
2787 unsigned short *s_retlenadr
;
2791 #define buflen s.s_buflen
2792 #define code s.s_code
2793 #define bufadr s.s_bufadr
2794 #define retlenadr s.s_retlenadr
2796 #define R_OK 4 /* test for read permission */
2797 #define W_OK 2 /* test for write permission */
2798 #define X_OK 1 /* test for execute (search) permission */
2799 #define F_OK 0 /* test for presence of file */
2802 sys_access (path
, mode
)
2806 static char *user
= NULL
;
2809 /* translate possible directory spec into .DIR file name, so brain-dead
2810 * access can treat the directory like a file. */
2811 if (directory_file_name (path
, dir_fn
))
2815 return access (path
, mode
);
2816 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
2822 unsigned short int dummy
;
2824 static int constant
= ACL$C_FILE
;
2825 DESCRIPTOR (path_desc
, path
);
2826 DESCRIPTOR (user_desc
, user
);
2830 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
2833 acces
|= CHP$M_READ
;
2835 acces
|= CHP$M_WRITE
;
2836 itemlst
[0].buflen
= sizeof (int);
2837 itemlst
[0].code
= CHP$_FLAGS
;
2838 itemlst
[0].bufadr
= (char *) &flags
;
2839 itemlst
[0].retlenadr
= &dummy
;
2840 itemlst
[1].buflen
= sizeof (int);
2841 itemlst
[1].code
= CHP$_ACCESS
;
2842 itemlst
[1].bufadr
= (char *) &acces
;
2843 itemlst
[1].retlenadr
= &dummy
;
2844 itemlst
[2].end
= CHP$_END
;
2845 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
2846 return stat
== SS$_NORMAL
? 0 : -1;
2850 #else /* not VMS4_4 */
2853 #define ACE$M_WRITE 2
2854 #define ACE$C_KEYID 1
2856 static unsigned short memid
, grpid
;
2857 static unsigned int uic
;
2859 /* Called from init_sys_modes, so it happens not very often
2860 but at least each time Emacs is loaded. */
2861 sys_access_reinit ()
2867 sys_access (filename
, type
)
2873 int status
, size
, i
, typecode
, acl_controlled
;
2874 unsigned int *aclptr
, *aclend
, aclbuf
[60];
2875 union prvdef prvmask
;
2877 /* Get UIC and GRP values for protection checking. */
2880 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
2883 memid
= uic
& 0xFFFF;
2887 if (type
!= 2) /* not checking write access */
2888 return access (filename
, type
);
2890 /* Check write protection. */
2892 #define CHECKPRIV(bit) (prvmask.bit)
2893 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
2895 /* Find privilege bits */
2896 status
= sys$
setprv (0, 0, 0, prvmask
);
2898 error ("Unable to find privileges: %s", vmserrstr (status
));
2899 if (CHECKPRIV (PRV$V_BYPASS
))
2900 return 0; /* BYPASS enabled */
2902 fab
.fab$b_fac
= FAB$M_GET
;
2903 fab
.fab$l_fna
= filename
;
2904 fab
.fab$b_fns
= strlen (filename
);
2905 fab
.fab$l_xab
= &xab
;
2906 xab
= cc$rms_xabpro
;
2907 xab
.xab$l_aclbuf
= aclbuf
;
2908 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
2909 status
= sys$
open (&fab
, 0, 0);
2912 sys$
close (&fab
, 0, 0);
2913 /* Check system access */
2914 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
2916 /* Check ACL entries, if any */
2918 if (xab
.xab$w_acllen
> 0)
2921 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
2922 while (*aclptr
&& aclptr
< aclend
)
2924 size
= (*aclptr
& 0xff) / 4;
2925 typecode
= (*aclptr
>> 8) & 0xff;
2926 if (typecode
== ACE$C_KEYID
)
2927 for (i
= size
- 1; i
> 1; i
--)
2928 if (aclptr
[i
] == uic
)
2931 if (aclptr
[1] & ACE$M_WRITE
)
2932 return 0; /* Write access through ACL */
2934 aclptr
= &aclptr
[size
];
2936 if (acl_controlled
) /* ACL specified, prohibits write access */
2939 /* No ACL entries specified, check normal protection */
2940 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
2942 if (WRITEABLE (XAB$V_GRP
) &&
2943 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
2944 return 0; /* Group writeable */
2945 if (WRITEABLE (XAB$V_OWN
) &&
2946 (xab
.xab$l_uic
& 0xFFFF) == memid
)
2947 return 0; /* Owner writeable */
2949 return -1; /* Not writeable */
2951 #endif /* not VMS4_4 */
2954 static char vtbuf
[NAM$C_MAXRSS
+1];
2956 /* translate a vms file spec to a unix path */
2958 sys_translate_vms (vfile
)
2969 /* leading device or logical name is a root directory */
2970 if (p
= strchr (vfile
, ':'))
2979 if (*p
== '[' || *p
== '<')
2981 while (*++vfile
!= *p
+ 2)
2985 if (vfile
[-1] == *p
)
3008 static char utbuf
[NAM$C_MAXRSS
+1];
3010 /* translate a unix path to a VMS file spec */
3012 sys_translate_unix (ufile
)
3035 if (index (&ufile
[1], '/'))
3042 if (index (&ufile
[1], '/'))
3049 if (strncmp (ufile
, "./", 2) == 0)
3056 ufile
++; /* skip the dot */
3057 if (index (&ufile
[1], '/'))
3062 else if (strncmp (ufile
, "../", 3) == 0)
3070 ufile
+= 2; /* skip the dots */
3071 if (index (&ufile
[1], '/'))
3096 strcpy (pathname
, egetenv ("PATH"));
3101 if ('a' <= *ptr
&& *ptr
<= 'z')
3110 long item_code
= JPI$_OWNER
;
3111 unsigned long parent_id
;
3114 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3117 vaxc$errno
= status
;
3127 return (getgid () << 16) | getuid ();
3131 sys_read (fildes
, buf
, nbyte
)
3136 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3141 sys_write (fildes
, buf
, nbyte
)
3146 register int nwrote
, rtnval
= 0;
3148 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3154 return rtnval
? rtnval
: -1;
3155 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3156 return rtnval
? rtnval
: -1;
3157 return (rtnval
+ nwrote
);
3162 * VAX/VMS VAX C RTL really loses. It insists that records
3163 * end with a newline (carriage return) character, and if they
3164 * don't it adds one (nice of it isn't it!)
3166 * Thus we do this stupidity below.
3170 sys_write (fildes
, buf
, nbytes
)
3173 unsigned int nbytes
;
3180 fstat (fildes
, &st
);
3186 /* Handle fixed-length files with carriage control. */
3187 if (st
.st_fab_rfm
== FAB$C_FIX
3188 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3190 len
= st
.st_fab_mrs
;
3191 retval
= write (fildes
, p
, min (len
, nbytes
));
3194 retval
++; /* This skips the implied carriage control */
3198 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3199 while (*e
!= '\n' && e
> p
) e
--;
3200 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3201 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3203 retval
= write (fildes
, p
, len
);
3214 /* Create file NEW copying its attributes from file OLD. If
3215 OLD is 0 or does not exist, create based on the value of
3218 /* Protection value the file should ultimately have.
3219 Set by create_copy_attrs, and use by rename_sansversions. */
3220 static unsigned short int fab_final_pro
;
3223 creat_copy_attrs (old
, new)
3226 struct FAB fab
= cc$rms_fab
;
3227 struct XABPRO xabpro
;
3228 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3229 extern int vms_stmlf_recfm
;
3233 fab
.fab$b_fac
= FAB$M_GET
;
3234 fab
.fab$l_fna
= old
;
3235 fab
.fab$b_fns
= strlen (old
);
3236 fab
.fab$l_xab
= (char *) &xabpro
;
3237 xabpro
= cc$rms_xabpro
;
3238 xabpro
.xab$l_aclbuf
= aclbuf
;
3239 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3240 /* Call $OPEN to fill in the fab & xabpro fields. */
3241 if (sys$
open (&fab
, 0, 0) & 1)
3243 sys$
close (&fab
, 0, 0);
3244 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3245 if (xabpro
.xab$w_acllen
> 0)
3247 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3248 /* If the acl buffer was too short, redo open with longer one.
3249 Wouldn't need to do this if there were some system imposed
3250 limit on the size of an ACL, but I can't find any such. */
3252 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3253 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3254 if (sys$
open (&fab
, 0, 0) & 1)
3255 sys$
close (&fab
, 0, 0);
3261 xabpro
.xab$l_aclbuf
= 0;
3266 fab
.fab$l_fna
= new;
3267 fab
.fab$b_fns
= strlen (new);
3271 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3272 fab
.fab$b_rat
= FAB$M_CR
;
3275 /* Set the file protections such that we will be able to manipulate
3276 this file. Once we are done writing and renaming it, we will set
3277 the protections back. */
3279 fab_final_pro
= xabpro
.xab$w_pro
;
3281 sys$
setdfprot (0, &fab_final_pro
);
3282 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3284 /* Create the new file with either default attrs or attrs copied
3286 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3288 sys$
close (&fab
, 0, 0);
3289 /* As this is a "replacement" for creat, return a file descriptor
3290 opened for writing. */
3291 return open (new, O_WRONLY
);
3296 #include <varargs.h>
3299 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3303 sys_creat (va_alist
)
3306 va_list list_incrementor
;
3309 int rfd
; /* related file descriptor */
3310 int fd
; /* Our new file descriptor */
3317 extern int vms_stmlf_recfm
;
3320 va_start (list_incrementor
);
3321 name
= va_arg (list_incrementor
, char *);
3322 mode
= va_arg (list_incrementor
, int);
3324 rfd
= va_arg (list_incrementor
, int);
3325 va_end (list_incrementor
);
3328 /* Use information from the related file descriptor to set record
3329 format of the newly created file. */
3330 fstat (rfd
, &st_buf
);
3331 switch (st_buf
.st_fab_rfm
)
3334 strcpy (rfm
, "rfm = fix");
3335 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3336 strcpy (rat
, "rat = ");
3337 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3339 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3340 strcat (rat
, "ftn");
3341 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3342 strcat (rat
, "prn");
3343 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3344 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3345 strcat (rat
, ", blk");
3347 strcat (rat
, "blk");
3348 return creat (name
, 0, rfm
, rat
, mrs
);
3351 strcpy (rfm
, "rfm = vfc");
3352 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3353 strcpy (rat
, "rat = ");
3354 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3356 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3357 strcat (rat
, "ftn");
3358 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3359 strcat (rat
, "prn");
3360 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3361 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3362 strcat (rat
, ", blk");
3364 strcat (rat
, "blk");
3365 return creat (name
, 0, rfm
, rat
, fsz
);
3368 strcpy (rfm
, "rfm = stm");
3372 strcpy (rfm
, "rfm = stmcr");
3376 strcpy (rfm
, "rfm = stmlf");
3380 strcpy (rfm
, "rfm = udf");
3384 strcpy (rfm
, "rfm = var");
3387 strcpy (rat
, "rat = ");
3388 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3390 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3391 strcat (rat
, "ftn");
3392 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3393 strcat (rat
, "prn");
3394 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3395 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3396 strcat (rat
, ", blk");
3398 strcat (rat
, "blk");
3402 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3403 strcpy (rat
, "rat=cr");
3405 /* Until the VAX C RTL fixes the many bugs with modes, always use
3406 mode 0 to get the user's default protection. */
3407 fd
= creat (name
, 0, rfm
, rat
);
3408 if (fd
< 0 && errno
== EEXIST
)
3410 if (unlink (name
) < 0)
3411 report_file_error ("delete", build_string (name
));
3412 fd
= creat (name
, 0, rfm
, rat
);
3418 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3419 sys_fwrite (ptr
, size
, num
, fp
)
3420 register char * ptr
;
3423 register int tot
= num
* size
;
3430 * The VMS C library routine creat actually creates a new version of an
3431 * existing file rather than truncating the old version. There are times
3432 * when this is not the desired behavior, for instance, when writing an
3433 * auto save file (you only want one version), or when you don't have
3434 * write permission in the directory containing the file (but the file
3435 * itself is writable). Hence this routine, which is equivalent to
3436 * "close (creat (fn, 0));" on Unix if fn already exists.
3442 struct FAB xfab
= cc$rms_fab
;
3443 struct RAB xrab
= cc$rms_rab
;
3446 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3447 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3448 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3449 xfab
.fab$l_fna
= fn
;
3450 xfab
.fab$b_fns
= strlen (fn
);
3451 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3453 xrab
.rab$l_fab
= &xfab
;
3455 /* This gibberish opens the file, positions to the first record, and
3456 deletes all records from there until the end of file. */
3457 if ((sys$
open (&xfab
) & 01) == 01)
3459 if ((sys$
connect (&xrab
) & 01) == 01 &&
3460 (sys$
find (&xrab
) & 01) == 01 &&
3461 (sys$
truncate (&xrab
) & 01) == 01)
3472 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3473 SYSPRV or a readable SYSUAF.DAT. */
3479 * Routine to read the VMS User Authorization File and return
3480 * a specific user's record.
3483 static struct UAF retuaf
;
3486 get_uaf_name (uname
)
3493 uaf_fab
= cc$rms_fab
;
3494 uaf_rab
= cc$rms_rab
;
3495 /* initialize fab fields */
3496 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3497 uaf_fab
.fab$b_fns
= 21;
3498 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3499 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3500 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3501 /* initialize rab fields */
3502 uaf_rab
.rab$l_fab
= &uaf_fab
;
3503 /* open the User Authorization File */
3504 status
= sys$
open (&uaf_fab
);
3508 vaxc$errno
= status
;
3511 status
= sys$
connect (&uaf_rab
);
3515 vaxc$errno
= status
;
3518 /* read the requested record - index is in uname */
3519 uaf_rab
.rab$l_kbf
= uname
;
3520 uaf_rab
.rab$b_ksz
= strlen (uname
);
3521 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3522 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3523 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3524 status
= sys$
get (&uaf_rab
);
3528 vaxc$errno
= status
;
3531 /* close the User Authorization File */
3532 status
= sys$
disconnect (&uaf_rab
);
3536 vaxc$errno
= status
;
3539 status
= sys$
close (&uaf_fab
);
3543 vaxc$errno
= status
;
3557 uaf_fab
= cc$rms_fab
;
3558 uaf_rab
= cc$rms_rab
;
3559 /* initialize fab fields */
3560 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3561 uaf_fab
.fab$b_fns
= 21;
3562 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3563 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3564 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3565 /* initialize rab fields */
3566 uaf_rab
.rab$l_fab
= &uaf_fab
;
3567 /* open the User Authorization File */
3568 status
= sys$
open (&uaf_fab
);
3572 vaxc$errno
= status
;
3575 status
= sys$
connect (&uaf_rab
);
3579 vaxc$errno
= status
;
3582 /* read the requested record - index is in uic */
3583 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3584 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3585 uaf_rab
.rab$b_ksz
= sizeof uic
;
3586 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3587 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3588 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3589 status
= sys$
get (&uaf_rab
);
3593 vaxc$errno
= status
;
3596 /* close the User Authorization File */
3597 status
= sys$
disconnect (&uaf_rab
);
3601 vaxc$errno
= status
;
3604 status
= sys$
close (&uaf_fab
);
3608 vaxc$errno
= status
;
3614 static struct passwd retpw
;
3622 /* copy these out first because if the username is 32 chars, the next
3623 section will overwrite the first byte of the UIC */
3624 retpw
.pw_uid
= up
->uaf$w_mem
;
3625 retpw
.pw_gid
= up
->uaf$w_grp
;
3627 /* I suppose this is not the best sytle, to possibly overwrite one
3628 byte beyond the end of the field, but what the heck... */
3629 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3630 while (ptr
[-1] == ' ')
3633 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3635 /* the rest of these are counted ascii strings */
3636 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3637 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3638 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3639 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3640 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3641 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3642 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3643 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3647 #else /* not READ_SYSUAF */
3648 static struct passwd retpw
;
3649 #endif /* not READ_SYSUAF */
3660 unsigned char * full
;
3661 #endif /* READ_SYSUAF */
3666 if ('a' <= *ptr
&& *ptr
<= 'z')
3671 if (!(up
= get_uaf_name (name
)))
3673 return cnv_uaf_pw (up
);
3675 if (strcmp (name
, getenv ("USER")) == 0)
3677 retpw
.pw_uid
= getuid ();
3678 retpw
.pw_gid
= getgid ();
3679 strcpy (retpw
.pw_name
, name
);
3680 if (full
= egetenv ("FULLNAME"))
3681 strcpy (retpw
.pw_gecos
, full
);
3683 *retpw
.pw_gecos
= '\0';
3684 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
3685 *retpw
.pw_shell
= '\0';
3690 #endif /* not READ_SYSUAF */
3700 if (!(up
= get_uaf_uic (uid
)))
3702 return cnv_uaf_pw (up
);
3704 if (uid
== sys_getuid ())
3705 return getpwnam (egetenv ("USER"));
3708 #endif /* not READ_SYSUAF */
3711 /* return total address space available to the current process. This is
3712 the sum of the current p0 size, p1 size and free page table entries
3717 unsigned long free_pages
;
3718 unsigned long frep0va
;
3719 unsigned long frep1va
;
3722 item_code
= JPI$_FREPTECNT
;
3723 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
3726 vaxc$errno
= status
;
3731 item_code
= JPI$_FREP0VA
;
3732 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
3735 vaxc$errno
= status
;
3738 item_code
= JPI$_FREP1VA
;
3739 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
3742 vaxc$errno
= status
;
3746 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
3749 define_logical_name (varname
, string
)
3753 struct dsc$descriptor_s strdsc
=
3754 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
3755 struct dsc$descriptor_s envdsc
=
3756 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3757 struct dsc$descriptor_s lnmdsc
=
3758 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3760 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
3763 delete_logical_name (varname
)
3766 struct dsc$descriptor_s envdsc
=
3767 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3768 struct dsc$descriptor_s lnmdsc
=
3769 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3771 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
3785 error ("execvp system call not implemented");
3793 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
3794 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
3795 char from_esn
[NAM$C_MAXRSS
];
3796 char to_esn
[NAM$C_MAXRSS
];
3798 from_fab
.fab$l_fna
= from
;
3799 from_fab
.fab$b_fns
= strlen (from
);
3800 from_fab
.fab$l_nam
= &from_nam
;
3801 from_fab
.fab$l_fop
= FAB$M_NAM
;
3803 from_nam
.nam$l_esa
= from_esn
;
3804 from_nam
.nam$b_ess
= sizeof from_esn
;
3806 to_fab
.fab$l_fna
= to
;
3807 to_fab
.fab$b_fns
= strlen (to
);
3808 to_fab
.fab$l_nam
= &to_nam
;
3809 to_fab
.fab$l_fop
= FAB$M_NAM
;
3811 to_nam
.nam$l_esa
= to_esn
;
3812 to_nam
.nam$b_ess
= sizeof to_esn
;
3814 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
3820 if (status
== RMS$_DEV
)
3824 vaxc$errno
= status
;
3829 /* This function renames a file like `rename', but it strips
3830 the version number from the "to" filename, such that the "to" file is
3831 will always be a new version. It also sets the file protection once it is
3832 finished. The protection that we will use is stored in fab_final_pro,
3833 and was set when we did a creat_copy_attrs to create the file that we
3836 We could use the chmod function, but Eunichs uses 3 bits per user category
3837 to describe the protection, and VMS uses 4 (write and delete are seperate
3838 bits). To maintain portability, the VMS implementation of `chmod' wires
3839 the W and D bits together. */
3842 static struct fibdef fib
; /* We need this initialized to zero */
3843 char vms_file_written
[NAM$C_MAXRSS
];
3846 rename_sans_version (from
,to
)
3853 struct FAB to_fab
= cc$rms_fab
;
3854 struct NAM to_nam
= cc$rms_nam
;
3855 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
3856 struct dsc$descriptor fib_attr
[2]
3857 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
3858 char to_esn
[NAM$C_MAXRSS
];
3860 $
DESCRIPTOR (disk
,to_esn
);
3862 to_fab
.fab$l_fna
= to
;
3863 to_fab
.fab$b_fns
= strlen (to
);
3864 to_fab
.fab$l_nam
= &to_nam
;
3865 to_fab
.fab$l_fop
= FAB$M_NAM
;
3867 to_nam
.nam$l_esa
= to_esn
;
3868 to_nam
.nam$b_ess
= sizeof to_esn
;
3870 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
3872 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
3873 *(to_nam
.nam$l_ver
) = '\0';
3875 stat
= rename (from
, to_esn
);
3879 strcpy (vms_file_written
, to_esn
);
3881 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
3882 to_fab
.fab$b_fns
= strlen (vms_file_written
);
3884 /* Now set the file protection to the correct value */
3885 sys$
open (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
3887 /* Copy these fields into the fib */
3888 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
3889 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
3890 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
3892 sys$
close (&to_fab
, 0, 0);
3894 stat
= sys$
assign (&disk
, &chan
, 0, 0); /* open a channel to the disk */
3897 stat
= sys$
qiow (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
3898 0, 0, 0, &fib_attr
, 0);
3901 stat
= sys$
dassgn (chan
);
3904 strcpy (vms_file_written
, to_esn
); /* We will write this to the screen*/
3914 unsigned short fid
[3];
3915 char esa
[NAM$C_MAXRSS
];
3918 fab
.fab$l_fop
= FAB$M_OFP
;
3919 fab
.fab$l_fna
= file
;
3920 fab
.fab$b_fns
= strlen (file
);
3921 fab
.fab$l_nam
= &nam
;
3924 nam
.nam$l_esa
= esa
;
3925 nam
.nam$b_ess
= NAM$C_MAXRSS
;
3927 status
= SYS$
PARSE (&fab
);
3928 if ((status
& 1) == 0)
3931 vaxc$errno
= status
;
3934 status
= SYS$
SEARCH (&fab
);
3935 if ((status
& 1) == 0)
3938 vaxc$errno
= status
;
3942 fid
[0] = nam
.nam$w_fid
[0];
3943 fid
[1] = nam
.nam$w_fid
[1];
3944 fid
[2] = nam
.nam$w_fid
[2];
3946 fab
.fab$l_fna
= new;
3947 fab
.fab$b_fns
= strlen (new);
3949 status
= SYS$
PARSE (&fab
);
3950 if ((status
& 1) == 0)
3953 vaxc$errno
= status
;
3957 nam
.nam$w_fid
[0] = fid
[0];
3958 nam
.nam$w_fid
[1] = fid
[1];
3959 nam
.nam$w_fid
[2] = fid
[2];
3961 nam
.nam$l_esa
= nam
.nam$l_name
;
3962 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
3964 status
= SYS$
ENTER (&fab
);
3965 if ((status
& 1) == 0)
3968 vaxc$errno
= status
;
3978 printf ("%s not yet implemented\r\n", badfunc
);
3986 /* Arrange to return a range centered on zero. */
3987 return rand () - (1 << 30);
3998 /* Called from init_sys_modes. */
4003 /* If we're not on an HFT we shouldn't do any of this. We determine
4004 if we are on an HFT by trying to get an HFT error code. If this
4005 call fails, we're not on an HFT. */
4007 if (ioctl (0, HFQERROR
, &junk
) < 0)
4009 #else /* not IBMR2AIX */
4010 if (ioctl (0, HFQEIO
, 0) < 0)
4012 #endif /* not IBMR2AIX */
4014 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4015 as the rubout key's ASCII code. Here this is changed. The bug is that
4016 there's no way to determine the old mapping, so in reset_sys_modes
4017 we need to assume that the normal map had been present. Of course, this
4018 code also doesn't help if on a terminal emulator which doesn't understand
4022 struct hfkeymap keymap
;
4024 buf
.hf_bufp
= (char *)&keymap
;
4025 buf
.hf_buflen
= sizeof (keymap
);
4026 keymap
.hf_nkeys
= 2;
4027 keymap
.hfkey
[0].hf_kpos
= 15;
4028 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4030 keymap
.hfkey
[0].hf_keyidh
= '<';
4031 #else /* not IBMR2AIX */
4032 keymap
.hfkey
[0].hf_page
= '<';
4033 #endif /* not IBMR2AIX */
4034 keymap
.hfkey
[0].hf_char
= 127;
4035 keymap
.hfkey
[1].hf_kpos
= 15;
4036 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4038 keymap
.hfkey
[1].hf_keyidh
= '<';
4039 #else /* not IBMR2AIX */
4040 keymap
.hfkey
[1].hf_page
= '<';
4041 #endif /* not IBMR2AIX */
4042 keymap
.hfkey
[1].hf_char
= 127;
4043 hftctl (0, HFSKBD
, &buf
);
4045 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4047 line_ins_del_ok
= char_ins_del_ok
= 0;
4050 /* Reset the rubout key to backspace. */
4055 struct hfkeymap keymap
;
4059 if (ioctl (0, HFQERROR
, &junk
) < 0)
4061 #else /* not IBMR2AIX */
4062 if (ioctl (0, HFQEIO
, 0) < 0)
4064 #endif /* not IBMR2AIX */
4066 buf
.hf_bufp
= (char *)&keymap
;
4067 buf
.hf_buflen
= sizeof (keymap
);
4068 keymap
.hf_nkeys
= 2;
4069 keymap
.hfkey
[0].hf_kpos
= 15;
4070 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4072 keymap
.hfkey
[0].hf_keyidh
= '<';
4073 #else /* not IBMR2AIX */
4074 keymap
.hfkey
[0].hf_page
= '<';
4075 #endif /* not IBMR2AIX */
4076 keymap
.hfkey
[0].hf_char
= 8;
4077 keymap
.hfkey
[1].hf_kpos
= 15;
4078 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4080 keymap
.hfkey
[1].hf_keyidh
= '<';
4081 #else /* not IBMR2AIX */
4082 keymap
.hfkey
[1].hf_page
= '<';
4083 #endif /* not IBMR2AIX */
4084 keymap
.hfkey
[1].hf_char
= 8;
4085 hftctl (0, HFSKBD
, &buf
);