1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
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>
69 extern char *sys_errlist
[];
92 #define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */
96 #ifdef BSD /* this is done this way to avoid defined (BSD) || defined (USG)
97 because the vms compiler doesn't grok `defined' */
105 #endif /* not 4.1 bsd */
107 /* Get DGUX definition for FASYNC - DJB */
109 #include <sys/file.h>
112 #include <sys/ioctl.h>
119 #include <sys/wait.h>
123 #ifdef BROKEN_TIOCGWINSZ
128 #include <sys/utsname.h>
130 #ifndef MEMORY_IN_STRING_H
135 #include <sys/sioctl.h>
138 #include <sys/stream.h>
139 #include <sys/ptem.h>
141 #endif /* TIOCGWINSZ */
144 extern int quit_char
;
148 #include "termhooks.h"
149 #include "termchar.h"
150 #include "termopts.h"
151 #include "dispextern.h"
154 #ifdef NONSYSTEM_DIR_LIBRARY
156 #endif /* NONSYSTEM_DIR_LIBRARY */
158 #include "syssignal.h"
161 static int baud_convert
[] =
166 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
167 1800, 2400, 4800, 9600, 19200, 38400
173 /* The file descriptor for Emacs's input terminal.
174 Under Unix, this is always left zero;
175 under VMS, we place the input channel number here.
176 This allows us to write more code that works for both VMS and Unix. */
181 struct emacs_tty buf
;
186 /* Discarding input is not safe when the input could contain
187 replies from the X server. So don't do it. */
188 if (read_socket_hook
)
193 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
194 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
200 ioctl (0, TIOCFLUSH
, &zero
);
202 #else /* not Apollo */
203 EMACS_GET_TTY (input_fd
, &buf
);
204 EMACS_SET_TTY (input_fd
, &buf
, 0);
205 #endif /* not Apollo */
214 /* Should perhaps error if in batch mode */
216 ioctl (0, TIOCSTI
, &c
);
217 #else /* no TIOCSTI */
218 error ("Cannot stuff terminal input characters in this version of Unix.");
219 #endif /* no TIOCSTI */
233 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
234 &sg
.class, 12, 0, 0, 0, 0 );
235 ospeed
= sg
.xmit_baud
;
240 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
242 ospeed
= sg
.c_cflag
& CBAUD
;
243 #else /* neither VMS nor TERMIOS */
247 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
251 ioctl (input_fd
, TCGETA
, &sg
);
253 ospeed
= sg
.c_cflag
& CBAUD
;
254 #else /* neither VMS nor TERMIOS nor TERMIO */
257 sg
.sg_ospeed
= B9600
;
258 ioctl (0, TIOCGETP
, &sg
);
259 ospeed
= sg
.sg_ospeed
;
260 #endif /* not HAVE_TERMIO */
261 #endif /* not HAVE_TERMIOS */
265 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
266 ? baud_convert
[ospeed
] : 9600);
272 set_exclusive_use (fd
)
276 ioctl (fd
, FIOCLEX
, 0);
278 /* Ok to do nothing if this feature does not exist */
283 wait_without_blocking ()
286 wait3 (0, WNOHANG
| WUNTRACED
, 0);
288 croak ("wait_without_blocking");
290 synch_process_alive
= 0;
293 #endif /* not subprocesses */
295 int wait_debugging
; /* Set nonzero to make following function work under dbx
296 (at least for bsd). */
299 wait_for_termination_signal ()
302 /* Wait for subprocess with process id `pid' to terminate and
303 make sure it will get eliminated (not remain forever as a zombie) */
305 wait_for_termination (pid
)
314 status
= SYS$
FORCEX (&pid
, 0, 0);
317 #if (defined (BSD) && !defined (LINUX)) || (defined (HPUX) && !defined (HPUX_5))
318 /* Note that kill returns -1 even if the process is just a zombie now.
319 But inevitably a SIGCHLD interrupt should be generated
320 and child_sig will do wait3 and make the process go away. */
321 /* There is some indication that there is a bug involved with
322 termination of subprocesses, perhaps involving a kernel bug too,
323 but no idea what it is. Just as a hunch we signal SIGCHLD to see
324 if that causes the problem to go away or get worse. */
325 sigsetmask (sigmask (SIGCHLD
));
326 if (0 > kill (pid
, 0))
328 sigsetmask (SIGEMPTYMASK
);
329 kill (getpid (), SIGCHLD
);
335 sigpause (SIGEMPTYMASK
);
336 #else /* not BSD, not LINUX, and not HPUX version >= 6 */
337 #if defined (UNIPLUS) || defined (LINUX)
338 if (0 > kill (pid
, 0))
341 #else /* neither BSD nor UNIPLUS nor LINUX: random sysV */
342 #ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
343 sigblock (sigmask (SIGCHLD
));
344 if (0 > kill (pid
, 0))
346 sigunblock (sigmask (SIGCHLD
));
349 sigpause (sigmask (SIGCHLD
));
350 #else /* not POSIX_SIGNALS */
351 #ifdef HAVE_SYSV_SIGPAUSE
353 if (0 > kill (pid
, 0))
359 #else /* not HAVE_SYSV_SIGPAUSE */
360 if (0 > kill (pid
, 0))
362 /* Using sleep instead of pause avoids timing error.
363 If the inferior dies just before the sleep,
364 we lose just one second. */
366 #endif /* not HAVE_SYSV_SIGPAUSE */
367 #endif /* not POSIX_SIGNALS */
368 #endif /* not UNIPLUS */
369 #endif /* not BSD, and not HPUX version >= 6 */
371 #else /* not subprocesses */
373 if (kill (pid
, 0) < 0)
379 if (status
== pid
|| status
== -1)
382 #endif /* not subprocesses */
389 * flush any pending output
390 * (may flush input as well; it does not matter the way we use it)
393 flush_pending_output (channel
)
397 /* If we try this, we get hit with SIGTTIN, because
398 the child's tty belongs to the child's pgrp. */
401 ioctl (channel
, TCFLSH
, 1);
405 /* 3rd arg should be ignored
406 but some 4.2 kernels actually want the address of an int
407 and nonzero means something different. */
408 ioctl (channel
, TIOCFLUSH
, &zero
);
415 /* Set up the terminal at the other end of a pseudo-terminal that
416 we will be controlling an inferior through.
417 It should not echo or do line-editing, since that is done
418 in Emacs. No padding needed for insertion into an Emacs buffer. */
420 child_setup_tty (out
)
425 EMACS_GET_TTY (out
, &s
);
427 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
428 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
429 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
430 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
431 /* No output delays */
432 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
433 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
434 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
436 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
439 /* Said to be unnecesary: */
440 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
441 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
444 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
445 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
446 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
447 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
450 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
454 /* AIX enhanced edit loses NULs, so disable it */
457 s
.main
.c_iflag
&= ~ASCEDIT
;
459 /* Also, PTY overloads NUL and BREAK.
460 don't ignore break, but don't signal either, so it looks like NUL. */
461 s
.main
.c_iflag
&= ~IGNBRK
;
462 s
.main
.c_iflag
&= ~BRKINT
;
463 /* QUIT and INTR work better as signals, so disable character forms */
464 s
.main
.c_cc
[VQUIT
] = 0377;
465 s
.main
.c_cc
[VINTR
] = 0377;
466 #ifdef SIGNALS_VIA_CHARACTERS
467 /* the QUIT and INTR character are used in process_send_signal
468 so set them here to something useful. */
469 if (s
.main
.c_cc
[VQUIT
] == 0377)
470 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
471 if (s
.main
.c_cc
[VINTR
] == 0377)
472 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
473 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
474 /* QUIT and INTR work better as signals, so disable character forms */
475 s
.main
.c_cc
[VQUIT
] = 0377;
476 s
.main
.c_cc
[VINTR
] = 0377;
477 s
.main
.c_lflag
&= ~ISIG
;
478 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
479 s
.main
.c_cc
[VEOL
] = 0377;
480 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
483 #else /* not HAVE_TERMIO */
485 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
487 s
.main
.sg_erase
= 0377;
488 s
.main
.sg_kill
= 0377;
490 #endif /* not HAVE_TERMIO */
492 EMACS_SET_TTY (out
, &s
, 0);
501 ioctl (out
, FIOASYNC
, &zero
);
507 #endif /* subprocesses */
513 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
516 /* Record a signal code and the handler for it. */
520 SIGTYPE (*handler
) ();
523 /* Suspend the Emacs process; give terminal to its superior. */
528 /* "Foster" parentage allows emacs to return to a subprocess that attached
529 to the current emacs as a cheaper than starting a whole new process. This
530 is set up by KEPTEDITOR.COM. */
531 unsigned long parent_id
, foster_parent_id
;
534 fpid_string
= getenv ("EMACS_PARENT_PID");
535 if (fpid_string
!= NULL
)
537 sscanf (fpid_string
, "%x", &foster_parent_id
);
538 if (foster_parent_id
!= 0)
539 parent_id
= foster_parent_id
;
541 parent_id
= getppid ();
544 parent_id
= getppid ();
546 xfree (fpid_string
); /* On VMS, this was malloc'd */
548 if (parent_id
&& parent_id
!= 0xffffffff)
550 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
551 int status
= LIB$
ATTACH (&parent_id
) & 1;
552 signal (SIGINT
, oldsig
);
561 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
562 d_prompt
.a
= "Emacs: "; /* Just a reminder */
563 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
570 EMACS_KILLPG (getpgrp (0), SIGTSTP
);
572 #else /* No SIGTSTP */
573 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
574 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
575 kill (getpid (), SIGQUIT
);
577 #else /* No SIGTSTP or USG_JOBCTRL */
579 /* On a system where suspending is not implemented,
580 instead fork a subshell and let it talk directly to the terminal
583 struct save_signal saved_handlers
[5];
585 saved_handlers
[0].code
= SIGINT
;
586 saved_handlers
[1].code
= SIGQUIT
;
587 saved_handlers
[2].code
= SIGTERM
;
589 saved_handlers
[3].code
= SIGIO
;
590 saved_handlers
[4].code
= 0;
592 saved_handlers
[3].code
= 0;
596 error ("Can't spawn subshell");
601 sh
= (char *) egetenv ("SHELL");
604 /* Use our buffer's default directory for the subshell. */
610 /* mentioning current_buffer->buffer would mean including buffer.h,
611 which somehow wedges the hp compiler. So instead... */
613 dir
= intern ("default-directory");
615 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
617 dir
= Fsymbol_value (dir
);
618 if (XTYPE (dir
) != Lisp_String
)
621 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
622 len
= XSTRING (dir
)->size
;
623 bcopy (XSTRING (dir
)->data
, str
, len
);
624 if (str
[len
- 1] != '/') str
[len
++] = '/';
630 close_process_descs (); /* Close Emacs's pipes/ptys */
635 extern int emacs_priority
;
638 nice (-emacs_priority
);
643 write (1, "Can't execute subshell", 22);
647 save_signal_handlers (saved_handlers
);
648 synch_process_alive
= 1;
649 wait_for_termination (pid
);
650 restore_signal_handlers (saved_handlers
);
652 #endif /* no USG_JOBCTRL */
653 #endif /* no SIGTSTP */
657 save_signal_handlers (saved_handlers
)
658 struct save_signal
*saved_handlers
;
660 while (saved_handlers
->code
)
662 saved_handlers
->handler
663 = (SIGTYPE (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
668 restore_signal_handlers (saved_handlers
)
669 struct save_signal
*saved_handlers
;
671 while (saved_handlers
->code
)
673 signal (saved_handlers
->code
, saved_handlers
->handler
);
685 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
695 #ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
700 sigunblock (sigmask (SIGWINCH
));
702 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
704 interrupts_deferred
= 0;
710 sigblock (sigmask (SIGWINCH
));
712 fcntl (0, F_SETFL
, old_fcntl_flags
);
713 interrupts_deferred
= 1;
716 #else /* no FASYNC */
717 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
722 ioctl (0, FIOASYNC
, &on
);
723 interrupts_deferred
= 0;
730 ioctl (0, FIOASYNC
, &off
);
731 interrupts_deferred
= 1;
734 #else /* not FASYNC, not STRIDE */
738 croak ("request_sigio");
743 croak ("unrequest_sigio");
750 /* Getting and setting emacs_tty structures. */
752 /* Set *TC to the parameters associated with the terminal FD.
753 Return zero if all's well, or -1 if we ran into an error we
754 couldn't deal with. */
756 emacs_get_tty (fd
, settings
)
758 struct emacs_tty
*settings
;
760 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
762 /* We have those nifty POSIX tcmumbleattr functions. */
763 if (tcgetattr (fd
, &settings
->main
) < 0)
768 /* The SYSV-style interface? */
769 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
774 /* Vehemently Monstrous System? :-) */
775 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
776 &settings
->main
.class, 12, 0, 0, 0, 0)
781 /* I give up - I hope you have the BSD ioctls. */
782 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
789 /* Suivant - Do we have to get struct ltchars data? */
791 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
795 /* How about a struct tchars and a wordful of lmode bits? */
797 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
798 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
802 /* We have survived the tempest. */
807 /* Set the parameters of the tty on FD according to the contents of
808 *SETTINGS. If WAITP is non-zero, we wait for all queued output to
809 be written before making the change; otherwise, we forget any
810 queued input and make the change immediately.
811 Return 0 if all went well, and -1 if anything failed. */
813 emacs_set_tty (fd
, settings
, waitp
)
815 struct emacs_tty
*settings
;
818 /* Set the primary parameters - baud rate, character size, etcetera. */
821 /* We have those nifty POSIX tcmumbleattr functions.
822 William J. Smith <wjs@wiis.wang.com> writes:
823 "POSIX 1003.1 defines tcsetattr() to return success if it was
824 able to perform any of the requested actions, even if some
825 of the requested actions could not be performed.
826 We must read settings back to ensure tty setup properly.
827 AIX requires this to keep tty from hanging occasionally." */
828 /* This make sure that we dont loop indefinetly in here. */
829 for (i
= 0 ; i
< 10 ; i
++)
830 if (tcsetattr (fd
, waitp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
841 /* Get the current settings, and see if they're what we asked for. */
842 tcgetattr (fd
, &new);
843 /* We cannot use memcmp on the whole structure here because under
844 * aix386 the termios structure has some reserved field that may
847 if ( new.c_iflag
== settings
->main
.c_iflag
848 && new.c_oflag
== settings
->main
.c_oflag
849 && new.c_cflag
== settings
->main
.c_cflag
850 && new.c_lflag
== settings
->main
.c_lflag
851 && memcmp(new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
859 /* The SYSV-style interface? */
860 if (ioctl (fd
, waitp
? TCSETAW
: TCSETAF
, &settings
->main
) < 0)
865 /* Vehemently Monstrous System? :-) */
866 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
867 &settings
->main
.class, 12, 0, 0, 0, 0)
872 /* I give up - I hope you have the BSD ioctls. */
873 if (ioctl (fd
, (waitp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
880 /* Suivant - Do we have to get struct ltchars data? */
882 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
886 /* How about a struct tchars and a wordful of lmode bits? */
888 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
889 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
893 /* We have survived the tempest. */
898 /* The initial tty mode bits */
899 struct emacs_tty old_tty
;
901 int term_initted
; /* 1 if outer tty status has been recorded */
904 /* BSD 4.1 needs to keep track of the lmode bits in order to start
911 #endif /* F_SETOWN */
913 /* This may also be defined in stdio,
914 but if so, this does no harm,
915 and using the same name avoids wasting the other one's space. */
917 #if defined (USG) || defined (DGUX)
918 unsigned char _sobuf
[BUFSIZ
+8];
924 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
927 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
932 struct emacs_tty tty
;
936 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
937 extern int (*interrupt_signal
) ();
946 input_ef
= get_kbd_event_flag ();
947 /* LIB$GET_EF (&input_ef); */
948 SYS$
CLREF (input_ef
);
951 timer_ef
= get_timer_event_flag ();
952 /* LIB$GET_EF (&timer_ef); */
953 SYS$
CLREF (timer_ef
);
957 LIB$
GET_EF (&process_ef
);
958 SYS$
CLREF (process_ef
);
960 if (input_ef
/ 32 != process_ef
/ 32)
961 croak ("Input and process event flags in different clusters.");
963 if (input_ef
/ 32 != timer_ef
/ 32)
964 croak ("Input and timer event flags in different clusters.");
966 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
967 ((unsigned) 1 << (process_ef
% 32));
969 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
970 ((unsigned) 1 << (timer_ef
% 32));
972 sys_access_reinit ();
976 EMACS_GET_TTY (input_fd
, &old_tty
);
978 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
982 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
983 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
984 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
986 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
988 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
989 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
991 tty
.main
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
993 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
996 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
998 tty
.main
.c_iflag
&= ~IXANY
;
1002 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1003 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1005 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1009 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1010 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1013 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1014 /* Set up C-g for both SIGQUIT and SIGINT.
1015 We don't know which we will get, but we handle both alike
1016 so which one it really gives us does not matter. */
1017 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1018 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1019 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1021 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1024 #if defined (mips) || defined (HAVE_TCATTR)
1026 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1029 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1030 #endif /* V_DSUSP */
1031 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1032 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1034 #endif /* mips or HAVE_TCATTR */
1037 /* AIX enhanced edit loses NULs, so disable it */
1038 tty
.main
.c_line
= 0;
1039 tty
.main
.c_iflag
&= ~ASCEDIT
;
1041 tty
.main
.c_cc
[VSTRT
] = 255;
1042 tty
.main
.c_cc
[VSTOP
] = 255;
1043 tty
.main
.c_cc
[VSUSP
] = 255;
1044 tty
.main
.c_cc
[VDSUSP
] = 255;
1045 #endif /* IBMR2AIX */
1046 /* Also, PTY overloads NUL and BREAK.
1047 don't ignore break, but don't signal either, so it looks like NUL.
1048 This really serves a purpose only if running in an XTERM window
1049 or via TELNET or the like, but does no harm elsewhere. */
1050 tty
.main
.c_iflag
&= ~IGNBRK
;
1051 tty
.main
.c_iflag
&= ~BRKINT
;
1053 #else /* if not HAVE_TERMIO */
1055 tty
.main
.tt_char
|= TT$M_NOECHO
;
1057 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1059 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1061 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1062 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1063 #else /* not VMS (BSD, that is) */
1064 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1066 tty
.main
.sg_flags
|= ANYP
;
1067 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1068 #endif /* not VMS (BSD, that is) */
1069 #endif /* not HAVE_TERMIO */
1071 /* If going to use CBREAK mode, we must request C-g to interrupt
1072 and turn off start and stop chars, etc. If not going to use
1073 CBREAK mode, do this anyway so as to turn off local flow
1074 control for user coming over network on 4.2; in this case,
1075 only t_stopc and t_startc really matter. */
1078 /* Note: if not using CBREAK mode, it makes no difference how we
1080 tty
.tchars
= new_tchars
;
1081 tty
.tchars
.t_intrc
= quit_char
;
1084 tty
.tchars
.t_startc
= '\021';
1085 tty
.tchars
.t_stopc
= '\023';
1088 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
1094 #define LNOFLSH 0100000
1097 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1103 #endif /* HAVE_TCHARS */
1104 #endif /* not HAVE_TERMIO */
1107 tty
.ltchars
= new_ltchars
;
1108 #endif /* HAVE_LTCHARS */
1110 EMACS_SET_TTY (input_fd
, &tty
, 0);
1112 /* This code added to insure that, if flow-control is not to be used,
1113 we have an unlocked terminal at the start. */
1116 if (!flow_control
) ioctl (0, TCXONC
, 1);
1120 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
1128 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1129 to be only LF. This is the way that is done. */
1132 if (ioctl (1, HFTGETID
, &tty
) != -1)
1133 write (1, "\033[20l", 5);
1139 /* Appears to do nothing when in PASTHRU mode.
1140 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1141 interrupt_signal, oob_chars, 0, 0, 0, 0);
1143 queue_kbd_input (0);
1148 #ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
1149 if (interrupt_input
)
1151 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
1152 fcntl (0, F_SETOWN
, getpid ());
1155 #endif /* F_GETOWN */
1156 #endif /* F_SETFL */
1159 if (interrupt_input
)
1163 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1167 /* This symbol is defined on recent USG systems.
1168 Someone says without this call USG won't really buffer the file
1169 even with a call to setbuf. */
1170 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1172 setbuf (stdout
, _sobuf
);
1174 set_terminal_modes ();
1175 if (term_initted
&& no_redraw_on_reenter
)
1177 if (display_completed
)
1178 direct_output_forward_char (0);
1184 if (FRAMEP (Vterminal_frame
))
1185 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1192 /* Return nonzero if safe to use tabs in output.
1193 At the time this is called, init_sys_modes has not been done yet. */
1197 struct emacs_tty tty
;
1199 EMACS_GET_TTY (input_fd
, &tty
);
1200 return EMACS_TTY_TABS_OK (&tty
);
1203 /* Get terminal size from system.
1204 Store number of lines into *heightp and width into *widthp.
1205 If zero or a negative number is stored, the value is not valid. */
1207 get_frame_size (widthp
, heightp
)
1208 int *widthp
, *heightp
;
1214 struct winsize size
;
1216 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1217 *widthp
= *heightp
= 0;
1220 *widthp
= size
.ws_col
;
1221 *heightp
= size
.ws_row
;
1227 /* SunOS - style. */
1228 struct ttysize size
;
1230 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1231 *widthp
= *heightp
= 0;
1234 *widthp
= size
.ts_cols
;
1235 *heightp
= size
.ts_lines
;
1241 struct sensemode tty
;
1243 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1244 &tty
.class, 12, 0, 0, 0, 0);
1245 *widthp
= tty
.scr_wid
;
1246 *heightp
= tty
.scr_len
;
1248 #else /* system doesn't know size */
1253 #endif /* not VMS */
1254 #endif /* not SunOS-style */
1255 #endif /* not BSD-style */
1259 /* Prepare the terminal for exiting Emacs; move the cursor to the
1260 bottom of the frame, turn off interrupt-driven I/O, etc. */
1270 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1272 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1273 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1274 /* clear_end_of_line may move the cursor */
1275 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1278 /* HFT devices normally use ^J as a LF/CR. We forced it to
1279 do the LF only. Now, we need to reset it. */
1282 if (ioctl (1, HFTGETID
, &tty
) != -1)
1283 write (1, "\033[20h", 5);
1287 reset_terminal_modes ();
1291 /* Avoid possible loss of output when changing terminal modes. */
1292 fsync (fileno (stdout
));
1297 #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */
1298 if (interrupt_input
)
1301 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1303 #endif /* F_SETOWN */
1304 #endif /* F_SETFL */
1306 if (interrupt_input
)
1310 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1320 /* Set up the proper status flags for use of a pty. */
1325 /* I'm told that TOICREMOTE does not mean control chars
1326 "can't be sent" but rather that they don't have
1327 input-editing or signaling effects.
1328 That should be good, because we have other ways
1329 to do those things in Emacs.
1330 However, telnet mode seems not to work on 4.2.
1331 So TIOCREMOTE is turned off now. */
1333 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1334 will hang. In particular, the "timeout" feature (which
1335 causes a read to return if there is no data available)
1336 does this. Also it is known that telnet mode will hang
1337 in such a way that Emacs must be stopped (perhaps this
1338 is the same problem).
1340 If TIOCREMOTE is turned off, then there is a bug in
1341 hp-ux which sometimes loses data. Apparently the
1342 code which blocks the master process when the internal
1343 buffer fills up does not work. Other than this,
1344 though, everything else seems to work fine.
1346 Since the latter lossage is more benign, we may as well
1347 lose that way. -- cph */
1352 ioctl (fd
, FIONBIO
, &on
);
1357 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1358 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1359 /* cause EMACS not to die when it should, i.e., when its own controlling */
1360 /* tty goes away. I've complained to the AIX developers, and they may */
1361 /* change this behavior, but I'm not going to hold my breath. */
1362 signal (SIGHUP
, SIG_IGN
);
1365 #endif /* HAVE_PTYS */
1369 /* Assigning an input channel is done at the start of Emacs execution.
1370 This is called each time Emacs is resumed, also, but does nothing
1371 because input_chain is no longer zero. */
1379 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1385 /* Deassigning the input channel is done before exiting. */
1389 return SYS$
DASSGN (input_fd
);
1394 /* Request reading one character into the keyboard buffer.
1395 This is done as soon as the buffer becomes empty. */
1400 extern kbd_input_ast ();
1402 waiting_for_ast
= 0;
1404 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1405 &input_iosb
, kbd_input_ast
, 1,
1406 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1411 /* Ast routine that is called when keyboard input comes in
1412 in accord with the SYS$QIO above. */
1416 register int c
= -1;
1417 int old_errno
= errno
;
1418 extern EMACS_TIME
*input_available_clear_time
;
1420 if (waiting_for_ast
)
1421 SYS$
SETEF (input_ef
);
1422 waiting_for_ast
= 0;
1425 if (input_count
== 25)
1427 printf ("Ast # %d,", input_count
);
1428 printf (" iosb = %x, %x, %x, %x",
1429 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1432 if (input_iosb
.offset
)
1436 printf (", char = 0%o", c
);
1448 struct input_event e
;
1449 e
.kind
= ascii_keystroke
;
1450 XSET (e
.code
, Lisp_Int
, c
);
1452 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1454 e
.frame_or_window
= Qnil
;
1456 kbd_buffer_store_event (&e
);
1458 if (input_available_clear_time
)
1459 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1463 /* Wait until there is something in kbd_buffer. */
1465 wait_for_kbd_input ()
1467 extern int have_process_input
, process_exited
;
1469 /* If already something, avoid doing system calls. */
1470 if (detect_input_pending ())
1474 /* Clear a flag, and tell ast routine above to set it. */
1475 SYS$
CLREF (input_ef
);
1476 waiting_for_ast
= 1;
1477 /* Check for timing error: ast happened while we were doing that. */
1478 if (!detect_input_pending ())
1480 /* No timing error: wait for flag to be set. */
1481 set_waiting_for_input (0);
1482 SYS$
WFLOR (input_ef
, input_eflist
);
1483 clear_waiting_for_input (0);
1484 if (!detect_input_pending ())
1485 /* Check for subprocess input availability */
1487 int dsp
= have_process_input
|| process_exited
;
1489 SYS$
CLREF (process_ef
);
1490 if (have_process_input
)
1491 process_command_input ();
1496 update_mode_lines
++;
1497 redisplay_preserve_echo_area ();
1501 waiting_for_ast
= 0;
1504 /* Get rid of any pending QIO, when we are about to suspend
1505 or when we want to throw away pending input.
1506 We wait for a positive sign that the AST routine has run
1507 and therefore there is no I/O request queued when we return.
1508 SYS$SETAST is used to avoid a timing error. */
1513 printf ("At end_kbd_input.\n");
1517 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1519 SYS$
CANCEL (input_fd
);
1524 /* Clear a flag, and tell ast routine above to set it. */
1525 SYS$
CLREF (input_ef
);
1526 waiting_for_ast
= 1;
1528 SYS$
CANCEL (input_fd
);
1530 SYS$
WAITFR (input_ef
);
1531 waiting_for_ast
= 0;
1534 /* Wait for either input available or time interval expiry. */
1536 input_wait_timeout (timeval
)
1537 int timeval
; /* Time to wait, in seconds */
1540 static int zero
= 0;
1541 static int large
= -10000000;
1543 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1545 /* If already something, avoid doing system calls. */
1546 if (detect_input_pending ())
1550 /* Clear a flag, and tell ast routine above to set it. */
1551 SYS$
CLREF (input_ef
);
1552 waiting_for_ast
= 1;
1553 /* Check for timing error: ast happened while we were doing that. */
1554 if (!detect_input_pending ())
1556 /* No timing error: wait for flag to be set. */
1558 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1559 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1561 waiting_for_ast
= 0;
1564 /* The standard `sleep' routine works some other way
1565 and it stops working if you have ever quit out of it.
1566 This one continues to work. */
1572 static int zero
= 0;
1573 static int large
= -10000000;
1575 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1578 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1579 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1594 croak ("request sigio");
1599 croak ("unrequest sigio");
1604 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1609 #ifndef SYSTEM_MALLOC
1616 /* Some systems that cannot dump also cannot implement these. */
1619 * Return the address of the start of the text segment prior to
1620 * doing an unexec. After unexec the return value is undefined.
1621 * See crt0.c for further explanation and _start.
1625 #ifndef CANNOT_UNEXEC
1630 return ((char *) TEXT_START
);
1634 return ((char *) csrt
);
1635 #else /* not GOULD */
1636 extern int _start ();
1637 return ((char *) _start
);
1639 #endif /* TEXT_START */
1641 #endif /* not CANNOT_UNEXEC */
1644 * Return the address of the start of the data segment prior to
1645 * doing an unexec. After unexec the return value is undefined.
1646 * See crt0.c for further information and definition of data_start.
1648 * Apparently, on BSD systems this is etext at startup. On
1649 * USG systems (swapping) this is highly mmu dependent and
1650 * is also dependent on whether or not the program is running
1651 * with shared text. Generally there is a (possibly large)
1652 * gap between end of text and start of data with shared text.
1654 * On Uniplus+ systems with shared text, data starts at a
1655 * fixed address. Each port (from a given oem) is generally
1656 * different, and the specific value of the start of data can
1657 * be obtained via the UniPlus+ specific "uvar" system call,
1658 * however the method outlined in crt0.c seems to be more portable.
1660 * Probably what will have to happen when a USG unexec is available,
1661 * at least on UniPlus, is temacs will have to be made unshared so
1662 * that text and data are contiguous. Then once loadup is complete,
1663 * unexec will produce a shared executable where the data can be
1664 * at the normal shared text boundry and the startofdata variable
1665 * will be patched by unexec to the correct value.
1673 return ((char *) DATA_START
);
1675 #ifdef ORDINARY_LINK
1677 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1678 * data_start isn't defined. We take the address of environ, which
1679 * is known to live at or near the start of the system crt0.c, and
1680 * we don't sweat the handful of bytes that might lose.
1682 extern char **environ
;
1684 return((char *) &environ
);
1686 extern int data_start
;
1687 return ((char *) &data_start
);
1688 #endif /* ORDINARY_LINK */
1689 #endif /* DATA_START */
1691 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1694 /* Some systems that cannot dump also cannot implement these. */
1697 * Return the address of the end of the text segment prior to
1698 * doing an unexec. After unexec the return value is undefined.
1705 return ((char *) TEXT_END
);
1708 return ((char *) &etext
);
1713 * Return the address of the end of the data segment prior to
1714 * doing an unexec. After unexec the return value is undefined.
1721 return ((char *) DATA_END
);
1724 return ((char *) &edata
);
1728 #endif /* not CANNOT_DUMP */
1730 /* Get_system_name returns as its value
1731 a string for the Lisp function system-name to return. */
1737 /* Can't have this within the function since `static' is #defined to
1738 nothing for some USG systems. */
1740 #ifdef HAVE_GETHOSTNAME
1741 static char get_system_name_name
[256];
1742 #else /* not HAVE_GETHOSTNAME */
1743 static struct utsname get_system_name_name
;
1744 #endif /* not HAVE_GETHOSTNAME */
1751 #include <sys/socket.h>
1753 #endif /* HAVE_SOCKETS */
1754 #endif /* not VMS */
1755 #endif /* not USG */
1756 #endif /* not BSD4_1 */
1762 #ifdef HAVE_GETHOSTNAME
1763 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1764 return get_system_name_name
;
1765 #else /* not HAVE_GETHOSTNAME */
1766 uname (&get_system_name_name
);
1767 return (get_system_name_name
.nodename
);
1768 #endif /* not HAVE_GETHOSTNAME */
1772 #else /* not USG, not 4.1 */
1773 static char system_name_saved
[32];
1776 if ((sp
= egetenv ("SYS$NODE")) == 0)
1782 if ((end
= index (sp
, ':')) != 0)
1785 strcpy (system_name_saved
, sp
);
1787 gethostname (system_name_saved
, sizeof (system_name_saved
));
1789 /* Turn the hostname into the official, fully-qualified hostname.
1790 Don't do this if we're going to dump; this can confuse system
1791 libraries on some machines and make the dumped emacs core dump. */
1794 #endif /* not CANNOT_DUMP */
1797 hp
= gethostbyname (system_name_saved
);
1798 if (hp
&& strlen (hp
->h_name
) < sizeof(system_name_saved
))
1799 strcpy (system_name_saved
, hp
->h_name
);
1801 #endif /* HAVE_SOCKETS */
1802 #endif /* not VMS */
1803 return system_name_saved
;
1804 #endif /* not USG, not 4.1 */
1805 #endif /* not USG */
1809 #ifndef HAVE_GETHOSTNAME
1810 void gethostname(buf
, len
)
1815 s
= getenv ("SYS$NODE");
1819 strncpy (buf
, s
, len
- 2);
1820 buf
[len
- 1] = '\0';
1822 } /* static void gethostname */
1823 #endif /* ! HAVE_GETHOSTNAME */
1830 #ifdef HAVE_X_WINDOWS
1831 /* Cause explanatory error message at compile time,
1832 since the select emulation is not good enough for X. */
1833 int *x
= &x_windows_lose_if_no_select_system_call
;
1836 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1837 * Only checks read descriptors.
1839 /* How long to wait between checking fds in select */
1840 #define SELECT_PAUSE 1
1843 /* For longjmp'ing back to read_input_waiting. */
1845 jmp_buf read_alarm_throw
;
1847 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1848 The read_socket_hook function sets this to 1 while it is waiting. */
1850 int read_alarm_should_throw
;
1858 #else /* not BSD4_1 */
1859 signal (SIGALRM
, SIG_IGN
);
1860 #endif /* not BSD4_1 */
1861 if (read_alarm_should_throw
)
1862 longjmp (read_alarm_throw
, 1);
1865 /* Only rfds are checked. */
1867 select (nfds
, rfds
, wfds
, efds
, timeout
)
1869 int *rfds
, *wfds
, *efds
, *timeout
;
1871 int ravail
= 0, orfds
= 0, old_alarm
;
1872 int timeoutval
= timeout
? *timeout
: 100000;
1873 int *local_timeout
= &timeoutval
;
1874 extern int proc_buffered_char
[];
1875 #ifndef subprocesses
1876 int process_tick
= 0, update_tick
= 0;
1878 extern int process_tick
, update_tick
;
1880 SIGTYPE (*old_trap
) ();
1893 /* If we are looking only for the terminal, with no timeout,
1894 just read it and wait -- that's more efficient. */
1895 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1897 if (! detect_input_pending ())
1898 read_input_waiting ();
1903 /* Once a second, till the timer expires, check all the flagged read
1904 * descriptors to see if any input is available. If there is some then
1905 * set the corresponding bit in the return copy of rfds.
1909 register int to_check
, bit
, fd
;
1913 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1917 int avail
= 0, status
= 0;
1920 avail
= detect_input_pending (); /* Special keyboard handler */
1924 status
= ioctl (fd
, FIONREAD
, &avail
);
1925 #else /* no FIONREAD */
1926 /* Hoping it will return -1 if nothing available
1927 or 0 if all 0 chars requested are read. */
1928 if (proc_buffered_char
[fd
] >= 0)
1932 avail
= read (fd
, &buf
, 1);
1934 proc_buffered_char
[fd
] = buf
;
1936 #endif /* no FIONREAD */
1938 if (status
>= 0 && avail
> 0)
1946 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
1948 old_alarm
= alarm (0);
1949 old_trap
= signal (SIGALRM
, select_alarm
);
1951 alarm (SELECT_PAUSE
);
1952 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1953 while (select_alarmed
== 0 && *local_timeout
!= 0
1954 && process_tick
== update_tick
)
1956 /* If we are interested in terminal input,
1957 wait by reading the terminal.
1958 That makes instant wakeup for terminal input at least. */
1961 read_input_waiting ();
1962 if (detect_input_pending ())
1968 (*local_timeout
) -= SELECT_PAUSE
;
1969 /* Reset the old alarm if there was one */
1971 signal (SIGALRM
, old_trap
);
1974 /* Reset or forge an interrupt for the original handler. */
1975 old_alarm
-= SELECT_PAUSE
;
1977 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
1981 if (*local_timeout
== 0) /* Stop on timer being cleared */
1987 /* Read keyboard input into the standard buffer,
1988 waiting for at least one character. */
1990 /* Make all keyboard buffers much bigger when using X windows. */
1991 #ifdef HAVE_X_WINDOWS
1992 #define BUFFER_SIZE_FACTOR 16
1994 #define BUFFER_SIZE_FACTOR 1
1997 read_input_waiting ()
1999 char buf
[256 * BUFFER_SIZE_FACTOR
];
2000 struct input_event e
;
2002 extern int quit_char
;
2004 if (read_socket_hook
)
2006 read_alarm_should_throw
= 0;
2007 if (! setjmp (read_alarm_throw
))
2008 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
2013 nread
= read (fileno (stdin
), buf
, 1);
2015 /* Scan the chars for C-g and store them in kbd_buffer. */
2016 e
.kind
= ascii_keystroke
;
2017 e
.frame_or_window
= selected_frame
;
2019 for (i
= 0; i
< nread
; i
++)
2021 XSET (e
.code
, Lisp_Int
, buf
[i
]);
2022 kbd_buffer_store_event (&e
);
2023 /* Don't look at input that follows a C-g too closely.
2024 This reduces lossage due to autorepeat on C-g. */
2025 if (buf
[i
] == quit_char
)
2030 #endif /* not HAVE_SELECT */
2031 #endif /* not VMS */
2035 * Partially emulate 4.2 open call.
2036 * open is defined as this in 4.1.
2038 * - added by Michael Bloom @ Citicorp/TTI
2043 sys_open (path
, oflag
, mode
)
2047 if (oflag
& O_CREAT
)
2048 return creat (path
, mode
);
2050 return open (path
, oflag
);
2057 lmode
= LINTRUP
| lmode
;
2058 ioctl (0, TIOCLSET
, &lmode
);
2065 lmode
= ~LINTRUP
& lmode
;
2066 ioctl (0, TIOCLSET
, &lmode
);
2073 interrupts_deferred
= 0;
2080 interrupts_deferred
= 1;
2083 /* still inside #ifdef BSD4_1 */
2086 int sigheld
; /* Mask of held signals */
2091 sigheld
|= sigbit (signum
);
2098 sigheld
|= sigbit (signum
);
2104 sigheld
&= ~sigbit (signum
);
2108 sigfree () /* Free all held signals */
2111 for (i
= 0; i
< NSIG
; i
++)
2112 if (sigheld
& sigbit (i
))
2119 return 1 << (i
- 1);
2121 #endif /* subprocesses */
2124 /* POSIX signals support - DJB */
2125 /* Anyone with POSIX signals should have ANSI C declarations */
2127 #ifdef POSIX_SIGNALS
2129 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
2130 static struct sigaction new_action
, old_action
;
2134 sigemptyset (&empty_mask
);
2135 sigfillset (&full_mask
);
2139 sys_signal (int signal_number
, signal_handler_t action
)
2142 /* This gets us restartable system calls for efficiency.
2143 The "else" code will works as well. */
2144 return (berk_signal (signal_number
, action
));
2146 sigemptyset (&new_action
.sa_mask
);
2147 new_action
.sa_handler
= action
;
2148 new_action
.sa_flags
= 0;
2149 sigaction (signal_number
, &new_action
, &old_action
);
2150 return (old_action
.sa_handler
);
2155 /* If we're compiling with GCC, we don't need this function, since it
2156 can be written as a macro. */
2158 sys_sigmask (int sig
)
2161 sigemptyset (&mask
);
2162 sigaddset (&mask
, sig
);
2168 sys_sigpause (sigset_t new_mask
)
2170 /* pause emulating berk sigpause... */
2171 sigsuspend (&new_mask
);
2175 /* I'd like to have these guys return pointers to the mask storage in here,
2176 but there'd be trouble if the code was saving multiple masks. I'll be
2177 safe and pass the structure. It normally won't be more than 2 bytes
2181 sys_sigblock (sigset_t new_mask
)
2184 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2189 sys_sigunblock (sigset_t new_mask
)
2192 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2197 sys_sigsetmask (sigset_t new_mask
)
2200 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2204 #endif /* POSIX_SIGNALS */
2211 register int length
;
2215 long max_str
= 65535;
2217 while (length
> max_str
) {
2218 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2223 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2225 while (length
-- > 0)
2227 #endif /* not VMS */
2230 /* Saying `void' requires a declaration, above, where bcopy is used
2231 and that declaration causes pain for systems where bcopy is a macro. */
2232 bcopy (b1
, b2
, length
)
2235 register int length
;
2238 long max_str
= 65535;
2240 while (length
> max_str
) {
2241 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2247 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2249 while (length
-- > 0)
2251 #endif /* not VMS */
2255 bcmp (b1
, b2
, length
) /* This could be a macro! */
2258 register int length
;
2261 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2262 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2264 return STR$
COMPARE (&src1
, &src2
);
2266 while (length
-- > 0)
2271 #endif /* not VMS */
2273 #endif /* not BSTRING */
2278 * The BSD random returns numbers in the range of
2279 * 0 to 2e31 - 1. The USG rand returns numbers in the
2280 * range of 0 to 2e15 - 1. This is probably not significant
2287 /* Arrange to return a range centered on zero. */
2288 return (rand () << 15) + rand () - (1 << 29);
2302 /* Arrange to return a range centered on zero. */
2303 return (rand () << 15) + rand () - (1 << 29);
2314 #ifdef WRONG_NAME_INSQUE
2327 /* If any place else asks for the TERM variable,
2328 allow it to be overridden with the EMACS_TERM variable
2329 before attempting to translate the logical name TERM. As a last
2330 resort, ask for VAX C's special idea of the TERM variable. */
2337 static char buf
[256];
2338 static struct dsc$descriptor_s equiv
2339 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2340 static struct dsc$descriptor_s d_name
2341 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2344 if (!strcmp (name
, "TERM"))
2346 val
= (char *) getenv ("EMACS_TERM");
2351 d_name
.dsc$w_length
= strlen (name
);
2352 d_name
.dsc$a_pointer
= name
;
2353 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2355 char *str
= (char *) xmalloc (eqlen
+ 1);
2356 bcopy (buf
, str
, eqlen
);
2358 /* This is a storage leak, but a pain to fix. With luck,
2359 no one will ever notice. */
2362 return (char *) getenv (name
);
2367 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2368 to force a call on the debugger from within the image. */
2373 LIB$
SIGNAL (SS$_DEBUG
);
2379 #ifdef LINK_CRTL_SHARE
2380 #ifdef SHAREABLE_LIB_BUG
2381 /* Variables declared noshare and initialized in shareable libraries
2382 cannot be shared. The VMS linker incorrectly forces you to use a private
2383 version which is uninitialized... If not for this "feature", we
2384 could use the C library definition of sys_nerr and sys_errlist. */
2386 char *sys_errlist
[] =
2390 "no such file or directory",
2392 "interrupted system call",
2394 "no such device or address",
2395 "argument list too long",
2396 "exec format error",
2399 "no more processes",
2400 "not enough memory",
2401 "permission denied",
2403 "block device required",
2404 "mount devices busy",
2406 "cross-device link",
2411 "file table overflow",
2412 "too many open files",
2416 "no space left on device",
2418 "read-only file system",
2424 "vax/vms specific error code nontranslatable error"
2426 #endif /* SHAREABLE_LIB_BUG */
2427 #endif /* LINK_CRTL_SHARE */
2430 #ifdef INTERRUPTIBLE_OPEN
2434 sys_open (path
, oflag
, mode
)
2438 register int rtnval
;
2440 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2441 && (errno
== EINTR
));
2445 #endif /* INTERRUPTIBLE_OPEN */
2447 #ifdef INTERRUPTIBLE_CLOSE
2452 register int rtnval
;
2454 while ((rtnval
= close (fd
)) == -1
2455 && (errno
== EINTR
));
2459 #endif /* INTERRUPTIBLE_CLOSE */
2461 #ifdef INTERRUPTIBLE_IO
2464 sys_read (fildes
, buf
, nbyte
)
2469 register int rtnval
;
2471 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2472 && (errno
== EINTR
));
2477 sys_write (fildes
, buf
, nbyte
)
2482 register int rtnval
;
2484 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2485 && (errno
== EINTR
));
2489 #endif /* INTERRUPTIBLE_IO */
2493 * All of the following are for USG.
2495 * On USG systems the system calls are INTERRUPTIBLE by signals
2496 * that the user program has elected to catch. Thus the system call
2497 * must be retried in these cases. To handle this without massive
2498 * changes in the source code, we remap the standard system call names
2499 * to names for our own functions in sysdep.c that do the system call
2500 * with retries. Actually, for portability reasons, it is good
2501 * programming practice, as this example shows, to limit all actual
2502 * system calls to a single occurance in the source. Sure, this
2503 * adds an extra level of function call overhead but it is almost
2504 * always negligible. Fred Fish, Unisoft Systems Inc.
2507 #ifndef HAVE_SYS_SIGLIST
2508 char *sys_siglist
[NSIG
+ 1] =
2511 /* AIX has changed the signals a bit */
2512 "bogus signal", /* 0 */
2513 "hangup", /* 1 SIGHUP */
2514 "interrupt", /* 2 SIGINT */
2515 "quit", /* 3 SIGQUIT */
2516 "illegal instruction", /* 4 SIGILL */
2517 "trace trap", /* 5 SIGTRAP */
2518 "IOT instruction", /* 6 SIGIOT */
2519 "crash likely", /* 7 SIGDANGER */
2520 "floating point exception", /* 8 SIGFPE */
2521 "kill", /* 9 SIGKILL */
2522 "bus error", /* 10 SIGBUS */
2523 "segmentation violation", /* 11 SIGSEGV */
2524 "bad argument to system call", /* 12 SIGSYS */
2525 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2526 "alarm clock", /* 14 SIGALRM */
2527 "software termination signum", /* 15 SIGTERM */
2528 "user defined signal 1", /* 16 SIGUSR1 */
2529 "user defined signal 2", /* 17 SIGUSR2 */
2530 "death of a child", /* 18 SIGCLD */
2531 "power-fail restart", /* 19 SIGPWR */
2532 "bogus signal", /* 20 */
2533 "bogus signal", /* 21 */
2534 "bogus signal", /* 22 */
2535 "bogus signal", /* 23 */
2536 "bogus signal", /* 24 */
2537 "LAN I/O interrupt", /* 25 SIGAIO */
2538 "PTY I/O interrupt", /* 26 SIGPTY */
2539 "I/O intervention required", /* 27 SIGIOINT */
2540 "HFT grant", /* 28 SIGGRANT */
2541 "HFT retract", /* 29 SIGRETRACT */
2542 "HFT sound done", /* 30 SIGSOUND */
2543 "HFT input ready", /* 31 SIGMSG */
2545 "bogus signal", /* 0 */
2546 "hangup", /* 1 SIGHUP */
2547 "interrupt", /* 2 SIGINT */
2548 "quit", /* 3 SIGQUIT */
2549 "illegal instruction", /* 4 SIGILL */
2550 "trace trap", /* 5 SIGTRAP */
2551 "IOT instruction", /* 6 SIGIOT */
2552 "EMT instruction", /* 7 SIGEMT */
2553 "floating point exception", /* 8 SIGFPE */
2554 "kill", /* 9 SIGKILL */
2555 "bus error", /* 10 SIGBUS */
2556 "segmentation violation", /* 11 SIGSEGV */
2557 "bad argument to system call", /* 12 SIGSYS */
2558 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2559 "alarm clock", /* 14 SIGALRM */
2560 "software termination signum", /* 15 SIGTERM */
2561 "user defined signal 1", /* 16 SIGUSR1 */
2562 "user defined signal 2", /* 17 SIGUSR2 */
2563 "death of a child", /* 18 SIGCLD */
2564 "power-fail restart", /* 19 SIGPWR */
2565 #endif /* not AIX */
2568 #endif /* HAVE_SYS_SIGLIST */
2571 * Warning, this function may not duplicate 4.2 action properly
2572 * under error conditions.
2576 /* In 4.1, param.h fails to define this. */
2577 #define MAXPATHLEN 1024
2586 char *npath
, *spath
;
2587 extern char *getcwd ();
2589 BLOCK_INPUT
; /* getcwd uses malloc */
2590 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2591 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2592 up to first slash. Should be harmless on other systems. */
2593 while (*npath
&& *npath
!= '/')
2595 strcpy (pathname
, npath
);
2596 free (spath
); /* getcwd uses malloc */
2601 #endif /* HAVE_GETWD */
2604 * Emulate rename using unlink/link. Note that this is
2605 * only partially correct. Also, doesn't enforce restriction
2606 * that files be of same type (regular->regular, dir->dir, etc).
2615 if (access (from
, 0) == 0)
2618 if (link (from
, to
) == 0)
2619 if (unlink (from
) == 0)
2630 * Substitute fork for vfork on USG flavors.
2638 #endif /* not HAVE_VFORK */
2640 #ifdef MISSING_UTIMES
2642 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2651 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2652 utimbuf structure defined anywhere but in the man page. */
2662 struct timeval tvp
[];
2665 utb
.actime
= tvp
[0].tv_sec
;
2666 utb
.modtime
= tvp
[1].tv_sec
;
2669 #endif /* IRIS_UTIME */
2675 /* HPUX curses library references perror, but as far as we know
2676 it won't be called. Anyway this definition will do for now. */
2682 #endif /* not HAVE_PERROR */
2688 * Emulate BSD dup2. First close newd if it already exists.
2689 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2690 * until we are, then close the unsuccessful ones.
2697 register int fd
, ret
;
2702 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2704 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2711 ret
= dup2 (old
,new);
2717 #endif /* not HAVE_DUP2 */
2720 * Gettimeofday. Simulate as much as possible. Only accurate
2721 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2722 * Only needed when subprocesses are defined.
2727 #ifndef HAVE_GETTIMEOFDAY
2731 gettimeofday (tp
, tzp
)
2733 struct timezone
*tzp
;
2735 extern long time ();
2737 tp
->tv_sec
= time ((long *)0);
2740 tzp
->tz_minuteswest
= -1;
2746 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2749 * This function will go away as soon as all the stubs fixed. (fnf)
2755 printf ("%s not yet implemented\r\n", badfunc
);
2764 char *sys_siglist
[NSIG
+ 1] =
2766 "null signal", /* 0 SIGNULL */
2767 "hangup", /* 1 SIGHUP */
2768 "interrupt", /* 2 SIGINT */
2769 "quit", /* 3 SIGQUIT */
2770 "illegal instruction", /* 4 SIGILL */
2771 "trace trap", /* 5 SIGTRAP */
2772 "abort termination", /* 6 SIGABRT */
2773 "SIGEMT", /* 7 SIGEMT */
2774 "floating point exception", /* 8 SIGFPE */
2775 "kill", /* 9 SIGKILL */
2776 "bus error", /* 10 SIGBUS */
2777 "segmentation violation", /* 11 SIGSEGV */
2778 "bad argument to system call", /* 12 SIGSYS */
2779 "write on a pipe with no reader", /* 13 SIGPIPE */
2780 "alarm clock", /* 14 SIGALRM */
2781 "software termination signal", /* 15 SIGTERM */
2782 "user defined signal 1", /* 16 SIGUSR1 */
2783 "user defined signal 2", /* 17 SIGUSR2 */
2784 "child stopped or terminated", /* 18 SIGCLD */
2785 "power-fail restart", /* 19 SIGPWR */
2786 "window size changed", /* 20 SIGWINCH */
2787 "undefined", /* 21 */
2788 "pollable event occured", /* 22 SIGPOLL */
2789 "sendable stop signal not from tty", /* 23 SIGSTOP */
2790 "stop signal from tty", /* 24 SIGSTP */
2791 "continue a stopped process", /* 25 SIGCONT */
2792 "attempted background tty read", /* 26 SIGTTIN */
2793 "attempted background tty write", /* 27 SIGTTOU */
2794 "undefined", /* 28 */
2795 "undefined", /* 29 */
2796 "undefined", /* 30 */
2797 "undefined", /* 31 */
2798 "undefined", /* 32 */
2799 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2800 "I/O is possible", /* 34 SIGIO */
2801 "exceeded cpu time limit", /* 35 SIGXCPU */
2802 "exceeded file size limit", /* 36 SIGXFSZ */
2803 "virtual time alarm", /* 37 SIGVTALRM */
2804 "profiling time alarm", /* 38 SIGPROF */
2805 "undefined", /* 39 */
2806 "file record locks revoked", /* 40 SIGLOST */
2807 "undefined", /* 41 */
2808 "undefined", /* 42 */
2809 "undefined", /* 43 */
2810 "undefined", /* 44 */
2811 "undefined", /* 45 */
2812 "undefined", /* 46 */
2813 "undefined", /* 47 */
2814 "undefined", /* 48 */
2815 "undefined", /* 49 */
2816 "undefined", /* 50 */
2817 "undefined", /* 51 */
2818 "undefined", /* 52 */
2819 "undefined", /* 53 */
2820 "undefined", /* 54 */
2821 "undefined", /* 55 */
2822 "undefined", /* 56 */
2823 "undefined", /* 57 */
2824 "undefined", /* 58 */
2825 "undefined", /* 59 */
2826 "undefined", /* 60 */
2827 "undefined", /* 61 */
2828 "undefined", /* 62 */
2829 "undefined", /* 63 */
2830 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2836 /* Directory routines for systems that don't have them. */
2838 #ifdef SYSV_SYSTEM_DIR
2845 register DIR *dirp
; /* stream from opendir */
2847 sys_close (dirp
->dd_fd
);
2848 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2849 xfree ((char *) dirp
);
2851 #endif /* not AIX */
2852 #endif /* SYSV_SYSTEM_DIR */
2854 #ifdef NONSYSTEM_DIR_LIBRARY
2858 char *filename
; /* name of directory */
2860 register DIR *dirp
; /* -> malloc'ed storage */
2861 register int fd
; /* file descriptor for read */
2862 struct stat sbuf
; /* result of fstat */
2864 fd
= sys_open (filename
, 0);
2869 if (fstat (fd
, &sbuf
) < 0
2870 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2871 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2875 return 0; /* bad luck today */
2880 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2887 register DIR *dirp
; /* stream from opendir */
2889 sys_close (dirp
->dd_fd
);
2890 xfree ((char *) dirp
);
2898 ino_t od_ino
; /* inode */
2899 char od_name
[DIRSIZ
]; /* filename */
2901 #endif /* not VMS */
2903 struct direct dir_static
; /* simulated directory contents */
2908 register DIR *dirp
; /* stream from opendir */
2911 register struct olddir
*dp
; /* -> directory data */
2913 register struct dir$_name
*dp
; /* -> directory data */
2914 register struct dir$_version
*dv
; /* -> version data */
2919 if (dirp
->dd_loc
>= dirp
->dd_size
)
2920 dirp
->dd_loc
= dirp
->dd_size
= 0;
2922 if (dirp
->dd_size
== 0 /* refill buffer */
2923 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2927 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
2928 dirp
->dd_loc
+= sizeof (struct olddir
);
2930 if (dp
->od_ino
!= 0) /* not deleted entry */
2932 dir_static
.d_ino
= dp
->od_ino
;
2933 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
2934 dir_static
.d_name
[DIRSIZ
] = '\0';
2935 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2936 dir_static
.d_reclen
= sizeof (struct direct
)
2938 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2939 return &dir_static
; /* -> simulated structure */
2942 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2943 if (dirp
->dd_loc
== 0)
2944 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
2945 : dp
->dir$b_namecount
;
2946 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
2947 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2948 dir_static
.d_namlen
= dp
->dir$b_namecount
;
2949 dir_static
.d_reclen
= sizeof (struct direct
)
2951 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2952 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2953 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
2954 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
2961 /* readdirver is just like readdir except it returns all versions of a file
2962 as separate entries. */
2967 register DIR *dirp
; /* stream from opendir */
2969 register struct dir$_name
*dp
; /* -> directory data */
2970 register struct dir$_version
*dv
; /* -> version data */
2972 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
2973 dirp
->dd_loc
= dirp
->dd_size
= 0;
2975 if (dirp
->dd_size
== 0 /* refill buffer */
2976 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2979 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2980 if (dirp
->dd_loc
== 0)
2981 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
2982 : dp
->dir$b_namecount
;
2983 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
2984 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2985 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
2986 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2987 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2988 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
2989 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2990 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
2996 #endif /* NONSYSTEM_DIR_LIBRARY */
2998 /* Functions for VMS */
3000 #include "vms-pwd.h"
3005 /* Return as a string the VMS error string pertaining to STATUS.
3006 Reuses the same static buffer each time it is called. */
3010 int status
; /* VMS status code */
3014 static char buf
[257];
3016 bufadr
[0] = sizeof buf
- 1;
3017 bufadr
[1] = (int) buf
;
3018 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3019 return "untranslatable VMS error status";
3027 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3028 * not work correctly. (It also doesn't work well in version 2.3.)
3033 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3034 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3038 unsigned short s_buflen
;
3039 unsigned short s_code
;
3041 unsigned short *s_retlenadr
;
3045 #define buflen s.s_buflen
3046 #define code s.s_code
3047 #define bufadr s.s_bufadr
3048 #define retlenadr s.s_retlenadr
3050 #define R_OK 4 /* test for read permission */
3051 #define W_OK 2 /* test for write permission */
3052 #define X_OK 1 /* test for execute (search) permission */
3053 #define F_OK 0 /* test for presence of file */
3056 sys_access (path
, mode
)
3060 static char *user
= NULL
;
3063 /* translate possible directory spec into .DIR file name, so brain-dead
3064 * access can treat the directory like a file. */
3065 if (directory_file_name (path
, dir_fn
))
3069 return access (path
, mode
);
3070 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3076 unsigned short int dummy
;
3078 static int constant
= ACL$C_FILE
;
3079 DESCRIPTOR (path_desc
, path
);
3080 DESCRIPTOR (user_desc
, user
);
3084 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3087 acces
|= CHP$M_READ
;
3089 acces
|= CHP$M_WRITE
;
3090 itemlst
[0].buflen
= sizeof (int);
3091 itemlst
[0].code
= CHP$_FLAGS
;
3092 itemlst
[0].bufadr
= (char *) &flags
;
3093 itemlst
[0].retlenadr
= &dummy
;
3094 itemlst
[1].buflen
= sizeof (int);
3095 itemlst
[1].code
= CHP$_ACCESS
;
3096 itemlst
[1].bufadr
= (char *) &acces
;
3097 itemlst
[1].retlenadr
= &dummy
;
3098 itemlst
[2].end
= CHP$_END
;
3099 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3100 return stat
== SS$_NORMAL
? 0 : -1;
3104 #else /* not VMS4_4 */
3107 #define ACE$M_WRITE 2
3108 #define ACE$C_KEYID 1
3110 static unsigned short memid
, grpid
;
3111 static unsigned int uic
;
3113 /* Called from init_sys_modes, so it happens not very often
3114 but at least each time Emacs is loaded. */
3115 sys_access_reinit ()
3121 sys_access (filename
, type
)
3127 int status
, size
, i
, typecode
, acl_controlled
;
3128 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3129 union prvdef prvmask
;
3131 /* Get UIC and GRP values for protection checking. */
3134 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3137 memid
= uic
& 0xFFFF;
3141 if (type
!= 2) /* not checking write access */
3142 return access (filename
, type
);
3144 /* Check write protection. */
3146 #define CHECKPRIV(bit) (prvmask.bit)
3147 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3149 /* Find privilege bits */
3150 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3152 error ("Unable to find privileges: %s", vmserrstr (status
));
3153 if (CHECKPRIV (PRV$V_BYPASS
))
3154 return 0; /* BYPASS enabled */
3156 fab
.fab$b_fac
= FAB$M_GET
;
3157 fab
.fab$l_fna
= filename
;
3158 fab
.fab$b_fns
= strlen (filename
);
3159 fab
.fab$l_xab
= &xab
;
3160 xab
= cc$rms_xabpro
;
3161 xab
.xab$l_aclbuf
= aclbuf
;
3162 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3163 status
= SYS$
OPEN (&fab
, 0, 0);
3166 SYS$
CLOSE (&fab
, 0, 0);
3167 /* Check system access */
3168 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
3170 /* Check ACL entries, if any */
3172 if (xab
.xab$w_acllen
> 0)
3175 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3176 while (*aclptr
&& aclptr
< aclend
)
3178 size
= (*aclptr
& 0xff) / 4;
3179 typecode
= (*aclptr
>> 8) & 0xff;
3180 if (typecode
== ACE$C_KEYID
)
3181 for (i
= size
- 1; i
> 1; i
--)
3182 if (aclptr
[i
] == uic
)
3185 if (aclptr
[1] & ACE$M_WRITE
)
3186 return 0; /* Write access through ACL */
3188 aclptr
= &aclptr
[size
];
3190 if (acl_controlled
) /* ACL specified, prohibits write access */
3193 /* No ACL entries specified, check normal protection */
3194 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3196 if (WRITEABLE (XAB$V_GRP
) &&
3197 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3198 return 0; /* Group writeable */
3199 if (WRITEABLE (XAB$V_OWN
) &&
3200 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3201 return 0; /* Owner writeable */
3203 return -1; /* Not writeable */
3205 #endif /* not VMS4_4 */
3208 static char vtbuf
[NAM$C_MAXRSS
+1];
3210 /* translate a vms file spec to a unix path */
3212 sys_translate_vms (vfile
)
3223 /* leading device or logical name is a root directory */
3224 if (p
= strchr (vfile
, ':'))
3233 if (*p
== '[' || *p
== '<')
3235 while (*++vfile
!= *p
+ 2)
3239 if (vfile
[-1] == *p
)
3262 static char utbuf
[NAM$C_MAXRSS
+1];
3264 /* translate a unix path to a VMS file spec */
3266 sys_translate_unix (ufile
)
3289 if (index (&ufile
[1], '/'))
3296 if (index (&ufile
[1], '/'))
3303 if (strncmp (ufile
, "./", 2) == 0)
3310 ufile
++; /* skip the dot */
3311 if (index (&ufile
[1], '/'))
3316 else if (strncmp (ufile
, "../", 3) == 0)
3324 ufile
+= 2; /* skip the dots */
3325 if (index (&ufile
[1], '/'))
3350 extern char *getcwd ();
3352 #define MAXPATHLEN 1024
3354 ptr
= xmalloc (MAXPATHLEN
);
3355 getcwd (ptr
, MAXPATHLEN
);
3356 strcpy (pathname
, ptr
);
3364 long item_code
= JPI$_OWNER
;
3365 unsigned long parent_id
;
3368 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3371 vaxc$errno
= status
;
3381 return (getgid () << 16) | getuid ();
3385 sys_read (fildes
, buf
, nbyte
)
3390 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3395 sys_write (fildes
, buf
, nbyte
)
3400 register int nwrote
, rtnval
= 0;
3402 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3408 return rtnval
? rtnval
: -1;
3409 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3410 return rtnval
? rtnval
: -1;
3411 return (rtnval
+ nwrote
);
3416 * VAX/VMS VAX C RTL really loses. It insists that records
3417 * end with a newline (carriage return) character, and if they
3418 * don't it adds one (nice of it isn't it!)
3420 * Thus we do this stupidity below.
3424 sys_write (fildes
, buf
, nbytes
)
3427 unsigned int nbytes
;
3434 fstat (fildes
, &st
);
3440 /* Handle fixed-length files with carriage control. */
3441 if (st
.st_fab_rfm
== FAB$C_FIX
3442 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3444 len
= st
.st_fab_mrs
;
3445 retval
= write (fildes
, p
, min (len
, nbytes
));
3448 retval
++; /* This skips the implied carriage control */
3452 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3453 while (*e
!= '\n' && e
> p
) e
--;
3454 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3455 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3457 retval
= write (fildes
, p
, len
);
3468 /* Create file NEW copying its attributes from file OLD. If
3469 OLD is 0 or does not exist, create based on the value of
3472 /* Protection value the file should ultimately have.
3473 Set by create_copy_attrs, and use by rename_sansversions. */
3474 static unsigned short int fab_final_pro
;
3477 creat_copy_attrs (old
, new)
3480 struct FAB fab
= cc$rms_fab
;
3481 struct XABPRO xabpro
;
3482 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3483 extern int vms_stmlf_recfm
;
3487 fab
.fab$b_fac
= FAB$M_GET
;
3488 fab
.fab$l_fna
= old
;
3489 fab
.fab$b_fns
= strlen (old
);
3490 fab
.fab$l_xab
= (char *) &xabpro
;
3491 xabpro
= cc$rms_xabpro
;
3492 xabpro
.xab$l_aclbuf
= aclbuf
;
3493 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3494 /* Call $OPEN to fill in the fab & xabpro fields. */
3495 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3497 SYS$
CLOSE (&fab
, 0, 0);
3498 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3499 if (xabpro
.xab$w_acllen
> 0)
3501 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3502 /* If the acl buffer was too short, redo open with longer one.
3503 Wouldn't need to do this if there were some system imposed
3504 limit on the size of an ACL, but I can't find any such. */
3506 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3507 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3508 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3509 SYS$
CLOSE (&fab
, 0, 0);
3515 xabpro
.xab$l_aclbuf
= 0;
3520 fab
.fab$l_fna
= new;
3521 fab
.fab$b_fns
= strlen (new);
3525 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3526 fab
.fab$b_rat
= FAB$M_CR
;
3529 /* Set the file protections such that we will be able to manipulate
3530 this file. Once we are done writing and renaming it, we will set
3531 the protections back. */
3533 fab_final_pro
= xabpro
.xab$w_pro
;
3535 SYS$
SETDFPROT (0, &fab_final_pro
);
3536 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3538 /* Create the new file with either default attrs or attrs copied
3540 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3542 SYS$
CLOSE (&fab
, 0, 0);
3543 /* As this is a "replacement" for creat, return a file descriptor
3544 opened for writing. */
3545 return open (new, O_WRONLY
);
3550 #include <varargs.h>
3553 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3557 sys_creat (va_alist
)
3560 va_list list_incrementor
;
3563 int rfd
; /* related file descriptor */
3564 int fd
; /* Our new file descriptor */
3571 extern int vms_stmlf_recfm
;
3574 va_start (list_incrementor
);
3575 name
= va_arg (list_incrementor
, char *);
3576 mode
= va_arg (list_incrementor
, int);
3578 rfd
= va_arg (list_incrementor
, int);
3579 va_end (list_incrementor
);
3582 /* Use information from the related file descriptor to set record
3583 format of the newly created file. */
3584 fstat (rfd
, &st_buf
);
3585 switch (st_buf
.st_fab_rfm
)
3588 strcpy (rfm
, "rfm = fix");
3589 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3590 strcpy (rat
, "rat = ");
3591 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3593 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3594 strcat (rat
, "ftn");
3595 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3596 strcat (rat
, "prn");
3597 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3598 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3599 strcat (rat
, ", blk");
3601 strcat (rat
, "blk");
3602 return creat (name
, 0, rfm
, rat
, mrs
);
3605 strcpy (rfm
, "rfm = vfc");
3606 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3607 strcpy (rat
, "rat = ");
3608 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3610 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3611 strcat (rat
, "ftn");
3612 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3613 strcat (rat
, "prn");
3614 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3615 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3616 strcat (rat
, ", blk");
3618 strcat (rat
, "blk");
3619 return creat (name
, 0, rfm
, rat
, fsz
);
3622 strcpy (rfm
, "rfm = stm");
3626 strcpy (rfm
, "rfm = stmcr");
3630 strcpy (rfm
, "rfm = stmlf");
3634 strcpy (rfm
, "rfm = udf");
3638 strcpy (rfm
, "rfm = var");
3641 strcpy (rat
, "rat = ");
3642 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3644 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3645 strcat (rat
, "ftn");
3646 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3647 strcat (rat
, "prn");
3648 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3649 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3650 strcat (rat
, ", blk");
3652 strcat (rat
, "blk");
3656 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3657 strcpy (rat
, "rat=cr");
3659 /* Until the VAX C RTL fixes the many bugs with modes, always use
3660 mode 0 to get the user's default protection. */
3661 fd
= creat (name
, 0, rfm
, rat
);
3662 if (fd
< 0 && errno
== EEXIST
)
3664 if (unlink (name
) < 0)
3665 report_file_error ("delete", build_string (name
));
3666 fd
= creat (name
, 0, rfm
, rat
);
3672 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3673 sys_fwrite (ptr
, size
, num
, fp
)
3674 register char * ptr
;
3677 register int tot
= num
* size
;
3684 * The VMS C library routine creat actually creates a new version of an
3685 * existing file rather than truncating the old version. There are times
3686 * when this is not the desired behavior, for instance, when writing an
3687 * auto save file (you only want one version), or when you don't have
3688 * write permission in the directory containing the file (but the file
3689 * itself is writable). Hence this routine, which is equivalent to
3690 * "close (creat (fn, 0));" on Unix if fn already exists.
3696 struct FAB xfab
= cc$rms_fab
;
3697 struct RAB xrab
= cc$rms_rab
;
3700 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3701 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3702 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3703 xfab
.fab$l_fna
= fn
;
3704 xfab
.fab$b_fns
= strlen (fn
);
3705 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3707 xrab
.rab$l_fab
= &xfab
;
3709 /* This gibberish opens the file, positions to the first record, and
3710 deletes all records from there until the end of file. */
3711 if ((SYS$
OPEN (&xfab
) & 01) == 01)
3713 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
3714 (SYS$
FIND (&xrab
) & 01) == 01 &&
3715 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
3726 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3727 SYSPRV or a readable SYSUAF.DAT. */
3733 * Routine to read the VMS User Authorization File and return
3734 * a specific user's record.
3737 static struct UAF retuaf
;
3740 get_uaf_name (uname
)
3747 uaf_fab
= cc$rms_fab
;
3748 uaf_rab
= cc$rms_rab
;
3749 /* initialize fab fields */
3750 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3751 uaf_fab
.fab$b_fns
= 21;
3752 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3753 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3754 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3755 /* initialize rab fields */
3756 uaf_rab
.rab$l_fab
= &uaf_fab
;
3757 /* open the User Authorization File */
3758 status
= SYS$
OPEN (&uaf_fab
);
3762 vaxc$errno
= status
;
3765 status
= SYS$
CONNECT (&uaf_rab
);
3769 vaxc$errno
= status
;
3772 /* read the requested record - index is in uname */
3773 uaf_rab
.rab$l_kbf
= uname
;
3774 uaf_rab
.rab$b_ksz
= strlen (uname
);
3775 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3776 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3777 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3778 status
= SYS$
GET (&uaf_rab
);
3782 vaxc$errno
= status
;
3785 /* close the User Authorization File */
3786 status
= SYS$
DISCONNECT (&uaf_rab
);
3790 vaxc$errno
= status
;
3793 status
= SYS$
CLOSE (&uaf_fab
);
3797 vaxc$errno
= status
;
3811 uaf_fab
= cc$rms_fab
;
3812 uaf_rab
= cc$rms_rab
;
3813 /* initialize fab fields */
3814 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3815 uaf_fab
.fab$b_fns
= 21;
3816 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3817 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3818 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3819 /* initialize rab fields */
3820 uaf_rab
.rab$l_fab
= &uaf_fab
;
3821 /* open the User Authorization File */
3822 status
= SYS$
OPEN (&uaf_fab
);
3826 vaxc$errno
= status
;
3829 status
= SYS$
CONNECT (&uaf_rab
);
3833 vaxc$errno
= status
;
3836 /* read the requested record - index is in uic */
3837 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3838 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3839 uaf_rab
.rab$b_ksz
= sizeof uic
;
3840 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3841 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3842 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3843 status
= SYS$
GET (&uaf_rab
);
3847 vaxc$errno
= status
;
3850 /* close the User Authorization File */
3851 status
= SYS$
DISCONNECT (&uaf_rab
);
3855 vaxc$errno
= status
;
3858 status
= SYS$
CLOSE (&uaf_fab
);
3862 vaxc$errno
= status
;
3868 static struct passwd retpw
;
3876 /* copy these out first because if the username is 32 chars, the next
3877 section will overwrite the first byte of the UIC */
3878 retpw
.pw_uid
= up
->uaf$w_mem
;
3879 retpw
.pw_gid
= up
->uaf$w_grp
;
3881 /* I suppose this is not the best sytle, to possibly overwrite one
3882 byte beyond the end of the field, but what the heck... */
3883 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3884 while (ptr
[-1] == ' ')
3887 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3889 /* the rest of these are counted ascii strings */
3890 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3891 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3892 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3893 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3894 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3895 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3896 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3897 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3901 #else /* not READ_SYSUAF */
3902 static struct passwd retpw
;
3903 #endif /* not READ_SYSUAF */
3914 unsigned char * full
;
3915 #endif /* READ_SYSUAF */
3920 if ('a' <= *ptr
&& *ptr
<= 'z')
3925 if (!(up
= get_uaf_name (name
)))
3927 return cnv_uaf_pw (up
);
3929 if (strcmp (name
, getenv ("USER")) == 0)
3931 retpw
.pw_uid
= getuid ();
3932 retpw
.pw_gid
= getgid ();
3933 strcpy (retpw
.pw_name
, name
);
3934 if (full
= egetenv ("FULLNAME"))
3935 strcpy (retpw
.pw_gecos
, full
);
3937 *retpw
.pw_gecos
= '\0';
3938 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
3939 *retpw
.pw_shell
= '\0';
3944 #endif /* not READ_SYSUAF */
3954 if (!(up
= get_uaf_uic (uid
)))
3956 return cnv_uaf_pw (up
);
3958 if (uid
== sys_getuid ())
3959 return getpwnam (egetenv ("USER"));
3962 #endif /* not READ_SYSUAF */
3965 /* return total address space available to the current process. This is
3966 the sum of the current p0 size, p1 size and free page table entries
3971 unsigned long free_pages
;
3972 unsigned long frep0va
;
3973 unsigned long frep1va
;
3976 item_code
= JPI$_FREPTECNT
;
3977 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
3980 vaxc$errno
= status
;
3985 item_code
= JPI$_FREP0VA
;
3986 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
3989 vaxc$errno
= status
;
3992 item_code
= JPI$_FREP1VA
;
3993 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
3996 vaxc$errno
= status
;
4000 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4003 define_logical_name (varname
, string
)
4007 struct dsc$descriptor_s strdsc
=
4008 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4009 struct dsc$descriptor_s envdsc
=
4010 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4011 struct dsc$descriptor_s lnmdsc
=
4012 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4014 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4017 delete_logical_name (varname
)
4020 struct dsc$descriptor_s envdsc
=
4021 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4022 struct dsc$descriptor_s lnmdsc
=
4023 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4025 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4036 error ("execvp system call not implemented");
4044 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4045 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4046 char from_esn
[NAM$C_MAXRSS
];
4047 char to_esn
[NAM$C_MAXRSS
];
4049 from_fab
.fab$l_fna
= from
;
4050 from_fab
.fab$b_fns
= strlen (from
);
4051 from_fab
.fab$l_nam
= &from_nam
;
4052 from_fab
.fab$l_fop
= FAB$M_NAM
;
4054 from_nam
.nam$l_esa
= from_esn
;
4055 from_nam
.nam$b_ess
= sizeof from_esn
;
4057 to_fab
.fab$l_fna
= to
;
4058 to_fab
.fab$b_fns
= strlen (to
);
4059 to_fab
.fab$l_nam
= &to_nam
;
4060 to_fab
.fab$l_fop
= FAB$M_NAM
;
4062 to_nam
.nam$l_esa
= to_esn
;
4063 to_nam
.nam$b_ess
= sizeof to_esn
;
4065 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4071 if (status
== RMS$_DEV
)
4075 vaxc$errno
= status
;
4080 /* This function renames a file like `rename', but it strips
4081 the version number from the "to" filename, such that the "to" file is
4082 will always be a new version. It also sets the file protection once it is
4083 finished. The protection that we will use is stored in fab_final_pro,
4084 and was set when we did a creat_copy_attrs to create the file that we
4087 We could use the chmod function, but Eunichs uses 3 bits per user category
4088 to describe the protection, and VMS uses 4 (write and delete are seperate
4089 bits). To maintain portability, the VMS implementation of `chmod' wires
4090 the W and D bits together. */
4093 static struct fibdef fib
; /* We need this initialized to zero */
4094 char vms_file_written
[NAM$C_MAXRSS
];
4097 rename_sans_version (from
,to
)
4104 struct FAB to_fab
= cc$rms_fab
;
4105 struct NAM to_nam
= cc$rms_nam
;
4106 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4107 struct dsc$descriptor fib_attr
[2]
4108 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4109 char to_esn
[NAM$C_MAXRSS
];
4111 $
DESCRIPTOR (disk
,to_esn
);
4113 to_fab
.fab$l_fna
= to
;
4114 to_fab
.fab$b_fns
= strlen (to
);
4115 to_fab
.fab$l_nam
= &to_nam
;
4116 to_fab
.fab$l_fop
= FAB$M_NAM
;
4118 to_nam
.nam$l_esa
= to_esn
;
4119 to_nam
.nam$b_ess
= sizeof to_esn
;
4121 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4123 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4124 *(to_nam
.nam$l_ver
) = '\0';
4126 stat
= rename (from
, to_esn
);
4130 strcpy (vms_file_written
, to_esn
);
4132 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4133 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4135 /* Now set the file protection to the correct value */
4136 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4138 /* Copy these fields into the fib */
4139 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4140 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4141 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4143 SYS$
CLOSE (&to_fab
, 0, 0);
4145 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4148 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4149 0, 0, 0, &fib_attr
, 0);
4152 stat
= SYS$
DASSGN (chan
);
4155 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4165 unsigned short fid
[3];
4166 char esa
[NAM$C_MAXRSS
];
4169 fab
.fab$l_fop
= FAB$M_OFP
;
4170 fab
.fab$l_fna
= file
;
4171 fab
.fab$b_fns
= strlen (file
);
4172 fab
.fab$l_nam
= &nam
;
4175 nam
.nam$l_esa
= esa
;
4176 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4178 status
= SYS$
PARSE (&fab
);
4179 if ((status
& 1) == 0)
4182 vaxc$errno
= status
;
4185 status
= SYS$
SEARCH (&fab
);
4186 if ((status
& 1) == 0)
4189 vaxc$errno
= status
;
4193 fid
[0] = nam
.nam$w_fid
[0];
4194 fid
[1] = nam
.nam$w_fid
[1];
4195 fid
[2] = nam
.nam$w_fid
[2];
4197 fab
.fab$l_fna
= new;
4198 fab
.fab$b_fns
= strlen (new);
4200 status
= SYS$
PARSE (&fab
);
4201 if ((status
& 1) == 0)
4204 vaxc$errno
= status
;
4208 nam
.nam$w_fid
[0] = fid
[0];
4209 nam
.nam$w_fid
[1] = fid
[1];
4210 nam
.nam$w_fid
[2] = fid
[2];
4212 nam
.nam$l_esa
= nam
.nam$l_name
;
4213 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4215 status
= SYS$
ENTER (&fab
);
4216 if ((status
& 1) == 0)
4219 vaxc$errno
= status
;
4229 printf ("%s not yet implemented\r\n", badfunc
);
4237 /* Arrange to return a range centered on zero. */
4238 return rand () - (1 << 30);
4249 /* Called from init_sys_modes. */
4254 /* If we're not on an HFT we shouldn't do any of this. We determine
4255 if we are on an HFT by trying to get an HFT error code. If this
4256 call fails, we're not on an HFT. */
4258 if (ioctl (0, HFQERROR
, &junk
) < 0)
4260 #else /* not IBMR2AIX */
4261 if (ioctl (0, HFQEIO
, 0) < 0)
4263 #endif /* not IBMR2AIX */
4265 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4266 as the rubout key's ASCII code. Here this is changed. The bug is that
4267 there's no way to determine the old mapping, so in reset_sys_modes
4268 we need to assume that the normal map had been present. Of course, this
4269 code also doesn't help if on a terminal emulator which doesn't understand
4273 struct hfkeymap keymap
;
4275 buf
.hf_bufp
= (char *)&keymap
;
4276 buf
.hf_buflen
= sizeof (keymap
);
4277 keymap
.hf_nkeys
= 2;
4278 keymap
.hfkey
[0].hf_kpos
= 15;
4279 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4281 keymap
.hfkey
[0].hf_keyidh
= '<';
4282 #else /* not IBMR2AIX */
4283 keymap
.hfkey
[0].hf_page
= '<';
4284 #endif /* not IBMR2AIX */
4285 keymap
.hfkey
[0].hf_char
= 127;
4286 keymap
.hfkey
[1].hf_kpos
= 15;
4287 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4289 keymap
.hfkey
[1].hf_keyidh
= '<';
4290 #else /* not IBMR2AIX */
4291 keymap
.hfkey
[1].hf_page
= '<';
4292 #endif /* not IBMR2AIX */
4293 keymap
.hfkey
[1].hf_char
= 127;
4294 hftctl (0, HFSKBD
, &buf
);
4296 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4298 line_ins_del_ok
= char_ins_del_ok
= 0;
4301 /* Reset the rubout key to backspace. */
4306 struct hfkeymap keymap
;
4310 if (ioctl (0, HFQERROR
, &junk
) < 0)
4312 #else /* not IBMR2AIX */
4313 if (ioctl (0, HFQEIO
, 0) < 0)
4315 #endif /* not IBMR2AIX */
4317 buf
.hf_bufp
= (char *)&keymap
;
4318 buf
.hf_buflen
= sizeof (keymap
);
4319 keymap
.hf_nkeys
= 2;
4320 keymap
.hfkey
[0].hf_kpos
= 15;
4321 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4323 keymap
.hfkey
[0].hf_keyidh
= '<';
4324 #else /* not IBMR2AIX */
4325 keymap
.hfkey
[0].hf_page
= '<';
4326 #endif /* not IBMR2AIX */
4327 keymap
.hfkey
[0].hf_char
= 8;
4328 keymap
.hfkey
[1].hf_kpos
= 15;
4329 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4331 keymap
.hfkey
[1].hf_keyidh
= '<';
4332 #else /* not IBMR2AIX */
4333 keymap
.hfkey
[1].hf_page
= '<';
4334 #endif /* not IBMR2AIX */
4335 keymap
.hfkey
[1].hf_char
= 8;
4336 hftctl (0, HFSKBD
, &buf
);