1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 86, 87, 88, 93, 94 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 2, 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. */
26 #include "blockinput.h"
29 #define min(x,y) ((x) > (y) ? (y) : (x))
31 /* In this file, open, read and write refer to the system calls,
32 not our sugared interfaces sys_open, sys_read and sys_write.
33 Contrariwise, for systems where we use the system calls directly,
34 define sys_read, etc. here as aliases for them. */
37 #define sys_write write
38 #endif /* `read' is not a macro */
44 #define sys_close close
51 #else /* `open' is a macro */
53 #endif /* `open' is a macro */
55 /* Does anyone other than VMS need this? */
57 #define sys_fwrite fwrite
63 #include <sys/types.h>
67 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
71 #include <sys/param.h>
96 #define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */
100 #ifdef BSD /* this is done this way to avoid defined (BSD) || defined (USG)
101 because the vms compiler doesn't grok `defined' */
109 #endif /* not 4.1 bsd */
112 /* On some systems (DGUX comes to mind real fast) FASYNC causes
113 background writes to the terminal to stop all processes in the
114 process group when invoked under the csh (and probably any shell
115 with job control). This stops Emacs dead in its tracks when coming
121 #include <sys/ioctl.h>
126 #ifdef BROKEN_TIOCGWINSZ
132 #include <sys/utsname.h>
134 #ifndef MEMORY_IN_STRING_H
137 #if defined (TIOCGWINSZ) || defined (ISC4_0)
139 #include <sys/sioctl.h>
142 #include <sys/stream.h>
143 #include <sys/ptem.h>
145 #endif /* TIOCGWINSZ or ISC4_0 */
148 extern int quit_char
;
152 #include "termhooks.h"
153 #include "termchar.h"
154 #include "termopts.h"
155 #include "dispextern.h"
158 #ifdef NONSYSTEM_DIR_LIBRARY
160 #endif /* NONSYSTEM_DIR_LIBRARY */
162 #include "syssignal.h"
165 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
171 #define LNOFLSH 0100000
174 static int baud_convert
[] =
179 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
180 1800, 2400, 4800, 9600, 19200, 38400
186 /* The file descriptor for Emacs's input terminal.
187 Under Unix, this is normaly zero except when using X;
188 under VMS, we place the input channel number here.
189 This allows us to write more code that works for both VMS and Unix. */
192 /* Specify a different file descriptor for further input operations. */
201 /* Discard pending input on descriptor input_fd. */
205 struct emacs_tty buf
;
210 /* Discarding input is not safe when the input could contain
211 replies from the X server. So don't do it. */
212 if (read_socket_hook
)
217 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
218 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
224 ioctl (input_fd
, TIOCFLUSH
, &zero
);
226 #else /* not Apollo */
227 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
228 while (dos_keyread () != -1)
230 #else /* not MSDOS */
231 EMACS_GET_TTY (input_fd
, &buf
);
232 EMACS_SET_TTY (input_fd
, &buf
, 0);
233 #endif /* not MSDOS */
234 #endif /* not Apollo */
240 /* Arrange for character C to be read as the next input from
246 /* Should perhaps error if in batch mode */
248 ioctl (input_fd
, TIOCSTI
, &c
);
249 #else /* no TIOCSTI */
250 error ("Cannot stuff terminal input characters in this version of Unix");
251 #endif /* no TIOCSTI */
268 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
269 &sg
.class, 12, 0, 0, 0, 0 );
270 ospeed
= sg
.xmit_baud
;
276 tcgetattr (input_fd
, &sg
);
277 ospeed
= cfgetospeed (&sg
);
278 #else /* neither VMS nor TERMIOS */
284 tcgetattr (input_fd
, &sg
);
286 ioctl (input_fd
, TCGETA
, &sg
);
288 ospeed
= sg
.c_cflag
& CBAUD
;
289 #else /* neither VMS nor TERMIOS nor TERMIO */
292 sg
.sg_ospeed
= B9600
;
293 if (ioctl (input_fd
, TIOCGETP
, &sg
) < 0)
295 ospeed
= sg
.sg_ospeed
;
296 #endif /* not HAVE_TERMIO */
297 #endif /* not HAVE_TERMIOS */
299 #endif /* not MSDOS */
302 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
303 ? baud_convert
[ospeed
] : 9600);
309 set_exclusive_use (fd
)
313 ioctl (fd
, FIOCLEX
, 0);
315 /* Ok to do nothing if this feature does not exist */
320 wait_without_blocking ()
323 wait3 (0, WNOHANG
| WUNTRACED
, 0);
325 croak ("wait_without_blocking");
327 synch_process_alive
= 0;
330 #endif /* not subprocesses */
332 int wait_debugging
; /* Set nonzero to make following function work under dbx
333 (at least for bsd). */
336 wait_for_termination_signal ()
339 /* Wait for subprocess with process id `pid' to terminate and
340 make sure it will get eliminated (not remain forever as a zombie) */
342 wait_for_termination (pid
)
351 status
= SYS$
FORCEX (&pid
, 0, 0);
354 #if defined (BSD) || (defined (HPUX) && !defined (HPUX_5))
355 /* Note that kill returns -1 even if the process is just a zombie now.
356 But inevitably a SIGCHLD interrupt should be generated
357 and child_sig will do wait3 and make the process go away. */
358 /* There is some indication that there is a bug involved with
359 termination of subprocesses, perhaps involving a kernel bug too,
360 but no idea what it is. Just as a hunch we signal SIGCHLD to see
361 if that causes the problem to go away or get worse. */
362 sigsetmask (sigmask (SIGCHLD
));
363 if (0 > kill (pid
, 0))
365 sigsetmask (SIGEMPTYMASK
);
366 kill (getpid (), SIGCHLD
);
372 sigpause (SIGEMPTYMASK
);
373 #else /* not BSD, and not HPUX version >= 6 */
374 #if defined (UNIPLUS)
375 if (0 > kill (pid
, 0))
378 #else /* neither BSD nor UNIPLUS: random sysV */
379 #ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
380 sigblock (sigmask (SIGCHLD
));
381 if (0 > kill (pid
, 0))
383 sigunblock (sigmask (SIGCHLD
));
386 sigpause (SIGEMPTYMASK
);
387 #else /* not POSIX_SIGNALS */
388 #ifdef HAVE_SYSV_SIGPAUSE
390 if (0 > kill (pid
, 0))
396 #else /* not HAVE_SYSV_SIGPAUSE */
397 if (0 > kill (pid
, 0))
399 /* Using sleep instead of pause avoids timing error.
400 If the inferior dies just before the sleep,
401 we lose just one second. */
403 #endif /* not HAVE_SYSV_SIGPAUSE */
404 #endif /* not POSIX_SIGNALS */
405 #endif /* not UNIPLUS */
406 #endif /* not BSD, and not HPUX version >= 6 */
408 #else /* not subprocesses */
410 if (kill (pid
, 0) < 0)
416 if (status
== pid
|| status
== -1)
419 #endif /* not subprocesses */
426 * flush any pending output
427 * (may flush input as well; it does not matter the way we use it)
430 flush_pending_output (channel
)
434 /* If we try this, we get hit with SIGTTIN, because
435 the child's tty belongs to the child's pgrp. */
438 ioctl (channel
, TCFLSH
, 1);
442 /* 3rd arg should be ignored
443 but some 4.2 kernels actually want the address of an int
444 and nonzero means something different. */
445 ioctl (channel
, TIOCFLUSH
, &zero
);
452 /* Set up the terminal at the other end of a pseudo-terminal that
453 we will be controlling an inferior through.
454 It should not echo or do line-editing, since that is done
455 in Emacs. No padding needed for insertion into an Emacs buffer. */
457 child_setup_tty (out
)
463 EMACS_GET_TTY (out
, &s
);
465 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
466 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
467 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
469 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
470 /* No output delays */
472 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
473 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
475 s
.main
.c_iflag
&= ~IUCLC
; /* Disable downcasing on input. */
478 s
.main
.c_oflag
&= ~OLCUC
; /* Disable upcasing on output. */
480 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CSIZE
) | CS8
; /* Don't strip 8th bit */
482 /* Said to be unnecessary: */
483 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
484 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
487 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
488 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
489 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
490 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
493 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
497 /* AIX enhanced edit loses NULs, so disable it */
500 s
.main
.c_iflag
&= ~ASCEDIT
;
502 /* Also, PTY overloads NUL and BREAK.
503 don't ignore break, but don't signal either, so it looks like NUL. */
504 s
.main
.c_iflag
&= ~IGNBRK
;
505 s
.main
.c_iflag
&= ~BRKINT
;
506 /* QUIT and INTR work better as signals, so disable character forms */
507 s
.main
.c_cc
[VINTR
] = 0377;
508 #ifdef SIGNALS_VIA_CHARACTERS
509 /* the QUIT and INTR character are used in process_send_signal
510 so set them here to something useful. */
511 if (s
.main
.c_cc
[VQUIT
] == 0377)
512 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
513 if (s
.main
.c_cc
[VINTR
] == 0377)
514 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
515 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
516 /* QUIT and INTR work better as signals, so disable character forms */
517 s
.main
.c_cc
[VQUIT
] = 0377;
518 s
.main
.c_cc
[VINTR
] = 0377;
519 s
.main
.c_lflag
&= ~ISIG
;
520 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
521 s
.main
.c_cc
[VEOL
] = 0377;
522 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
525 #else /* not HAVE_TERMIO */
527 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
529 s
.main
.sg_flags
|= LPASS8
;
530 s
.main
.sg_erase
= 0377;
531 s
.main
.sg_kill
= 0377;
532 s
.lmode
= LLITOUT
| s
.lmode
; /* Don't strip 8th bit */
534 #endif /* not HAVE_TERMIO */
536 EMACS_SET_TTY (out
, &s
, 0);
545 ioctl (out
, FIOASYNC
, &zero
);
548 #endif /* not MSDOS */
552 #endif /* subprocesses */
558 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
561 /* Record a signal code and the handler for it. */
565 SIGTYPE (*handler
) ();
568 /* Suspend the Emacs process; give terminal to its superior. */
573 /* "Foster" parentage allows emacs to return to a subprocess that attached
574 to the current emacs as a cheaper than starting a whole new process. This
575 is set up by KEPTEDITOR.COM. */
576 unsigned long parent_id
, foster_parent_id
;
579 fpid_string
= getenv ("EMACS_PARENT_PID");
580 if (fpid_string
!= NULL
)
582 sscanf (fpid_string
, "%x", &foster_parent_id
);
583 if (foster_parent_id
!= 0)
584 parent_id
= foster_parent_id
;
586 parent_id
= getppid ();
589 parent_id
= getppid ();
591 xfree (fpid_string
); /* On VMS, this was malloc'd */
593 if (parent_id
&& parent_id
!= 0xffffffff)
595 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
596 int status
= LIB$
ATTACH (&parent_id
) & 1;
597 signal (SIGINT
, oldsig
);
606 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
607 d_prompt
.a
= "Emacs: "; /* Just a reminder */
608 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
613 #if defined(SIGTSTP) && !defined(MSDOS)
616 int pgrp
= EMACS_GETPGRP (0);
617 EMACS_KILLPG (pgrp
, SIGTSTP
);
620 #else /* No SIGTSTP */
621 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
622 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
623 kill (getpid (), SIGQUIT
);
625 #else /* No SIGTSTP or USG_JOBCTRL */
627 /* On a system where suspending is not implemented,
628 instead fork a subshell and let it talk directly to the terminal
632 #endif /* no USG_JOBCTRL */
633 #endif /* no SIGTSTP */
637 /* Fork a subshell. */
642 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
644 char oldwd
[MAXPATHLEN
+1]; /* Fixed length is safe on MSDOS. */
647 struct save_signal saved_handlers
[5];
649 saved_handlers
[0].code
= SIGINT
;
650 saved_handlers
[1].code
= SIGQUIT
;
651 saved_handlers
[2].code
= SIGTERM
;
653 saved_handlers
[3].code
= SIGIO
;
654 saved_handlers
[4].code
= 0;
656 saved_handlers
[3].code
= 0;
660 error ("Can't spawn subshell");
665 #ifdef MSDOS /* MW, Aug 1993 */
668 sh
= (char *) egetenv ("SHELL");
672 /* Use our buffer's default directory for the subshell. */
678 /* mentioning current_buffer->buffer would mean including buffer.h,
679 which somehow wedges the hp compiler. So instead... */
681 dir
= intern ("default-directory");
683 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
685 dir
= Fsymbol_value (dir
);
686 if (XTYPE (dir
) != Lisp_String
)
689 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
690 len
= XSTRING (dir
)->size
;
691 bcopy (XSTRING (dir
)->data
, str
, len
);
692 if (str
[len
- 1] != '/') str
[len
++] = '/';
698 close_process_descs (); /* Close Emacs's pipes/ptys */
701 #ifdef SET_EMACS_PRIORITY
703 extern int emacs_priority
;
705 if (emacs_priority
< 0)
706 nice (-emacs_priority
);
710 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
714 report_file_error ("Can't execute subshell", Fcons (build_string (sh
), Qnil
));
715 #else /* not MSDOS */
717 write (1, "Can't execute subshell", 22);
719 #endif /* not MSDOS */
722 save_signal_handlers (saved_handlers
);
723 synch_process_alive
= 1;
724 wait_for_termination (pid
);
725 restore_signal_handlers (saved_handlers
);
729 save_signal_handlers (saved_handlers
)
730 struct save_signal
*saved_handlers
;
732 while (saved_handlers
->code
)
734 saved_handlers
->handler
735 = (SIGTYPE (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
740 restore_signal_handlers (saved_handlers
)
741 struct save_signal
*saved_handlers
;
743 while (saved_handlers
->code
)
745 signal (saved_handlers
->code
, saved_handlers
->handler
);
757 old_fcntl_flags
= fcntl (input_fd
, F_GETFL
, 0) & ~FASYNC
;
767 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
772 sigunblock (sigmask (SIGWINCH
));
774 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
776 interrupts_deferred
= 0;
782 sigblock (sigmask (SIGWINCH
));
784 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
);
785 interrupts_deferred
= 1;
788 #else /* no FASYNC */
789 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
794 ioctl (input_fd
, FIOASYNC
, &on
);
795 interrupts_deferred
= 0;
802 ioctl (input_fd
, FIOASYNC
, &off
);
803 interrupts_deferred
= 1;
806 #else /* not FASYNC, not STRIDE */
818 sigaddset(&st
, SIGIO
);
819 ioctl (input_fd
, FIOASYNC
, &on
);
820 interrupts_deferred
= 0;
821 sigprocmask(SIG_UNBLOCK
, &st
, (sigset_t
*)0);
828 ioctl (input_fd
, FIOASYNC
, &off
);
829 interrupts_deferred
= 1;
836 croak ("request_sigio");
841 croak ("unrequest_sigio");
849 /* Saving and restoring the process group of Emacs's terminal. */
853 /* The process group of which Emacs was a member when it initially
856 If Emacs was in its own process group (i.e. inherited_pgroup ==
857 getpid ()), then we know we're running under a shell with job
858 control (Emacs would never be run as part of a pipeline).
861 If Emacs was not in its own process group, then we know we're
862 running under a shell (or a caller) that doesn't know how to
863 separate itself from Emacs (like sh). Emacs must be in its own
864 process group in order to receive SIGIO correctly. In this
865 situation, we put ourselves in our own pgroup, forcibly set the
866 tty's pgroup to our pgroup, and make sure to restore and reinstate
867 the tty's pgroup just like any other terminal setting. If
868 inherited_group was not the tty's pgroup, then we'll get a
869 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
870 it goes foreground in the future, which is what should happen. */
871 int inherited_pgroup
;
873 /* Split off the foreground process group to Emacs alone.
874 When we are in the foreground, but not started in our own process
875 group, redirect the TTY to point to our own process group. We need
876 to be in our own process group to receive SIGIO properly. */
877 narrow_foreground_group ()
881 setpgrp (0, inherited_pgroup
);
882 if (inherited_pgroup
!= me
)
883 EMACS_SET_TTY_PGRP (input_fd
, &me
);
887 /* Set the tty to our original foreground group. */
888 widen_foreground_group ()
890 if (inherited_pgroup
!= getpid ())
891 EMACS_SET_TTY_PGRP (input_fd
, &inherited_pgroup
);
892 setpgrp (0, inherited_pgroup
);
895 #endif /* BSD_PGRPS */
897 /* Getting and setting emacs_tty structures. */
899 /* Set *TC to the parameters associated with the terminal FD.
900 Return zero if all's well, or -1 if we ran into an error we
901 couldn't deal with. */
903 emacs_get_tty (fd
, settings
)
905 struct emacs_tty
*settings
;
907 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
909 /* We have those nifty POSIX tcmumbleattr functions. */
910 if (tcgetattr (fd
, &settings
->main
) < 0)
915 /* The SYSV-style interface? */
916 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
921 /* Vehemently Monstrous System? :-) */
922 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
923 &settings
->main
.class, 12, 0, 0, 0, 0)
929 /* I give up - I hope you have the BSD ioctls. */
930 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
932 #endif /* not MSDOS */
937 /* Suivant - Do we have to get struct ltchars data? */
939 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
943 /* How about a struct tchars and a wordful of lmode bits? */
945 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
946 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
950 /* We have survived the tempest. */
955 /* Set the parameters of the tty on FD according to the contents of
956 *SETTINGS. If WAITP is non-zero, we wait for all queued output to
957 be written before making the change; otherwise, we forget any
958 queued input and make the change immediately.
959 Return 0 if all went well, and -1 if anything failed. */
961 emacs_set_tty (fd
, settings
, waitp
)
963 struct emacs_tty
*settings
;
966 /* Set the primary parameters - baud rate, character size, etcetera. */
969 /* We have those nifty POSIX tcmumbleattr functions.
970 William J. Smith <wjs@wiis.wang.com> writes:
971 "POSIX 1003.1 defines tcsetattr() to return success if it was
972 able to perform any of the requested actions, even if some
973 of the requested actions could not be performed.
974 We must read settings back to ensure tty setup properly.
975 AIX requires this to keep tty from hanging occasionally." */
976 /* This make sure that we don't loop indefinitely in here. */
977 for (i
= 0 ; i
< 10 ; i
++)
978 if (tcsetattr (fd
, waitp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
989 /* Get the current settings, and see if they're what we asked for. */
990 tcgetattr (fd
, &new);
991 /* We cannot use memcmp on the whole structure here because under
992 * aix386 the termios structure has some reserved field that may
995 if ( new.c_iflag
== settings
->main
.c_iflag
996 && new.c_oflag
== settings
->main
.c_oflag
997 && new.c_cflag
== settings
->main
.c_cflag
998 && new.c_lflag
== settings
->main
.c_lflag
999 && memcmp(new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
1007 /* The SYSV-style interface? */
1008 if (ioctl (fd
, waitp
? TCSETAW
: TCSETAF
, &settings
->main
) < 0)
1013 /* Vehemently Monstrous System? :-) */
1014 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
1015 &settings
->main
.class, 12, 0, 0, 0, 0)
1021 /* I give up - I hope you have the BSD ioctls. */
1022 if (ioctl (fd
, (waitp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
1024 #endif /* not MSDOS */
1030 /* Suivant - Do we have to get struct ltchars data? */
1032 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
1036 /* How about a struct tchars and a wordful of lmode bits? */
1038 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
1039 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
1043 /* We have survived the tempest. */
1048 /* The initial tty mode bits */
1049 struct emacs_tty old_tty
;
1051 int term_initted
; /* 1 if outer tty status has been recorded */
1054 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1059 #ifndef F_SETOWN_BUG
1061 int old_fcntl_owner
;
1062 #endif /* F_SETOWN */
1063 #endif /* F_SETOWN_BUG */
1065 /* This may also be defined in stdio,
1066 but if so, this does no harm,
1067 and using the same name avoids wasting the other one's space. */
1069 #if defined (USG) || defined (DGUX)
1070 unsigned char _sobuf
[BUFSIZ
+8];
1072 char _sobuf
[BUFSIZ
];
1076 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
1079 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
1084 struct emacs_tty tty
;
1088 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
1089 extern int (*interrupt_signal
) ();
1098 input_ef
= get_kbd_event_flag ();
1099 /* LIB$GET_EF (&input_ef); */
1100 SYS$
CLREF (input_ef
);
1101 waiting_for_ast
= 0;
1103 timer_ef
= get_timer_event_flag ();
1104 /* LIB$GET_EF (&timer_ef); */
1105 SYS$
CLREF (timer_ef
);
1109 LIB$
GET_EF (&process_ef
);
1110 SYS$
CLREF (process_ef
);
1112 if (input_ef
/ 32 != process_ef
/ 32)
1113 croak ("Input and process event flags in different clusters.");
1115 if (input_ef
/ 32 != timer_ef
/ 32)
1116 croak ("Input and timer event flags in different clusters.");
1118 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1119 ((unsigned) 1 << (process_ef
% 32));
1121 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1122 ((unsigned) 1 << (timer_ef
% 32));
1124 sys_access_reinit ();
1126 #endif /* not VMS */
1129 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1130 narrow_foreground_group ();
1133 EMACS_GET_TTY (input_fd
, &old_tty
);
1135 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1139 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1140 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1141 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1143 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1145 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1146 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1148 tty
.main
.c_lflag
&= ~IEXTEN
; /* Disable other editing characters. */
1150 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1153 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1155 tty
.main
.c_iflag
&= ~IXANY
;
1159 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1160 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1162 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1166 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1167 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1170 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1171 /* Set up C-g for both SIGQUIT and SIGINT.
1172 We don't know which we will get, but we handle both alike
1173 so which one it really gives us does not matter. */
1174 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1175 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1176 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1178 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1181 #if defined (mips) || defined (HAVE_TCATTR)
1183 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1186 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1187 #endif /* V_DSUSP */
1188 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1189 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1192 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1195 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1196 #endif /* VREPRINT */
1198 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1199 #endif /* VWERASE */
1201 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1202 #endif /* VDISCARD */
1203 #endif /* mips or HAVE_TCATTR */
1206 /* AIX enhanced edit loses NULs, so disable it */
1207 tty
.main
.c_line
= 0;
1208 tty
.main
.c_iflag
&= ~ASCEDIT
;
1210 tty
.main
.c_cc
[VSTRT
] = 255;
1211 tty
.main
.c_cc
[VSTOP
] = 255;
1212 tty
.main
.c_cc
[VSUSP
] = 255;
1213 tty
.main
.c_cc
[VDSUSP
] = 255;
1214 #endif /* IBMR2AIX */
1215 /* Also, PTY overloads NUL and BREAK.
1216 don't ignore break, but don't signal either, so it looks like NUL.
1217 This really serves a purpose only if running in an XTERM window
1218 or via TELNET or the like, but does no harm elsewhere. */
1219 tty
.main
.c_iflag
&= ~IGNBRK
;
1220 tty
.main
.c_iflag
&= ~BRKINT
;
1222 #else /* if not HAVE_TERMIO */
1224 tty
.main
.tt_char
|= TT$M_NOECHO
;
1226 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1228 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1230 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1231 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1232 #else /* not VMS (BSD, that is) */
1234 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1236 tty
.main
.sg_flags
|= ANYP
;
1237 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1239 #endif /* not VMS (BSD, that is) */
1240 #endif /* not HAVE_TERMIO */
1242 /* If going to use CBREAK mode, we must request C-g to interrupt
1243 and turn off start and stop chars, etc. If not going to use
1244 CBREAK mode, do this anyway so as to turn off local flow
1245 control for user coming over network on 4.2; in this case,
1246 only t_stopc and t_startc really matter. */
1249 /* Note: if not using CBREAK mode, it makes no difference how we
1251 tty
.tchars
= new_tchars
;
1252 tty
.tchars
.t_intrc
= quit_char
;
1255 tty
.tchars
.t_startc
= '\021';
1256 tty
.tchars
.t_stopc
= '\023';
1259 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1261 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1262 anything, and leaving it in breaks the meta key. Go figure. */
1263 tty
.lmode
&= ~LLITOUT
;
1270 #endif /* HAVE_TCHARS */
1271 #endif /* not HAVE_TERMIO */
1274 tty
.ltchars
= new_ltchars
;
1275 #endif /* HAVE_LTCHARS */
1276 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1277 internal_terminal_init ();
1281 EMACS_SET_TTY (input_fd
, &tty
, 0);
1283 /* This code added to insure that, if flow-control is not to be used,
1284 we have an unlocked terminal at the start. */
1287 if (!flow_control
) ioctl (input_fd
, TCXONC
, 1);
1291 if (!flow_control
) ioctl (input_fd
, TIOCSTART
, 0);
1299 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1300 to be only LF. This is the way that is done. */
1303 if (ioctl (1, HFTGETID
, &tty
) != -1)
1304 write (1, "\033[20l", 5);
1310 /* Appears to do nothing when in PASTHRU mode.
1311 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1312 interrupt_signal, oob_chars, 0, 0, 0, 0);
1314 queue_kbd_input (0);
1319 #ifndef F_SETOWN_BUG
1320 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1322 && ! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1324 old_fcntl_owner
= fcntl (input_fd
, F_GETOWN
, 0);
1325 fcntl (input_fd
, F_SETOWN
, getpid ());
1328 #endif /* F_GETOWN */
1329 #endif /* F_SETOWN_BUG */
1330 #endif /* F_SETFL */
1333 if (interrupt_input
)
1337 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1341 /* This symbol is defined on recent USG systems.
1342 Someone says without this call USG won't really buffer the file
1343 even with a call to setbuf. */
1344 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1346 setbuf (stdout
, _sobuf
);
1348 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1349 set_terminal_modes ();
1351 if (term_initted
&& no_redraw_on_reenter
)
1353 if (display_completed
)
1354 direct_output_forward_char (0);
1360 if (FRAMEP (Vterminal_frame
))
1361 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1368 /* Return nonzero if safe to use tabs in output.
1369 At the time this is called, init_sys_modes has not been done yet. */
1373 struct emacs_tty tty
;
1375 EMACS_GET_TTY (input_fd
, &tty
);
1376 return EMACS_TTY_TABS_OK (&tty
);
1379 /* Get terminal size from system.
1380 Store number of lines into *HEIGHTP and width into *WIDTHP.
1381 We store 0 if there's no valid information. */
1383 get_frame_size (widthp
, heightp
)
1384 int *widthp
, *heightp
;
1390 struct winsize size
;
1392 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1393 *widthp
= *heightp
= 0;
1396 *widthp
= size
.ws_col
;
1397 *heightp
= size
.ws_row
;
1403 /* SunOS - style. */
1404 struct ttysize size
;
1406 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1407 *widthp
= *heightp
= 0;
1410 *widthp
= size
.ts_cols
;
1411 *heightp
= size
.ts_lines
;
1417 struct sensemode tty
;
1419 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1420 &tty
.class, 12, 0, 0, 0, 0);
1421 *widthp
= tty
.scr_wid
;
1422 *heightp
= tty
.scr_len
;
1426 *widthp
= ScreenCols ();
1427 *heightp
= ScreenRows ();
1428 #else /* system doesn't know size */
1433 #endif /* not VMS */
1434 #endif /* not SunOS-style */
1435 #endif /* not BSD-style */
1438 /* Set the logical window size associated with descriptor FD
1439 to HEIGHT and WIDTH. This is used mainly with ptys. */
1442 set_window_size (fd
, height
, width
)
1443 int fd
, height
, width
;
1448 struct winsize size
;
1449 size
.ws_row
= height
;
1450 size
.ws_col
= width
;
1452 if (ioctl (fd
, TIOCSWINSZ
, &size
) == -1)
1453 return 0; /* error */
1460 /* SunOS - style. */
1461 struct ttysize size
;
1462 size
.ts_lines
= height
;
1463 size
.ts_cols
= width
;
1465 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1471 #endif /* not SunOS-style */
1472 #endif /* not BSD-style */
1476 /* Prepare the terminal for exiting Emacs; move the cursor to the
1477 bottom of the frame, turn off interrupt-driven I/O, etc. */
1487 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1489 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1490 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1491 /* clear_end_of_line may move the cursor */
1492 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1495 /* HFT devices normally use ^J as a LF/CR. We forced it to
1496 do the LF only. Now, we need to reset it. */
1499 if (ioctl (1, HFTGETID
, &tty
) != -1)
1500 write (1, "\033[20h", 5);
1504 reset_terminal_modes ();
1508 /* Avoid possible loss of output when changing terminal modes. */
1509 fsync (fileno (stdout
));
1514 #ifndef F_SETOWN_BUG
1515 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1516 if (interrupt_input
)
1519 fcntl (input_fd
, F_SETOWN
, old_fcntl_owner
);
1521 #endif /* F_SETOWN */
1522 #endif /* F_SETOWN_BUG */
1524 fcntl (input_fd
, F_SETFL
, fcntl (input_fd
, F_GETFL
, 0) & ~O_NDELAY
);
1526 #endif /* F_SETFL */
1528 if (interrupt_input
)
1532 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1535 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1544 widen_foreground_group ();
1550 /* Set up the proper status flags for use of a pty. */
1555 /* I'm told that TOICREMOTE does not mean control chars
1556 "can't be sent" but rather that they don't have
1557 input-editing or signaling effects.
1558 That should be good, because we have other ways
1559 to do those things in Emacs.
1560 However, telnet mode seems not to work on 4.2.
1561 So TIOCREMOTE is turned off now. */
1563 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1564 will hang. In particular, the "timeout" feature (which
1565 causes a read to return if there is no data available)
1566 does this. Also it is known that telnet mode will hang
1567 in such a way that Emacs must be stopped (perhaps this
1568 is the same problem).
1570 If TIOCREMOTE is turned off, then there is a bug in
1571 hp-ux which sometimes loses data. Apparently the
1572 code which blocks the master process when the internal
1573 buffer fills up does not work. Other than this,
1574 though, everything else seems to work fine.
1576 Since the latter lossage is more benign, we may as well
1577 lose that way. -- cph */
1582 ioctl (fd
, FIONBIO
, &on
);
1587 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1588 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1589 /* cause EMACS not to die when it should, i.e., when its own controlling */
1590 /* tty goes away. I've complained to the AIX developers, and they may */
1591 /* change this behavior, but I'm not going to hold my breath. */
1592 signal (SIGHUP
, SIG_IGN
);
1595 #endif /* HAVE_PTYS */
1599 /* Assigning an input channel is done at the start of Emacs execution.
1600 This is called each time Emacs is resumed, also, but does nothing
1601 because input_chain is no longer zero. */
1609 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1615 /* Deassigning the input channel is done before exiting. */
1619 return SYS$
DASSGN (input_fd
);
1624 /* Request reading one character into the keyboard buffer.
1625 This is done as soon as the buffer becomes empty. */
1630 extern kbd_input_ast ();
1632 waiting_for_ast
= 0;
1634 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1635 &input_iosb
, kbd_input_ast
, 1,
1636 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1641 /* Ast routine that is called when keyboard input comes in
1642 in accord with the SYS$QIO above. */
1646 register int c
= -1;
1647 int old_errno
= errno
;
1648 extern EMACS_TIME
*input_available_clear_time
;
1650 if (waiting_for_ast
)
1651 SYS$
SETEF (input_ef
);
1652 waiting_for_ast
= 0;
1655 if (input_count
== 25)
1657 printf ("Ast # %d,", input_count
);
1658 printf (" iosb = %x, %x, %x, %x",
1659 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1662 if (input_iosb
.offset
)
1666 printf (", char = 0%o", c
);
1678 struct input_event e
;
1679 e
.kind
= ascii_keystroke
;
1680 XSET (e
.code
, Lisp_Int
, c
);
1682 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1684 e
.frame_or_window
= Qnil
;
1686 kbd_buffer_store_event (&e
);
1688 if (input_available_clear_time
)
1689 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1693 /* Wait until there is something in kbd_buffer. */
1695 wait_for_kbd_input ()
1697 extern int have_process_input
, process_exited
;
1699 /* If already something, avoid doing system calls. */
1700 if (detect_input_pending ())
1704 /* Clear a flag, and tell ast routine above to set it. */
1705 SYS$
CLREF (input_ef
);
1706 waiting_for_ast
= 1;
1707 /* Check for timing error: ast happened while we were doing that. */
1708 if (!detect_input_pending ())
1710 /* No timing error: wait for flag to be set. */
1711 set_waiting_for_input (0);
1712 SYS$
WFLOR (input_ef
, input_eflist
);
1713 clear_waiting_for_input (0);
1714 if (!detect_input_pending ())
1715 /* Check for subprocess input availability */
1717 int dsp
= have_process_input
|| process_exited
;
1719 SYS$
CLREF (process_ef
);
1720 if (have_process_input
)
1721 process_command_input ();
1726 update_mode_lines
++;
1727 prepare_menu_bars ();
1728 redisplay_preserve_echo_area ();
1732 waiting_for_ast
= 0;
1735 /* Get rid of any pending QIO, when we are about to suspend
1736 or when we want to throw away pending input.
1737 We wait for a positive sign that the AST routine has run
1738 and therefore there is no I/O request queued when we return.
1739 SYS$SETAST is used to avoid a timing error. */
1744 printf ("At end_kbd_input.\n");
1748 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1750 SYS$
CANCEL (input_fd
);
1755 /* Clear a flag, and tell ast routine above to set it. */
1756 SYS$
CLREF (input_ef
);
1757 waiting_for_ast
= 1;
1759 SYS$
CANCEL (input_fd
);
1761 SYS$
WAITFR (input_ef
);
1762 waiting_for_ast
= 0;
1765 /* Wait for either input available or time interval expiry. */
1767 input_wait_timeout (timeval
)
1768 int timeval
; /* Time to wait, in seconds */
1771 static int zero
= 0;
1772 static int large
= -10000000;
1774 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1776 /* If already something, avoid doing system calls. */
1777 if (detect_input_pending ())
1781 /* Clear a flag, and tell ast routine above to set it. */
1782 SYS$
CLREF (input_ef
);
1783 waiting_for_ast
= 1;
1784 /* Check for timing error: ast happened while we were doing that. */
1785 if (!detect_input_pending ())
1787 /* No timing error: wait for flag to be set. */
1789 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1790 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1792 waiting_for_ast
= 0;
1795 /* The standard `sleep' routine works some other way
1796 and it stops working if you have ever quit out of it.
1797 This one continues to work. */
1803 static int zero
= 0;
1804 static int large
= -10000000;
1806 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1809 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1810 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1825 croak ("request sigio");
1830 croak ("unrequest sigio");
1835 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1840 #ifndef SYSTEM_MALLOC
1847 /* Some systems that cannot dump also cannot implement these. */
1850 * Return the address of the start of the text segment prior to
1851 * doing an unexec. After unexec the return value is undefined.
1852 * See crt0.c for further explanation and _start.
1856 #if !defined (CANNOT_UNEXEC) && !defined (HAVE_TEXT_START)
1861 return ((char *) TEXT_START
);
1865 return ((char *) csrt
);
1866 #else /* not GOULD */
1867 extern int _start ();
1868 return ((char *) _start
);
1870 #endif /* TEXT_START */
1872 #endif /* not CANNOT_UNEXEC and not HAVE_TEXT_START */
1875 * Return the address of the start of the data segment prior to
1876 * doing an unexec. After unexec the return value is undefined.
1877 * See crt0.c for further information and definition of data_start.
1879 * Apparently, on BSD systems this is etext at startup. On
1880 * USG systems (swapping) this is highly mmu dependent and
1881 * is also dependent on whether or not the program is running
1882 * with shared text. Generally there is a (possibly large)
1883 * gap between end of text and start of data with shared text.
1885 * On Uniplus+ systems with shared text, data starts at a
1886 * fixed address. Each port (from a given oem) is generally
1887 * different, and the specific value of the start of data can
1888 * be obtained via the UniPlus+ specific "uvar" system call,
1889 * however the method outlined in crt0.c seems to be more portable.
1891 * Probably what will have to happen when a USG unexec is available,
1892 * at least on UniPlus, is temacs will have to be made unshared so
1893 * that text and data are contiguous. Then once loadup is complete,
1894 * unexec will produce a shared executable where the data can be
1895 * at the normal shared text boundry and the startofdata variable
1896 * will be patched by unexec to the correct value.
1904 return ((char *) DATA_START
);
1906 #ifdef ORDINARY_LINK
1908 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1909 * data_start isn't defined. We take the address of environ, which
1910 * is known to live at or near the start of the system crt0.c, and
1911 * we don't sweat the handful of bytes that might lose.
1913 extern char **environ
;
1915 return((char *) &environ
);
1917 extern int data_start
;
1918 return ((char *) &data_start
);
1919 #endif /* ORDINARY_LINK */
1920 #endif /* DATA_START */
1922 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1925 /* Some systems that cannot dump also cannot implement these. */
1928 * Return the address of the end of the text segment prior to
1929 * doing an unexec. After unexec the return value is undefined.
1936 return ((char *) TEXT_END
);
1939 return ((char *) &etext
);
1944 * Return the address of the end of the data segment prior to
1945 * doing an unexec. After unexec the return value is undefined.
1952 return ((char *) DATA_END
);
1955 return ((char *) &edata
);
1959 #endif /* not CANNOT_DUMP */
1961 /* init_system_name sets up the string for the Lisp function
1962 system-name to return. */
1968 extern Lisp_Object Vsystem_name
;
1973 #include <sys/socket.h>
1975 #endif /* HAVE_SOCKETS */
1976 #endif /* not VMS */
1977 #endif /* not BSD4_1 */
1983 Vsystem_name
= build_string (sysname
);
1987 if ((sp
= egetenv ("SYS$NODE")) == 0)
1988 Vsystem_name
= build_string ("vax-vms");
1989 else if ((end
= index (sp
, ':')) == 0)
1990 Vsystem_name
= build_string (sp
);
1992 Vsystem_name
= make_string (sp
, end
- sp
);
1994 #ifndef HAVE_GETHOSTNAME
1997 Vsystem_name
= build_string (uts
.nodename
);
1998 #else /* HAVE_GETHOSTNAME */
1999 int hostname_size
= 256;
2000 char *hostname
= (char *) alloca (hostname_size
);
2002 /* Try to get the host name; if the buffer is too short, try
2003 again. Apparently, the only indication gethostname gives of
2004 whether the buffer was large enough is the presence or absence
2005 of a '\0' in the string. Eech. */
2008 gethostname (hostname
, hostname_size
- 1);
2009 hostname
[hostname_size
- 1] = '\0';
2011 /* Was the buffer large enough for the '\0'? */
2012 if (strlen (hostname
) < hostname_size
- 1)
2015 hostname_size
<<= 1;
2016 hostname
= (char *) alloca (hostname_size
);
2019 /* Turn the hostname into the official, fully-qualified hostname.
2020 Don't do this if we're going to dump; this can confuse system
2021 libraries on some machines and make the dumped emacs core dump. */
2024 #endif /* not CANNOT_DUMP */
2026 struct hostent
*hp
= gethostbyname (hostname
);
2029 char *fqdn
= hp
->h_name
;
2032 if (!index (fqdn
, '.'))
2034 /* We still don't have a fully qualified domain name.
2035 Try to find one in the list of alternate names */
2036 char **alias
= hp
->h_aliases
;
2037 while (*alias
&& !index (*alias
, '.'))
2044 /* Convert the host name to lower case. */
2045 /* Using ctype.h here would introduce a possible locale
2046 dependence that is probably wrong for hostnames. */
2050 if (*p
>= 'A' && *p
<= 'Z')
2057 #endif /* HAVE_SOCKETS */
2058 Vsystem_name
= build_string (hostname
);
2059 #endif /* HAVE_GETHOSTNAME */
2064 for (p
= XSTRING (Vsystem_name
)->data
; *p
; p
++)
2065 if (*p
== ' ' || *p
== '\t')
2073 #ifdef HAVE_X_WINDOWS
2074 /* Cause explanatory error message at compile time,
2075 since the select emulation is not good enough for X. */
2076 int *x
= &x_windows_lose_if_no_select_system_call
;
2079 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2080 * Only checks read descriptors.
2082 /* How long to wait between checking fds in select */
2083 #define SELECT_PAUSE 1
2086 /* For longjmp'ing back to read_input_waiting. */
2088 jmp_buf read_alarm_throw
;
2090 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2091 The read_socket_hook function sets this to 1 while it is waiting. */
2093 int read_alarm_should_throw
;
2101 #else /* not BSD4_1 */
2102 signal (SIGALRM
, SIG_IGN
);
2103 #endif /* not BSD4_1 */
2104 if (read_alarm_should_throw
)
2105 longjmp (read_alarm_throw
, 1);
2108 /* Only rfds are checked. */
2110 select (nfds
, rfds
, wfds
, efds
, timeout
)
2112 int *rfds
, *wfds
, *efds
, *timeout
;
2114 int ravail
= 0, orfds
= 0, old_alarm
;
2115 int timeoutval
= timeout
? *timeout
: 100000;
2116 int *local_timeout
= &timeoutval
;
2117 extern int proc_buffered_char
[];
2118 #ifndef subprocesses
2119 int process_tick
= 0, update_tick
= 0;
2121 extern int process_tick
, update_tick
;
2123 SIGTYPE (*old_trap
) ();
2136 /* If we are looking only for the terminal, with no timeout,
2137 just read it and wait -- that's more efficient. */
2138 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
2140 if (! detect_input_pending ())
2141 read_input_waiting ();
2146 /* Once a second, till the timer expires, check all the flagged read
2147 * descriptors to see if any input is available. If there is some then
2148 * set the corresponding bit in the return copy of rfds.
2152 register int to_check
, bit
, fd
;
2156 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
2160 int avail
= 0, status
= 0;
2163 avail
= detect_input_pending (); /* Special keyboard handler */
2167 status
= ioctl (fd
, FIONREAD
, &avail
);
2168 #else /* no FIONREAD */
2170 abort (); /* I don't think we need it. */
2171 #else /* not MSDOS */
2172 /* Hoping it will return -1 if nothing available
2173 or 0 if all 0 chars requested are read. */
2174 if (proc_buffered_char
[fd
] >= 0)
2178 avail
= read (fd
, &buf
, 1);
2180 proc_buffered_char
[fd
] = buf
;
2182 #endif /* not MSDOS */
2183 #endif /* no FIONREAD */
2185 if (status
>= 0 && avail
> 0)
2193 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2195 old_alarm
= alarm (0);
2196 old_trap
= signal (SIGALRM
, select_alarm
);
2198 alarm (SELECT_PAUSE
);
2199 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2200 while (select_alarmed
== 0 && *local_timeout
!= 0
2201 && process_tick
== update_tick
)
2204 sleep_or_kbd_hit (SELECT_PAUSE
, (orfds
& 1) != 0);
2206 #else /* not MSDOS */
2207 /* If we are interested in terminal input,
2208 wait by reading the terminal.
2209 That makes instant wakeup for terminal input at least. */
2212 read_input_waiting ();
2213 if (detect_input_pending ())
2218 #endif /* not MSDOS */
2220 (*local_timeout
) -= SELECT_PAUSE
;
2221 /* Reset the old alarm if there was one */
2223 signal (SIGALRM
, old_trap
);
2226 /* Reset or forge an interrupt for the original handler. */
2227 old_alarm
-= SELECT_PAUSE
;
2229 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
2233 if (*local_timeout
== 0) /* Stop on timer being cleared */
2239 /* Read keyboard input into the standard buffer,
2240 waiting for at least one character. */
2242 /* Make all keyboard buffers much bigger when using X windows. */
2243 #ifdef HAVE_X_WINDOWS
2244 #define BUFFER_SIZE_FACTOR 16
2246 #define BUFFER_SIZE_FACTOR 1
2249 read_input_waiting ()
2251 struct input_event e
;
2253 extern int quit_char
;
2255 if (read_socket_hook
)
2257 struct input_event buf
[256];
2259 read_alarm_should_throw
= 0;
2260 if (! setjmp (read_alarm_throw
))
2261 nread
= (*read_socket_hook
) (0, buf
, 256, 1, 0);
2265 /* Scan the chars for C-g and store them in kbd_buffer. */
2266 for (i
= 0; i
< nread
; i
++)
2268 kbd_buffer_store_event (&buf
[i
]);
2269 /* Don't look at input that follows a C-g too closely.
2270 This reduces lossage due to autorepeat on C-g. */
2271 if (buf
[i
].kind
== ascii_keystroke
2272 && XINT(buf
[i
].code
) == quit_char
)
2279 nread
= read (fileno (stdin
), buf
, 1);
2281 /* Scan the chars for C-g and store them in kbd_buffer. */
2282 e
.kind
= ascii_keystroke
;
2283 e
.frame_or_window
= selected_frame
;
2285 for (i
= 0; i
< nread
; i
++)
2287 /* Convert chars > 0177 to meta events if desired.
2288 We do this under the same conditions that read_avail_input does. */
2289 if (read_socket_hook
== 0)
2291 /* If the user says she has a meta key, then believe her. */
2292 if (meta_key
== 1 && (buf
[i
] & 0x80))
2293 e
.modifiers
= meta_modifier
;
2298 XSET (e
.code
, Lisp_Int
, buf
[i
]);
2299 kbd_buffer_store_event (&e
);
2300 /* Don't look at input that follows a C-g too closely.
2301 This reduces lossage due to autorepeat on C-g. */
2302 if (buf
[i
] == quit_char
)
2308 #endif /* not HAVE_SELECT */
2309 #endif /* not VMS */
2313 * Partially emulate 4.2 open call.
2314 * open is defined as this in 4.1.
2316 * - added by Michael Bloom @ Citicorp/TTI
2321 sys_open (path
, oflag
, mode
)
2325 if (oflag
& O_CREAT
)
2326 return creat (path
, mode
);
2328 return open (path
, oflag
);
2335 lmode
= LINTRUP
| lmode
;
2336 ioctl (0, TIOCLSET
, &lmode
);
2343 lmode
= ~LINTRUP
& lmode
;
2344 ioctl (0, TIOCLSET
, &lmode
);
2351 interrupts_deferred
= 0;
2358 interrupts_deferred
= 1;
2361 /* still inside #ifdef BSD4_1 */
2364 int sigheld
; /* Mask of held signals */
2369 sigheld
|= sigbit (signum
);
2376 sigheld
|= sigbit (signum
);
2382 sigheld
&= ~sigbit (signum
);
2386 sigfree () /* Free all held signals */
2389 for (i
= 0; i
< NSIG
; i
++)
2390 if (sigheld
& sigbit (i
))
2397 return 1 << (i
- 1);
2399 #endif /* subprocesses */
2402 /* POSIX signals support - DJB */
2403 /* Anyone with POSIX signals should have ANSI C declarations */
2405 #ifdef POSIX_SIGNALS
2407 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
2408 static struct sigaction new_action
, old_action
;
2412 sigemptyset (&empty_mask
);
2413 sigfillset (&full_mask
);
2417 sys_signal (int signal_number
, signal_handler_t action
)
2420 /* This gets us restartable system calls for efficiency.
2421 The "else" code will works as well. */
2422 return (berk_signal (signal_number
, action
));
2424 sigemptyset (&new_action
.sa_mask
);
2425 new_action
.sa_handler
= action
;
2427 /* Emacs mostly works better with restartable system services. If this
2428 * flag exists, we probably want to turn it on here.
2430 new_action
.sa_flags
= SA_RESTART
;
2432 new_action
.sa_flags
= 0;
2434 sigaction (signal_number
, &new_action
, &old_action
);
2435 return (old_action
.sa_handler
);
2440 /* If we're compiling with GCC, we don't need this function, since it
2441 can be written as a macro. */
2443 sys_sigmask (int sig
)
2446 sigemptyset (&mask
);
2447 sigaddset (&mask
, sig
);
2453 sys_sigpause (sigset_t new_mask
)
2455 /* pause emulating berk sigpause... */
2456 sigsuspend (&new_mask
);
2460 /* I'd like to have these guys return pointers to the mask storage in here,
2461 but there'd be trouble if the code was saving multiple masks. I'll be
2462 safe and pass the structure. It normally won't be more than 2 bytes
2466 sys_sigblock (sigset_t new_mask
)
2469 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2474 sys_sigunblock (sigset_t new_mask
)
2477 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2482 sys_sigsetmask (sigset_t new_mask
)
2485 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2489 #endif /* POSIX_SIGNALS */
2498 register int length
;
2502 long max_str
= 65535;
2504 while (length
> max_str
) {
2505 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2510 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2512 while (length
-- > 0)
2514 #endif /* not VMS */
2517 #endif /* no bzero */
2520 /* Saying `void' requires a declaration, above, where bcopy is used
2521 and that declaration causes pain for systems where bcopy is a macro. */
2522 bcopy (b1
, b2
, length
)
2525 register int length
;
2528 long max_str
= 65535;
2530 while (length
> max_str
) {
2531 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2537 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2539 while (length
-- > 0)
2541 #endif /* not VMS */
2543 #endif /* no bcopy */
2547 bcmp (b1
, b2
, length
) /* This could be a macro! */
2550 register int length
;
2553 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2554 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2556 return STR$
COMPARE (&src1
, &src2
);
2558 while (length
-- > 0)
2563 #endif /* not VMS */
2565 #endif /* no bcmp */
2567 #endif /* not BSTRING */
2572 * The BSD random returns numbers in the range of
2573 * 0 to 2e31 - 1. The USG rand returns numbers in the
2574 * range of 0 to 2e15 - 1. This is probably not significant
2581 /* Arrange to return a range centered on zero. */
2582 return (rand () << 15) + rand () - (1 << 29);
2596 /* Arrange to return a range centered on zero. */
2597 return (rand () << 15) + rand () - (1 << 29);
2608 #ifdef WRONG_NAME_INSQUE
2621 /* If any place else asks for the TERM variable,
2622 allow it to be overridden with the EMACS_TERM variable
2623 before attempting to translate the logical name TERM. As a last
2624 resort, ask for VAX C's special idea of the TERM variable. */
2631 static char buf
[256];
2632 static struct dsc$descriptor_s equiv
2633 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2634 static struct dsc$descriptor_s d_name
2635 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2638 if (!strcmp (name
, "TERM"))
2640 val
= (char *) getenv ("EMACS_TERM");
2645 d_name
.dsc$w_length
= strlen (name
);
2646 d_name
.dsc$a_pointer
= name
;
2647 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2649 char *str
= (char *) xmalloc (eqlen
+ 1);
2650 bcopy (buf
, str
, eqlen
);
2652 /* This is a storage leak, but a pain to fix. With luck,
2653 no one will ever notice. */
2656 return (char *) getenv (name
);
2661 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2662 to force a call on the debugger from within the image. */
2667 LIB$
SIGNAL (SS$_DEBUG
);
2673 #ifdef LINK_CRTL_SHARE
2674 #ifdef SHAREABLE_LIB_BUG
2675 /* Variables declared noshare and initialized in sharable libraries
2676 cannot be shared. The VMS linker incorrectly forces you to use a private
2677 version which is uninitialized... If not for this "feature", we
2678 could use the C library definition of sys_nerr and sys_errlist. */
2680 char *sys_errlist
[] =
2684 "no such file or directory",
2686 "interrupted system call",
2688 "no such device or address",
2689 "argument list too long",
2690 "exec format error",
2693 "no more processes",
2694 "not enough memory",
2695 "permission denied",
2697 "block device required",
2698 "mount devices busy",
2700 "cross-device link",
2705 "file table overflow",
2706 "too many open files",
2710 "no space left on device",
2712 "read-only file system",
2718 "vax/vms specific error code nontranslatable error"
2720 #endif /* SHAREABLE_LIB_BUG */
2721 #endif /* LINK_CRTL_SHARE */
2724 #ifndef HAVE_STRERROR
2729 extern char *sys_errlist
[];
2730 extern int sys_nerr
;
2732 if (errnum
>= 0 && errnum
< sys_nerr
)
2733 return sys_errlist
[errnum
];
2734 return (char *) "Unknown error";
2737 #endif /* ! HAVE_STRERROR */
2739 #ifdef INTERRUPTIBLE_OPEN
2743 sys_open (path
, oflag
, mode
)
2747 register int rtnval
;
2749 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2750 && (errno
== EINTR
));
2754 #endif /* INTERRUPTIBLE_OPEN */
2756 #ifdef INTERRUPTIBLE_CLOSE
2761 register int rtnval
;
2763 while ((rtnval
= close (fd
)) == -1
2764 && (errno
== EINTR
));
2768 #endif /* INTERRUPTIBLE_CLOSE */
2770 #ifdef INTERRUPTIBLE_IO
2773 sys_read (fildes
, buf
, nbyte
)
2778 register int rtnval
;
2780 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2781 && (errno
== EINTR
));
2786 sys_write (fildes
, buf
, nbyte
)
2791 register int rtnval
, bytes_written
;
2797 rtnval
= write (fildes
, buf
, nbyte
);
2804 return (bytes_written
? bytes_written
: -1);
2809 bytes_written
+= rtnval
;
2811 return (bytes_written
);
2814 #endif /* INTERRUPTIBLE_IO */
2819 * Substitute fork for vfork on USG flavors.
2827 #endif /* not HAVE_VFORK */
2831 * All of the following are for USG.
2833 * On USG systems the system calls are INTERRUPTIBLE by signals
2834 * that the user program has elected to catch. Thus the system call
2835 * must be retried in these cases. To handle this without massive
2836 * changes in the source code, we remap the standard system call names
2837 * to names for our own functions in sysdep.c that do the system call
2838 * with retries. Actually, for portability reasons, it is good
2839 * programming practice, as this example shows, to limit all actual
2840 * system calls to a single occurrence in the source. Sure, this
2841 * adds an extra level of function call overhead but it is almost
2842 * always negligible. Fred Fish, Unisoft Systems Inc.
2845 #ifndef HAVE_SYS_SIGLIST
2846 char *sys_siglist
[NSIG
+ 1] =
2849 /* AIX has changed the signals a bit */
2850 "bogus signal", /* 0 */
2851 "hangup", /* 1 SIGHUP */
2852 "interrupt", /* 2 SIGINT */
2853 "quit", /* 3 SIGQUIT */
2854 "illegal instruction", /* 4 SIGILL */
2855 "trace trap", /* 5 SIGTRAP */
2856 "IOT instruction", /* 6 SIGIOT */
2857 "crash likely", /* 7 SIGDANGER */
2858 "floating point exception", /* 8 SIGFPE */
2859 "kill", /* 9 SIGKILL */
2860 "bus error", /* 10 SIGBUS */
2861 "segmentation violation", /* 11 SIGSEGV */
2862 "bad argument to system call", /* 12 SIGSYS */
2863 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2864 "alarm clock", /* 14 SIGALRM */
2865 "software termination signum", /* 15 SIGTERM */
2866 "user defined signal 1", /* 16 SIGUSR1 */
2867 "user defined signal 2", /* 17 SIGUSR2 */
2868 "death of a child", /* 18 SIGCLD */
2869 "power-fail restart", /* 19 SIGPWR */
2870 "bogus signal", /* 20 */
2871 "bogus signal", /* 21 */
2872 "bogus signal", /* 22 */
2873 "bogus signal", /* 23 */
2874 "bogus signal", /* 24 */
2875 "LAN I/O interrupt", /* 25 SIGAIO */
2876 "PTY I/O interrupt", /* 26 SIGPTY */
2877 "I/O intervention required", /* 27 SIGIOINT */
2878 "HFT grant", /* 28 SIGGRANT */
2879 "HFT retract", /* 29 SIGRETRACT */
2880 "HFT sound done", /* 30 SIGSOUND */
2881 "HFT input ready", /* 31 SIGMSG */
2883 "bogus signal", /* 0 */
2884 "hangup", /* 1 SIGHUP */
2885 "interrupt", /* 2 SIGINT */
2886 "quit", /* 3 SIGQUIT */
2887 "illegal instruction", /* 4 SIGILL */
2888 "trace trap", /* 5 SIGTRAP */
2889 "IOT instruction", /* 6 SIGIOT */
2890 "EMT instruction", /* 7 SIGEMT */
2891 "floating point exception", /* 8 SIGFPE */
2892 "kill", /* 9 SIGKILL */
2893 "bus error", /* 10 SIGBUS */
2894 "segmentation violation", /* 11 SIGSEGV */
2895 "bad argument to system call", /* 12 SIGSYS */
2896 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2897 "alarm clock", /* 14 SIGALRM */
2898 "software termination signum", /* 15 SIGTERM */
2899 "user defined signal 1", /* 16 SIGUSR1 */
2900 "user defined signal 2", /* 17 SIGUSR2 */
2901 "death of a child", /* 18 SIGCLD */
2902 "power-fail restart", /* 19 SIGPWR */
2904 "window size change", /* 20 SIGWINCH */
2905 "urgent socket condition", /* 21 SIGURG */
2906 "pollable event occured", /* 22 SIGPOLL */
2907 "stop (cannot be caught or ignored)", /* 23 SIGSTOP */
2908 "user stop requested from tty", /* 24 SIGTSTP */
2909 "stopped process has been continued", /* 25 SIGCONT */
2910 "background tty read attempted", /* 26 SIGTTIN */
2911 "background tty write attempted", /* 27 SIGTTOU */
2912 "virtual timer expired", /* 28 SIGVTALRM */
2913 "profiling timer expired", /* 29 SIGPROF */
2914 "exceeded cpu limit", /* 30 SIGXCPU */
2915 "exceeded file size limit", /* 31 SIGXFSZ */
2916 "process's lwps are blocked", /* 32 SIGWAITING */
2917 "special signal used by thread library", /* 33 SIGLWP */
2919 "Special Signal Used By CPR", /* 34 SIGFREEZE */
2922 "Special Signal Used By CPR", /* 35 SIGTHAW */
2925 #endif /* not AIX */
2928 #endif /* HAVE_SYS_SIGLIST */
2931 * Warning, this function may not duplicate 4.2 action properly
2932 * under error conditions.
2936 /* In 4.1, param.h fails to define this. */
2937 #define MAXPATHLEN 1024
2946 char *npath
, *spath
;
2947 extern char *getcwd ();
2949 BLOCK_INPUT
; /* getcwd uses malloc */
2950 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2953 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2954 up to first slash. Should be harmless on other systems. */
2955 while (*npath
&& *npath
!= '/')
2957 strcpy (pathname
, npath
);
2958 free (spath
); /* getcwd uses malloc */
2963 #endif /* HAVE_GETWD */
2966 * Emulate rename using unlink/link. Note that this is
2967 * only partially correct. Also, doesn't enforce restriction
2968 * that files be of same type (regular->regular, dir->dir, etc).
2977 if (access (from
, 0) == 0)
2980 if (link (from
, to
) == 0)
2981 if (unlink (from
) == 0)
2989 #ifdef MISSING_UTIMES
2991 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
3000 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
3001 utimbuf structure defined anywhere but in the man page. */
3011 struct timeval tvp
[];
3014 utb
.actime
= tvp
[0].tv_sec
;
3015 utb
.modtime
= tvp
[1].tv_sec
;
3018 #endif /* IRIS_UTIME */
3024 /* HPUX curses library references perror, but as far as we know
3025 it won't be called. Anyway this definition will do for now. */
3031 #endif /* not HAVE_PERROR */
3037 * Emulate BSD dup2. First close newd if it already exists.
3038 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3039 * until we are, then close the unsuccessful ones.
3046 register int fd
, ret
;
3051 fd
= fcntl (oldd
, F_DUPFD
, newd
);
3053 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, strerror (errno
));
3060 ret
= dup2 (old
,new);
3066 #endif /* not HAVE_DUP2 */
3069 * Gettimeofday. Simulate as much as possible. Only accurate
3070 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3071 * Only needed when subprocesses are defined.
3076 #ifndef HAVE_GETTIMEOFDAY
3080 gettimeofday (tp
, tzp
)
3082 struct timezone
*tzp
;
3084 extern long time ();
3086 tp
->tv_sec
= time ((long *)0);
3089 tzp
->tz_minuteswest
= -1;
3095 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3098 * This function will go away as soon as all the stubs fixed. (fnf)
3104 printf ("%s not yet implemented\r\n", badfunc
);
3113 char *sys_siglist
[NSIG
+ 1] =
3115 "null signal", /* 0 SIGNULL */
3116 "hangup", /* 1 SIGHUP */
3117 "interrupt", /* 2 SIGINT */
3118 "quit", /* 3 SIGQUIT */
3119 "illegal instruction", /* 4 SIGILL */
3120 "trace trap", /* 5 SIGTRAP */
3121 "abort termination", /* 6 SIGABRT */
3122 "SIGEMT", /* 7 SIGEMT */
3123 "floating point exception", /* 8 SIGFPE */
3124 "kill", /* 9 SIGKILL */
3125 "bus error", /* 10 SIGBUS */
3126 "segmentation violation", /* 11 SIGSEGV */
3127 "bad argument to system call", /* 12 SIGSYS */
3128 "write on a pipe with no reader", /* 13 SIGPIPE */
3129 "alarm clock", /* 14 SIGALRM */
3130 "software termination signal", /* 15 SIGTERM */
3131 "user defined signal 1", /* 16 SIGUSR1 */
3132 "user defined signal 2", /* 17 SIGUSR2 */
3133 "child stopped or terminated", /* 18 SIGCLD */
3134 "power-fail restart", /* 19 SIGPWR */
3135 "window size changed", /* 20 SIGWINCH */
3136 "undefined", /* 21 */
3137 "pollable event occurred", /* 22 SIGPOLL */
3138 "sendable stop signal not from tty", /* 23 SIGSTOP */
3139 "stop signal from tty", /* 24 SIGSTP */
3140 "continue a stopped process", /* 25 SIGCONT */
3141 "attempted background tty read", /* 26 SIGTTIN */
3142 "attempted background tty write", /* 27 SIGTTOU */
3143 "undefined", /* 28 */
3144 "undefined", /* 29 */
3145 "undefined", /* 30 */
3146 "undefined", /* 31 */
3147 "undefined", /* 32 */
3148 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
3149 "I/O is possible", /* 34 SIGIO */
3150 "exceeded cpu time limit", /* 35 SIGXCPU */
3151 "exceeded file size limit", /* 36 SIGXFSZ */
3152 "virtual time alarm", /* 37 SIGVTALRM */
3153 "profiling time alarm", /* 38 SIGPROF */
3154 "undefined", /* 39 */
3155 "file record locks revoked", /* 40 SIGLOST */
3156 "undefined", /* 41 */
3157 "undefined", /* 42 */
3158 "undefined", /* 43 */
3159 "undefined", /* 44 */
3160 "undefined", /* 45 */
3161 "undefined", /* 46 */
3162 "undefined", /* 47 */
3163 "undefined", /* 48 */
3164 "undefined", /* 49 */
3165 "undefined", /* 50 */
3166 "undefined", /* 51 */
3167 "undefined", /* 52 */
3168 "undefined", /* 53 */
3169 "undefined", /* 54 */
3170 "undefined", /* 55 */
3171 "undefined", /* 56 */
3172 "undefined", /* 57 */
3173 "undefined", /* 58 */
3174 "undefined", /* 59 */
3175 "undefined", /* 60 */
3176 "undefined", /* 61 */
3177 "undefined", /* 62 */
3178 "undefined", /* 63 */
3179 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
3185 /* Directory routines for systems that don't have them. */
3187 #ifdef SYSV_SYSTEM_DIR
3191 #if defined(BROKEN_CLOSEDIR) || !defined(HAVE_CLOSEDIR)
3195 register DIR *dirp
; /* stream from opendir */
3199 rtnval
= sys_close (dirp
->dd_fd
);
3201 /* Some systems (like Solaris) allocate the buffer and the DIR all
3202 in one block. Why in the world are we freeing this ourselves
3204 #if ! (defined (sun) && defined (USG5_4))
3205 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
3207 xfree ((char *) dirp
);
3211 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3212 #endif /* SYSV_SYSTEM_DIR */
3214 #ifdef NONSYSTEM_DIR_LIBRARY
3218 char *filename
; /* name of directory */
3220 register DIR *dirp
; /* -> malloc'ed storage */
3221 register int fd
; /* file descriptor for read */
3222 struct stat sbuf
; /* result of fstat */
3224 fd
= sys_open (filename
, 0);
3229 if (fstat (fd
, &sbuf
) < 0
3230 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
3231 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
3235 return 0; /* bad luck today */
3240 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
3247 register DIR *dirp
; /* stream from opendir */
3249 sys_close (dirp
->dd_fd
);
3250 xfree ((char *) dirp
);
3258 ino_t od_ino
; /* inode */
3259 char od_name
[DIRSIZ
]; /* filename */
3261 #endif /* not VMS */
3263 struct direct dir_static
; /* simulated directory contents */
3268 register DIR *dirp
; /* stream from opendir */
3271 register struct olddir
*dp
; /* -> directory data */
3273 register struct dir$_name
*dp
; /* -> directory data */
3274 register struct dir$_version
*dv
; /* -> version data */
3279 if (dirp
->dd_loc
>= dirp
->dd_size
)
3280 dirp
->dd_loc
= dirp
->dd_size
= 0;
3282 if (dirp
->dd_size
== 0 /* refill buffer */
3283 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3287 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3288 dirp
->dd_loc
+= sizeof (struct olddir
);
3290 if (dp
->od_ino
!= 0) /* not deleted entry */
3292 dir_static
.d_ino
= dp
->od_ino
;
3293 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3294 dir_static
.d_name
[DIRSIZ
] = '\0';
3295 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3296 dir_static
.d_reclen
= sizeof (struct direct
)
3298 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3299 return &dir_static
; /* -> simulated structure */
3302 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3303 if (dirp
->dd_loc
== 0)
3304 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3305 : dp
->dir$b_namecount
;
3306 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3307 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3308 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3309 dir_static
.d_reclen
= sizeof (struct direct
)
3311 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3312 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3313 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3314 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3321 /* readdirver is just like readdir except it returns all versions of a file
3322 as separate entries. */
3327 register DIR *dirp
; /* stream from opendir */
3329 register struct dir$_name
*dp
; /* -> directory data */
3330 register struct dir$_version
*dv
; /* -> version data */
3332 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3333 dirp
->dd_loc
= dirp
->dd_size
= 0;
3335 if (dirp
->dd_size
== 0 /* refill buffer */
3336 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3339 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3340 if (dirp
->dd_loc
== 0)
3341 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3342 : dp
->dir$b_namecount
;
3343 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3344 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3345 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3346 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3347 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3348 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3349 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3350 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3356 #endif /* NONSYSTEM_DIR_LIBRARY */
3359 /* mkdir and rmdir functions, for systems which don't have them. */
3363 * Written by Robert Rother, Mariah Corporation, August 1985.
3365 * If you want it, it's yours. All I ask in return is that if you
3366 * figure out how to do this in a Bourne Shell script you send me
3368 * sdcsvax!rmr or rmr@uscd
3370 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3371 * subroutine. 11Mar86; hoptoad!gnu
3373 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3374 * subroutine didn't return EEXIST. It does now.
3380 #ifdef MKDIR_PROTOTYPE
3384 mkdir (dpath
, dmode
)
3389 int cpid
, status
, fd
;
3390 struct stat statbuf
;
3392 if (stat (dpath
, &statbuf
) == 0)
3394 errno
= EEXIST
; /* Stat worked, so it already exists */
3398 /* If stat fails for a reason other than non-existence, return error */
3399 if (errno
!= ENOENT
)
3402 synch_process_alive
= 1;
3403 switch (cpid
= fork ())
3406 case -1: /* Error in fork */
3407 return (-1); /* Errno is set already */
3409 case 0: /* Child process */
3411 * Cheap hack to set mode of new directory. Since this
3412 * child process is going away anyway, we zap its umask.
3413 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3414 * directory. Does anybody care?
3416 status
= umask (0); /* Get current umask */
3417 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3418 fd
= sys_open("/dev/null", 2);
3425 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3426 _exit (-1); /* Can't exec /bin/mkdir */
3428 default: /* Parent process */
3429 wait_for_termination (cpid
);
3432 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3434 errno
= EIO
; /* We don't know why, but */
3435 return -1; /* /bin/mkdir failed */
3440 #endif /* not HAVE_MKDIR */
3447 int cpid
, status
, fd
;
3448 struct stat statbuf
;
3450 if (stat (dpath
, &statbuf
) != 0)
3452 /* Stat just set errno. We don't have to */
3456 synch_process_alive
= 1;
3457 switch (cpid
= fork ())
3460 case -1: /* Error in fork */
3461 return (-1); /* Errno is set already */
3463 case 0: /* Child process */
3464 fd
= sys_open("/dev/null", 2);
3471 wait_for_termination (cpid
);
3472 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3473 return -1; /* /bin/rmdir failed */
3474 default: /* Parent process */
3475 while (cpid
!= wait (&status
)); /* Wait for kid to finish */
3478 if (WIFSIGNALED (status
) || WEXITSTATUS (status
) != 0)
3480 errno
= EIO
; /* We don't know why, but */
3481 return -1; /* /bin/mkdir failed */
3486 #endif /* !HAVE_RMDIR */
3490 /* Functions for VMS */
3492 #include "vms-pwd.h"
3497 /* Return as a string the VMS error string pertaining to STATUS.
3498 Reuses the same static buffer each time it is called. */
3502 int status
; /* VMS status code */
3506 static char buf
[257];
3508 bufadr
[0] = sizeof buf
- 1;
3509 bufadr
[1] = (int) buf
;
3510 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3511 return "untranslatable VMS error status";
3519 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3520 * not work correctly. (It also doesn't work well in version 2.3.)
3525 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3526 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3530 unsigned short s_buflen
;
3531 unsigned short s_code
;
3533 unsigned short *s_retlenadr
;
3537 #define buflen s.s_buflen
3538 #define code s.s_code
3539 #define bufadr s.s_bufadr
3540 #define retlenadr s.s_retlenadr
3542 #define R_OK 4 /* test for read permission */
3543 #define W_OK 2 /* test for write permission */
3544 #define X_OK 1 /* test for execute (search) permission */
3545 #define F_OK 0 /* test for presence of file */
3548 sys_access (path
, mode
)
3552 static char *user
= NULL
;
3555 /* translate possible directory spec into .DIR file name, so brain-dead
3556 * access can treat the directory like a file. */
3557 if (directory_file_name (path
, dir_fn
))
3561 return access (path
, mode
);
3562 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3568 unsigned short int dummy
;
3570 static int constant
= ACL$C_FILE
;
3571 DESCRIPTOR (path_desc
, path
);
3572 DESCRIPTOR (user_desc
, user
);
3576 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3579 acces
|= CHP$M_READ
;
3581 acces
|= CHP$M_WRITE
;
3582 itemlst
[0].buflen
= sizeof (int);
3583 itemlst
[0].code
= CHP$_FLAGS
;
3584 itemlst
[0].bufadr
= (char *) &flags
;
3585 itemlst
[0].retlenadr
= &dummy
;
3586 itemlst
[1].buflen
= sizeof (int);
3587 itemlst
[1].code
= CHP$_ACCESS
;
3588 itemlst
[1].bufadr
= (char *) &acces
;
3589 itemlst
[1].retlenadr
= &dummy
;
3590 itemlst
[2].end
= CHP$_END
;
3591 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3592 return stat
== SS$_NORMAL
? 0 : -1;
3596 #else /* not VMS4_4 */
3599 #define ACE$M_WRITE 2
3600 #define ACE$C_KEYID 1
3602 static unsigned short memid
, grpid
;
3603 static unsigned int uic
;
3605 /* Called from init_sys_modes, so it happens not very often
3606 but at least each time Emacs is loaded. */
3607 sys_access_reinit ()
3613 sys_access (filename
, type
)
3619 int status
, size
, i
, typecode
, acl_controlled
;
3620 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3621 union prvdef prvmask
;
3623 /* Get UIC and GRP values for protection checking. */
3626 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3629 memid
= uic
& 0xFFFF;
3633 if (type
!= 2) /* not checking write access */
3634 return access (filename
, type
);
3636 /* Check write protection. */
3638 #define CHECKPRIV(bit) (prvmask.bit)
3639 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3641 /* Find privilege bits */
3642 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3644 error ("Unable to find privileges: %s", vmserrstr (status
));
3645 if (CHECKPRIV (PRV$V_BYPASS
))
3646 return 0; /* BYPASS enabled */
3648 fab
.fab$b_fac
= FAB$M_GET
;
3649 fab
.fab$l_fna
= filename
;
3650 fab
.fab$b_fns
= strlen (filename
);
3651 fab
.fab$l_xab
= &xab
;
3652 xab
= cc$rms_xabpro
;
3653 xab
.xab$l_aclbuf
= aclbuf
;
3654 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3655 status
= SYS$
OPEN (&fab
, 0, 0);
3658 SYS$
CLOSE (&fab
, 0, 0);
3659 /* Check system access */
3660 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
3662 /* Check ACL entries, if any */
3664 if (xab
.xab$w_acllen
> 0)
3667 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3668 while (*aclptr
&& aclptr
< aclend
)
3670 size
= (*aclptr
& 0xff) / 4;
3671 typecode
= (*aclptr
>> 8) & 0xff;
3672 if (typecode
== ACE$C_KEYID
)
3673 for (i
= size
- 1; i
> 1; i
--)
3674 if (aclptr
[i
] == uic
)
3677 if (aclptr
[1] & ACE$M_WRITE
)
3678 return 0; /* Write access through ACL */
3680 aclptr
= &aclptr
[size
];
3682 if (acl_controlled
) /* ACL specified, prohibits write access */
3685 /* No ACL entries specified, check normal protection */
3686 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3688 if (WRITEABLE (XAB$V_GRP
) &&
3689 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3690 return 0; /* Group writeable */
3691 if (WRITEABLE (XAB$V_OWN
) &&
3692 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3693 return 0; /* Owner writeable */
3695 return -1; /* Not writeable */
3697 #endif /* not VMS4_4 */
3700 static char vtbuf
[NAM$C_MAXRSS
+1];
3702 /* translate a vms file spec to a unix path */
3704 sys_translate_vms (vfile
)
3715 /* leading device or logical name is a root directory */
3716 if (p
= strchr (vfile
, ':'))
3725 if (*p
== '[' || *p
== '<')
3727 while (*++vfile
!= *p
+ 2)
3731 if (vfile
[-1] == *p
)
3754 static char utbuf
[NAM$C_MAXRSS
+1];
3756 /* translate a unix path to a VMS file spec */
3758 sys_translate_unix (ufile
)
3781 if (index (&ufile
[1], '/'))
3788 if (index (&ufile
[1], '/'))
3795 if (strncmp (ufile
, "./", 2) == 0)
3802 ufile
++; /* skip the dot */
3803 if (index (&ufile
[1], '/'))
3808 else if (strncmp (ufile
, "../", 3) == 0)
3816 ufile
+= 2; /* skip the dots */
3817 if (index (&ufile
[1], '/'))
3842 extern char *getcwd ();
3844 #define MAXPATHLEN 1024
3846 ptr
= xmalloc (MAXPATHLEN
);
3847 val
= getcwd (ptr
, MAXPATHLEN
);
3853 strcpy (pathname
, ptr
);
3861 long item_code
= JPI$_OWNER
;
3862 unsigned long parent_id
;
3865 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3868 vaxc$errno
= status
;
3878 return (getgid () << 16) | getuid ();
3882 sys_read (fildes
, buf
, nbyte
)
3887 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3892 sys_write (fildes
, buf
, nbyte
)
3897 register int nwrote
, rtnval
= 0;
3899 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3905 return rtnval
? rtnval
: -1;
3906 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3907 return rtnval
? rtnval
: -1;
3908 return (rtnval
+ nwrote
);
3913 * VAX/VMS VAX C RTL really loses. It insists that records
3914 * end with a newline (carriage return) character, and if they
3915 * don't it adds one (nice of it isn't it!)
3917 * Thus we do this stupidity below.
3921 sys_write (fildes
, buf
, nbytes
)
3924 unsigned int nbytes
;
3931 fstat (fildes
, &st
);
3937 /* Handle fixed-length files with carriage control. */
3938 if (st
.st_fab_rfm
== FAB$C_FIX
3939 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3941 len
= st
.st_fab_mrs
;
3942 retval
= write (fildes
, p
, min (len
, nbytes
));
3945 retval
++; /* This skips the implied carriage control */
3949 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3950 while (*e
!= '\n' && e
> p
) e
--;
3951 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3952 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3954 retval
= write (fildes
, p
, len
);
3965 /* Create file NEW copying its attributes from file OLD. If
3966 OLD is 0 or does not exist, create based on the value of
3969 /* Protection value the file should ultimately have.
3970 Set by create_copy_attrs, and use by rename_sansversions. */
3971 static unsigned short int fab_final_pro
;
3974 creat_copy_attrs (old
, new)
3977 struct FAB fab
= cc$rms_fab
;
3978 struct XABPRO xabpro
;
3979 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3980 extern int vms_stmlf_recfm
;
3984 fab
.fab$b_fac
= FAB$M_GET
;
3985 fab
.fab$l_fna
= old
;
3986 fab
.fab$b_fns
= strlen (old
);
3987 fab
.fab$l_xab
= (char *) &xabpro
;
3988 xabpro
= cc$rms_xabpro
;
3989 xabpro
.xab$l_aclbuf
= aclbuf
;
3990 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3991 /* Call $OPEN to fill in the fab & xabpro fields. */
3992 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3994 SYS$
CLOSE (&fab
, 0, 0);
3995 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3996 if (xabpro
.xab$w_acllen
> 0)
3998 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3999 /* If the acl buffer was too short, redo open with longer one.
4000 Wouldn't need to do this if there were some system imposed
4001 limit on the size of an ACL, but I can't find any such. */
4003 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
4004 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
4005 if (SYS$
OPEN (&fab
, 0, 0) & 1)
4006 SYS$
CLOSE (&fab
, 0, 0);
4012 xabpro
.xab$l_aclbuf
= 0;
4017 fab
.fab$l_fna
= new;
4018 fab
.fab$b_fns
= strlen (new);
4022 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
4023 fab
.fab$b_rat
= FAB$M_CR
;
4026 /* Set the file protections such that we will be able to manipulate
4027 this file. Once we are done writing and renaming it, we will set
4028 the protections back. */
4030 fab_final_pro
= xabpro
.xab$w_pro
;
4032 SYS$
SETDFPROT (0, &fab_final_pro
);
4033 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
4035 /* Create the new file with either default attrs or attrs copied
4037 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
4039 SYS$
CLOSE (&fab
, 0, 0);
4040 /* As this is a "replacement" for creat, return a file descriptor
4041 opened for writing. */
4042 return open (new, O_WRONLY
);
4047 #include <varargs.h>
4050 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4054 sys_creat (va_alist
)
4057 va_list list_incrementer
;
4060 int rfd
; /* related file descriptor */
4061 int fd
; /* Our new file descriptor */
4068 extern int vms_stmlf_recfm
;
4071 va_start (list_incrementer
);
4072 name
= va_arg (list_incrementer
, char *);
4073 mode
= va_arg (list_incrementer
, int);
4075 rfd
= va_arg (list_incrementer
, int);
4076 va_end (list_incrementer
);
4079 /* Use information from the related file descriptor to set record
4080 format of the newly created file. */
4081 fstat (rfd
, &st_buf
);
4082 switch (st_buf
.st_fab_rfm
)
4085 strcpy (rfm
, "rfm = fix");
4086 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
4087 strcpy (rat
, "rat = ");
4088 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4090 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4091 strcat (rat
, "ftn");
4092 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4093 strcat (rat
, "prn");
4094 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4095 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4096 strcat (rat
, ", blk");
4098 strcat (rat
, "blk");
4099 return creat (name
, 0, rfm
, rat
, mrs
);
4102 strcpy (rfm
, "rfm = vfc");
4103 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
4104 strcpy (rat
, "rat = ");
4105 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4107 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4108 strcat (rat
, "ftn");
4109 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4110 strcat (rat
, "prn");
4111 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4112 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4113 strcat (rat
, ", blk");
4115 strcat (rat
, "blk");
4116 return creat (name
, 0, rfm
, rat
, fsz
);
4119 strcpy (rfm
, "rfm = stm");
4123 strcpy (rfm
, "rfm = stmcr");
4127 strcpy (rfm
, "rfm = stmlf");
4131 strcpy (rfm
, "rfm = udf");
4135 strcpy (rfm
, "rfm = var");
4138 strcpy (rat
, "rat = ");
4139 if (st_buf
.st_fab_rat
& FAB$M_CR
)
4141 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
4142 strcat (rat
, "ftn");
4143 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
4144 strcat (rat
, "prn");
4145 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
4146 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
4147 strcat (rat
, ", blk");
4149 strcat (rat
, "blk");
4153 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
4154 strcpy (rat
, "rat=cr");
4156 /* Until the VAX C RTL fixes the many bugs with modes, always use
4157 mode 0 to get the user's default protection. */
4158 fd
= creat (name
, 0, rfm
, rat
);
4159 if (fd
< 0 && errno
== EEXIST
)
4161 if (unlink (name
) < 0)
4162 report_file_error ("delete", build_string (name
));
4163 fd
= creat (name
, 0, rfm
, rat
);
4169 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4170 sys_fwrite (ptr
, size
, num
, fp
)
4171 register char * ptr
;
4174 register int tot
= num
* size
;
4181 * The VMS C library routine creat actually creates a new version of an
4182 * existing file rather than truncating the old version. There are times
4183 * when this is not the desired behavior, for instance, when writing an
4184 * auto save file (you only want one version), or when you don't have
4185 * write permission in the directory containing the file (but the file
4186 * itself is writable). Hence this routine, which is equivalent to
4187 * "close (creat (fn, 0));" on Unix if fn already exists.
4193 struct FAB xfab
= cc$rms_fab
;
4194 struct RAB xrab
= cc$rms_rab
;
4197 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
4198 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
4199 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
4200 xfab
.fab$l_fna
= fn
;
4201 xfab
.fab$b_fns
= strlen (fn
);
4202 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
4204 xrab
.rab$l_fab
= &xfab
;
4206 /* This gibberish opens the file, positions to the first record, and
4207 deletes all records from there until the end of file. */
4208 if ((SYS$
OPEN (&xfab
) & 01) == 01)
4210 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
4211 (SYS$
FIND (&xrab
) & 01) == 01 &&
4212 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
4223 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4224 SYSPRV or a readable SYSUAF.DAT. */
4230 * Routine to read the VMS User Authorization File and return
4231 * a specific user's record.
4234 static struct UAF retuaf
;
4237 get_uaf_name (uname
)
4244 uaf_fab
= cc$rms_fab
;
4245 uaf_rab
= cc$rms_rab
;
4246 /* initialize fab fields */
4247 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4248 uaf_fab
.fab$b_fns
= 21;
4249 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4250 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4251 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4252 /* initialize rab fields */
4253 uaf_rab
.rab$l_fab
= &uaf_fab
;
4254 /* open the User Authorization File */
4255 status
= SYS$
OPEN (&uaf_fab
);
4259 vaxc$errno
= status
;
4262 status
= SYS$
CONNECT (&uaf_rab
);
4266 vaxc$errno
= status
;
4269 /* read the requested record - index is in uname */
4270 uaf_rab
.rab$l_kbf
= uname
;
4271 uaf_rab
.rab$b_ksz
= strlen (uname
);
4272 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4273 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4274 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4275 status
= SYS$
GET (&uaf_rab
);
4279 vaxc$errno
= status
;
4282 /* close the User Authorization File */
4283 status
= SYS$
DISCONNECT (&uaf_rab
);
4287 vaxc$errno
= status
;
4290 status
= SYS$
CLOSE (&uaf_fab
);
4294 vaxc$errno
= status
;
4308 uaf_fab
= cc$rms_fab
;
4309 uaf_rab
= cc$rms_rab
;
4310 /* initialize fab fields */
4311 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4312 uaf_fab
.fab$b_fns
= 21;
4313 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4314 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4315 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4316 /* initialize rab fields */
4317 uaf_rab
.rab$l_fab
= &uaf_fab
;
4318 /* open the User Authorization File */
4319 status
= SYS$
OPEN (&uaf_fab
);
4323 vaxc$errno
= status
;
4326 status
= SYS$
CONNECT (&uaf_rab
);
4330 vaxc$errno
= status
;
4333 /* read the requested record - index is in uic */
4334 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4335 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4336 uaf_rab
.rab$b_ksz
= sizeof uic
;
4337 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4338 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4339 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4340 status
= SYS$
GET (&uaf_rab
);
4344 vaxc$errno
= status
;
4347 /* close the User Authorization File */
4348 status
= SYS$
DISCONNECT (&uaf_rab
);
4352 vaxc$errno
= status
;
4355 status
= SYS$
CLOSE (&uaf_fab
);
4359 vaxc$errno
= status
;
4365 static struct passwd retpw
;
4373 /* copy these out first because if the username is 32 chars, the next
4374 section will overwrite the first byte of the UIC */
4375 retpw
.pw_uid
= up
->uaf$w_mem
;
4376 retpw
.pw_gid
= up
->uaf$w_grp
;
4378 /* I suppose this is not the best sytle, to possibly overwrite one
4379 byte beyond the end of the field, but what the heck... */
4380 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4381 while (ptr
[-1] == ' ')
4384 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4386 /* the rest of these are counted ascii strings */
4387 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4388 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4389 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4390 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4391 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4392 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4393 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4394 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4398 #else /* not READ_SYSUAF */
4399 static struct passwd retpw
;
4400 #endif /* not READ_SYSUAF */
4411 unsigned char * full
;
4412 #endif /* READ_SYSUAF */
4417 if ('a' <= *ptr
&& *ptr
<= 'z')
4422 if (!(up
= get_uaf_name (name
)))
4424 return cnv_uaf_pw (up
);
4426 if (strcmp (name
, getenv ("USER")) == 0)
4428 retpw
.pw_uid
= getuid ();
4429 retpw
.pw_gid
= getgid ();
4430 strcpy (retpw
.pw_name
, name
);
4431 if (full
= egetenv ("FULLNAME"))
4432 strcpy (retpw
.pw_gecos
, full
);
4434 *retpw
.pw_gecos
= '\0';
4435 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4436 *retpw
.pw_shell
= '\0';
4441 #endif /* not READ_SYSUAF */
4451 if (!(up
= get_uaf_uic (uid
)))
4453 return cnv_uaf_pw (up
);
4455 if (uid
== sys_getuid ())
4456 return getpwnam (egetenv ("USER"));
4459 #endif /* not READ_SYSUAF */
4462 /* return total address space available to the current process. This is
4463 the sum of the current p0 size, p1 size and free page table entries
4468 unsigned long free_pages
;
4469 unsigned long frep0va
;
4470 unsigned long frep1va
;
4473 item_code
= JPI$_FREPTECNT
;
4474 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4477 vaxc$errno
= status
;
4482 item_code
= JPI$_FREP0VA
;
4483 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4486 vaxc$errno
= status
;
4489 item_code
= JPI$_FREP1VA
;
4490 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4493 vaxc$errno
= status
;
4497 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4500 define_logical_name (varname
, string
)
4504 struct dsc$descriptor_s strdsc
=
4505 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4506 struct dsc$descriptor_s envdsc
=
4507 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4508 struct dsc$descriptor_s lnmdsc
=
4509 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4511 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4514 delete_logical_name (varname
)
4517 struct dsc$descriptor_s envdsc
=
4518 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4519 struct dsc$descriptor_s lnmdsc
=
4520 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4522 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4533 error ("execvp system call not implemented");
4541 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4542 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4543 char from_esn
[NAM$C_MAXRSS
];
4544 char to_esn
[NAM$C_MAXRSS
];
4546 from_fab
.fab$l_fna
= from
;
4547 from_fab
.fab$b_fns
= strlen (from
);
4548 from_fab
.fab$l_nam
= &from_nam
;
4549 from_fab
.fab$l_fop
= FAB$M_NAM
;
4551 from_nam
.nam$l_esa
= from_esn
;
4552 from_nam
.nam$b_ess
= sizeof from_esn
;
4554 to_fab
.fab$l_fna
= to
;
4555 to_fab
.fab$b_fns
= strlen (to
);
4556 to_fab
.fab$l_nam
= &to_nam
;
4557 to_fab
.fab$l_fop
= FAB$M_NAM
;
4559 to_nam
.nam$l_esa
= to_esn
;
4560 to_nam
.nam$b_ess
= sizeof to_esn
;
4562 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4568 if (status
== RMS$_DEV
)
4572 vaxc$errno
= status
;
4577 /* This function renames a file like `rename', but it strips
4578 the version number from the "to" filename, such that the "to" file is
4579 will always be a new version. It also sets the file protection once it is
4580 finished. The protection that we will use is stored in fab_final_pro,
4581 and was set when we did a creat_copy_attrs to create the file that we
4584 We could use the chmod function, but Eunichs uses 3 bits per user category
4585 to describe the protection, and VMS uses 4 (write and delete are separate
4586 bits). To maintain portability, the VMS implementation of `chmod' wires
4587 the W and D bits together. */
4590 static struct fibdef fib
; /* We need this initialized to zero */
4591 char vms_file_written
[NAM$C_MAXRSS
];
4594 rename_sans_version (from
,to
)
4601 struct FAB to_fab
= cc$rms_fab
;
4602 struct NAM to_nam
= cc$rms_nam
;
4603 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4604 struct dsc$descriptor fib_attr
[2]
4605 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4606 char to_esn
[NAM$C_MAXRSS
];
4608 $
DESCRIPTOR (disk
,to_esn
);
4610 to_fab
.fab$l_fna
= to
;
4611 to_fab
.fab$b_fns
= strlen (to
);
4612 to_fab
.fab$l_nam
= &to_nam
;
4613 to_fab
.fab$l_fop
= FAB$M_NAM
;
4615 to_nam
.nam$l_esa
= to_esn
;
4616 to_nam
.nam$b_ess
= sizeof to_esn
;
4618 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4620 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4621 *(to_nam
.nam$l_ver
) = '\0';
4623 stat
= rename (from
, to_esn
);
4627 strcpy (vms_file_written
, to_esn
);
4629 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4630 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4632 /* Now set the file protection to the correct value */
4633 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4635 /* Copy these fields into the fib */
4636 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4637 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4638 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4640 SYS$
CLOSE (&to_fab
, 0, 0);
4642 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4645 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4646 0, 0, 0, &fib_attr
, 0);
4649 stat
= SYS$
DASSGN (chan
);
4652 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4662 unsigned short fid
[3];
4663 char esa
[NAM$C_MAXRSS
];
4666 fab
.fab$l_fop
= FAB$M_OFP
;
4667 fab
.fab$l_fna
= file
;
4668 fab
.fab$b_fns
= strlen (file
);
4669 fab
.fab$l_nam
= &nam
;
4672 nam
.nam$l_esa
= esa
;
4673 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4675 status
= SYS$
PARSE (&fab
);
4676 if ((status
& 1) == 0)
4679 vaxc$errno
= status
;
4682 status
= SYS$
SEARCH (&fab
);
4683 if ((status
& 1) == 0)
4686 vaxc$errno
= status
;
4690 fid
[0] = nam
.nam$w_fid
[0];
4691 fid
[1] = nam
.nam$w_fid
[1];
4692 fid
[2] = nam
.nam$w_fid
[2];
4694 fab
.fab$l_fna
= new;
4695 fab
.fab$b_fns
= strlen (new);
4697 status
= SYS$
PARSE (&fab
);
4698 if ((status
& 1) == 0)
4701 vaxc$errno
= status
;
4705 nam
.nam$w_fid
[0] = fid
[0];
4706 nam
.nam$w_fid
[1] = fid
[1];
4707 nam
.nam$w_fid
[2] = fid
[2];
4709 nam
.nam$l_esa
= nam
.nam$l_name
;
4710 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4712 status
= SYS$
ENTER (&fab
);
4713 if ((status
& 1) == 0)
4716 vaxc$errno
= status
;
4726 printf ("%s not yet implemented\r\n", badfunc
);
4734 /* Arrange to return a range centered on zero. */
4735 return rand () - (1 << 30);
4746 /* Called from init_sys_modes. */
4751 /* If we're not on an HFT we shouldn't do any of this. We determine
4752 if we are on an HFT by trying to get an HFT error code. If this
4753 call fails, we're not on an HFT. */
4755 if (ioctl (0, HFQERROR
, &junk
) < 0)
4757 #else /* not IBMR2AIX */
4758 if (ioctl (0, HFQEIO
, 0) < 0)
4760 #endif /* not IBMR2AIX */
4762 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4763 as the rubout key's ASCII code. Here this is changed. The bug is that
4764 there's no way to determine the old mapping, so in reset_sys_modes
4765 we need to assume that the normal map had been present. Of course, this
4766 code also doesn't help if on a terminal emulator which doesn't understand
4770 struct hfkeymap keymap
;
4772 buf
.hf_bufp
= (char *)&keymap
;
4773 buf
.hf_buflen
= sizeof (keymap
);
4774 keymap
.hf_nkeys
= 2;
4775 keymap
.hfkey
[0].hf_kpos
= 15;
4776 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4778 keymap
.hfkey
[0].hf_keyidh
= '<';
4779 #else /* not IBMR2AIX */
4780 keymap
.hfkey
[0].hf_page
= '<';
4781 #endif /* not IBMR2AIX */
4782 keymap
.hfkey
[0].hf_char
= 127;
4783 keymap
.hfkey
[1].hf_kpos
= 15;
4784 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4786 keymap
.hfkey
[1].hf_keyidh
= '<';
4787 #else /* not IBMR2AIX */
4788 keymap
.hfkey
[1].hf_page
= '<';
4789 #endif /* not IBMR2AIX */
4790 keymap
.hfkey
[1].hf_char
= 127;
4791 hftctl (0, HFSKBD
, &buf
);
4793 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4795 line_ins_del_ok
= char_ins_del_ok
= 0;
4798 /* Reset the rubout key to backspace. */
4803 struct hfkeymap keymap
;
4807 if (ioctl (0, HFQERROR
, &junk
) < 0)
4809 #else /* not IBMR2AIX */
4810 if (ioctl (0, HFQEIO
, 0) < 0)
4812 #endif /* not IBMR2AIX */
4814 buf
.hf_bufp
= (char *)&keymap
;
4815 buf
.hf_buflen
= sizeof (keymap
);
4816 keymap
.hf_nkeys
= 2;
4817 keymap
.hfkey
[0].hf_kpos
= 15;
4818 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4820 keymap
.hfkey
[0].hf_keyidh
= '<';
4821 #else /* not IBMR2AIX */
4822 keymap
.hfkey
[0].hf_page
= '<';
4823 #endif /* not IBMR2AIX */
4824 keymap
.hfkey
[0].hf_char
= 8;
4825 keymap
.hfkey
[1].hf_kpos
= 15;
4826 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4828 keymap
.hfkey
[1].hf_keyidh
= '<';
4829 #else /* not IBMR2AIX */
4830 keymap
.hfkey
[1].hf_page
= '<';
4831 #endif /* not IBMR2AIX */
4832 keymap
.hfkey
[1].hf_char
= 8;
4833 hftctl (0, HFSKBD
, &buf
);