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 */
108 /* On some systems (DGUX comes to mind real fast) FASYNC causes
109 background writes to the terminal to stop all processes in the
110 process group when invoked under the csh (and probably any shell
111 with job control). This stops Emacs dead in its tracks when coming
116 #include <sys/ioctl.h>
123 #include <sys/wait.h>
127 #ifdef BROKEN_TIOCGWINSZ
132 #include <sys/utsname.h>
134 #ifndef MEMORY_IN_STRING_H
139 #include <sys/sioctl.h>
142 #include <sys/stream.h>
143 #include <sys/ptem.h>
145 #endif /* TIOCGWINSZ */
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 static int baud_convert
[] =
170 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
171 1800, 2400, 4800, 9600, 19200, 38400
177 /* The file descriptor for Emacs's input terminal.
178 Under Unix, this is always left zero;
179 under VMS, we place the input channel number here.
180 This allows us to write more code that works for both VMS and Unix. */
185 struct emacs_tty buf
;
190 /* Discarding input is not safe when the input could contain
191 replies from the X server. So don't do it. */
192 if (read_socket_hook
)
197 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
198 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
204 ioctl (0, TIOCFLUSH
, &zero
);
206 #else /* not Apollo */
207 EMACS_GET_TTY (input_fd
, &buf
);
208 EMACS_SET_TTY (input_fd
, &buf
, 0);
209 #endif /* not Apollo */
218 /* Should perhaps error if in batch mode */
220 ioctl (0, TIOCSTI
, &c
);
221 #else /* no TIOCSTI */
222 error ("Cannot stuff terminal input characters in this version of Unix.");
223 #endif /* no TIOCSTI */
237 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
238 &sg
.class, 12, 0, 0, 0, 0 );
239 ospeed
= sg
.xmit_baud
;
244 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
246 ospeed
= cfgetospeed (&sg
);
247 #else /* neither VMS nor TERMIOS */
251 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
255 ioctl (input_fd
, TCGETA
, &sg
);
257 ospeed
= sg
.c_cflag
& CBAUD
;
258 #else /* neither VMS nor TERMIOS nor TERMIO */
261 sg
.sg_ospeed
= B9600
;
262 if (ioctl (0, TIOCGETP
, &sg
) < 0)
264 ospeed
= sg
.sg_ospeed
;
265 #endif /* not HAVE_TERMIO */
266 #endif /* not HAVE_TERMIOS */
270 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
271 ? baud_convert
[ospeed
] : 9600);
277 set_exclusive_use (fd
)
281 ioctl (fd
, FIOCLEX
, 0);
283 /* Ok to do nothing if this feature does not exist */
288 wait_without_blocking ()
291 wait3 (0, WNOHANG
| WUNTRACED
, 0);
293 croak ("wait_without_blocking");
295 synch_process_alive
= 0;
298 #endif /* not subprocesses */
300 int wait_debugging
; /* Set nonzero to make following function work under dbx
301 (at least for bsd). */
304 wait_for_termination_signal ()
307 /* Wait for subprocess with process id `pid' to terminate and
308 make sure it will get eliminated (not remain forever as a zombie) */
310 wait_for_termination (pid
)
319 status
= SYS$
FORCEX (&pid
, 0, 0);
322 #if defined (BSD) || (defined (HPUX) && !defined (HPUX_5))
323 /* Note that kill returns -1 even if the process is just a zombie now.
324 But inevitably a SIGCHLD interrupt should be generated
325 and child_sig will do wait3 and make the process go away. */
326 /* There is some indication that there is a bug involved with
327 termination of subprocesses, perhaps involving a kernel bug too,
328 but no idea what it is. Just as a hunch we signal SIGCHLD to see
329 if that causes the problem to go away or get worse. */
330 sigsetmask (sigmask (SIGCHLD
));
331 if (0 > kill (pid
, 0))
333 sigsetmask (SIGEMPTYMASK
);
334 kill (getpid (), SIGCHLD
);
340 sigpause (SIGEMPTYMASK
);
341 #else /* not BSD, and not HPUX version >= 6 */
342 #if defined (UNIPLUS)
343 if (0 > kill (pid
, 0))
346 #else /* neither BSD nor UNIPLUS: random sysV */
347 #ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
348 sigblock (sigmask (SIGCHLD
));
349 if (0 > kill (pid
, 0))
351 sigunblock (sigmask (SIGCHLD
));
354 sigpause (SIGEMPTYMASK
);
355 #else /* not POSIX_SIGNALS */
356 #ifdef HAVE_SYSV_SIGPAUSE
358 if (0 > kill (pid
, 0))
364 #else /* not HAVE_SYSV_SIGPAUSE */
365 if (0 > kill (pid
, 0))
367 /* Using sleep instead of pause avoids timing error.
368 If the inferior dies just before the sleep,
369 we lose just one second. */
371 #endif /* not HAVE_SYSV_SIGPAUSE */
372 #endif /* not POSIX_SIGNALS */
373 #endif /* not UNIPLUS */
374 #endif /* not BSD, and not HPUX version >= 6 */
376 #else /* not subprocesses */
378 if (kill (pid
, 0) < 0)
384 if (status
== pid
|| status
== -1)
387 #endif /* not subprocesses */
394 * flush any pending output
395 * (may flush input as well; it does not matter the way we use it)
398 flush_pending_output (channel
)
402 /* If we try this, we get hit with SIGTTIN, because
403 the child's tty belongs to the child's pgrp. */
406 ioctl (channel
, TCFLSH
, 1);
410 /* 3rd arg should be ignored
411 but some 4.2 kernels actually want the address of an int
412 and nonzero means something different. */
413 ioctl (channel
, TIOCFLUSH
, &zero
);
420 /* Set up the terminal at the other end of a pseudo-terminal that
421 we will be controlling an inferior through.
422 It should not echo or do line-editing, since that is done
423 in Emacs. No padding needed for insertion into an Emacs buffer. */
425 child_setup_tty (out
)
430 EMACS_GET_TTY (out
, &s
);
432 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
433 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
434 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
435 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
436 /* No output delays */
437 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
438 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
439 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
441 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
444 /* Said to be unnecessary: */
445 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
446 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
449 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
450 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
451 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
452 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
455 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
459 /* AIX enhanced edit loses NULs, so disable it */
462 s
.main
.c_iflag
&= ~ASCEDIT
;
464 /* Also, PTY overloads NUL and BREAK.
465 don't ignore break, but don't signal either, so it looks like NUL. */
466 s
.main
.c_iflag
&= ~IGNBRK
;
467 s
.main
.c_iflag
&= ~BRKINT
;
468 /* QUIT and INTR work better as signals, so disable character forms */
469 s
.main
.c_cc
[VINTR
] = 0377;
470 #ifdef SIGNALS_VIA_CHARACTERS
471 /* the QUIT and INTR character are used in process_send_signal
472 so set them here to something useful. */
473 if (s
.main
.c_cc
[VQUIT
] == 0377)
474 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
475 if (s
.main
.c_cc
[VINTR
] == 0377)
476 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
477 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
478 /* QUIT and INTR work better as signals, so disable character forms */
479 s
.main
.c_cc
[VQUIT
] = 0377;
480 s
.main
.c_cc
[VINTR
] = 0377;
481 s
.main
.c_lflag
&= ~ISIG
;
482 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
483 s
.main
.c_cc
[VEOL
] = 0377;
484 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
487 #else /* not HAVE_TERMIO */
489 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
491 s
.main
.sg_erase
= 0377;
492 s
.main
.sg_kill
= 0377;
494 #endif /* not HAVE_TERMIO */
496 EMACS_SET_TTY (out
, &s
, 0);
505 ioctl (out
, FIOASYNC
, &zero
);
511 #endif /* subprocesses */
517 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
520 /* Record a signal code and the handler for it. */
524 SIGTYPE (*handler
) ();
527 /* Suspend the Emacs process; give terminal to its superior. */
532 /* "Foster" parentage allows emacs to return to a subprocess that attached
533 to the current emacs as a cheaper than starting a whole new process. This
534 is set up by KEPTEDITOR.COM. */
535 unsigned long parent_id
, foster_parent_id
;
538 fpid_string
= getenv ("EMACS_PARENT_PID");
539 if (fpid_string
!= NULL
)
541 sscanf (fpid_string
, "%x", &foster_parent_id
);
542 if (foster_parent_id
!= 0)
543 parent_id
= foster_parent_id
;
545 parent_id
= getppid ();
548 parent_id
= getppid ();
550 xfree (fpid_string
); /* On VMS, this was malloc'd */
552 if (parent_id
&& parent_id
!= 0xffffffff)
554 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
555 int status
= LIB$
ATTACH (&parent_id
) & 1;
556 signal (SIGINT
, oldsig
);
565 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
566 d_prompt
.a
= "Emacs: "; /* Just a reminder */
567 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
576 int pgrp
= getpgrp ();
578 int pgrp
= getpgrp (0);
580 EMACS_KILLPG (pgrp
, SIGTSTP
);
583 #else /* No SIGTSTP */
584 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
585 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
586 kill (getpid (), SIGQUIT
);
588 #else /* No SIGTSTP or USG_JOBCTRL */
590 /* On a system where suspending is not implemented,
591 instead fork a subshell and let it talk directly to the terminal
594 struct save_signal saved_handlers
[5];
596 saved_handlers
[0].code
= SIGINT
;
597 saved_handlers
[1].code
= SIGQUIT
;
598 saved_handlers
[2].code
= SIGTERM
;
600 saved_handlers
[3].code
= SIGIO
;
601 saved_handlers
[4].code
= 0;
603 saved_handlers
[3].code
= 0;
607 error ("Can't spawn subshell");
612 sh
= (char *) egetenv ("SHELL");
615 /* Use our buffer's default directory for the subshell. */
621 /* mentioning current_buffer->buffer would mean including buffer.h,
622 which somehow wedges the hp compiler. So instead... */
624 dir
= intern ("default-directory");
626 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
628 dir
= Fsymbol_value (dir
);
629 if (XTYPE (dir
) != Lisp_String
)
632 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
633 len
= XSTRING (dir
)->size
;
634 bcopy (XSTRING (dir
)->data
, str
, len
);
635 if (str
[len
- 1] != '/') str
[len
++] = '/';
641 close_process_descs (); /* Close Emacs's pipes/ptys */
646 extern int emacs_priority
;
649 nice (-emacs_priority
);
654 write (1, "Can't execute subshell", 22);
658 save_signal_handlers (saved_handlers
);
659 synch_process_alive
= 1;
660 wait_for_termination (pid
);
661 restore_signal_handlers (saved_handlers
);
663 #endif /* no USG_JOBCTRL */
664 #endif /* no SIGTSTP */
668 save_signal_handlers (saved_handlers
)
669 struct save_signal
*saved_handlers
;
671 while (saved_handlers
->code
)
673 saved_handlers
->handler
674 = (SIGTYPE (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
679 restore_signal_handlers (saved_handlers
)
680 struct save_signal
*saved_handlers
;
682 while (saved_handlers
->code
)
684 signal (saved_handlers
->code
, saved_handlers
->handler
);
696 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
706 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
711 sigunblock (sigmask (SIGWINCH
));
713 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
715 interrupts_deferred
= 0;
721 sigblock (sigmask (SIGWINCH
));
723 fcntl (0, F_SETFL
, old_fcntl_flags
);
724 interrupts_deferred
= 1;
727 #else /* no FASYNC */
728 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
733 ioctl (0, FIOASYNC
, &on
);
734 interrupts_deferred
= 0;
741 ioctl (0, FIOASYNC
, &off
);
742 interrupts_deferred
= 1;
745 #else /* not FASYNC, not STRIDE */
749 croak ("request_sigio");
754 croak ("unrequest_sigio");
761 /* Saving and restoring the process group of Emacs's terminal. */
765 /* The process group of which Emacs was a member when it initially
768 If Emacs was in its own process group (i.e. inherited_pgroup ==
769 getpid ()), then we know we're running under a shell with job
770 control (Emacs would never be run as part of a pipeline).
773 If Emacs was not in its own process group, then we know we're
774 running under a shell (or a caller) that doesn't know how to
775 separate itself from Emacs (like sh). Emacs must be in its own
776 process group in order to receive SIGIO correctly. In this
777 situation, we put ourselves in our own pgroup, forcibly set the
778 tty's pgroup to our pgroup, and make sure to restore and reinstate
779 the tty's pgroup just like any other terminal setting. If
780 inherited_group was not the tty's pgroup, then we'll get a
781 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
782 it goes foreground in the future, which is what should happen. */
783 int inherited_pgroup
;
785 /* Split off the foreground process group to Emacs alone.
786 When we are in the foreground, but not started in our own process
787 group, redirect the TTY to point to our own process group. We need
788 to be in our own process group to receive SIGIO properly. */
789 narrow_foreground_group ()
793 setpgrp (0, inherited_pgroup
);
794 if (inherited_pgroup
!= me
)
795 EMACS_SET_TTY_PGRP (0, &me
);
799 /* Set the tty to our original foreground group. */
800 widen_foreground_group ()
802 if (inherited_pgroup
!= getpid ())
803 EMACS_SET_TTY_PGRP (0, &inherited_pgroup
);
804 setpgrp (0, inherited_pgroup
);
809 /* Getting and setting emacs_tty structures. */
811 /* Set *TC to the parameters associated with the terminal FD.
812 Return zero if all's well, or -1 if we ran into an error we
813 couldn't deal with. */
815 emacs_get_tty (fd
, settings
)
817 struct emacs_tty
*settings
;
819 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
821 /* We have those nifty POSIX tcmumbleattr functions. */
822 if (tcgetattr (fd
, &settings
->main
) < 0)
827 /* The SYSV-style interface? */
828 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
833 /* Vehemently Monstrous System? :-) */
834 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
835 &settings
->main
.class, 12, 0, 0, 0, 0)
840 /* I give up - I hope you have the BSD ioctls. */
841 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
848 /* Suivant - Do we have to get struct ltchars data? */
850 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
854 /* How about a struct tchars and a wordful of lmode bits? */
856 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
857 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
861 /* We have survived the tempest. */
866 /* Set the parameters of the tty on FD according to the contents of
867 *SETTINGS. If WAITP is non-zero, we wait for all queued output to
868 be written before making the change; otherwise, we forget any
869 queued input and make the change immediately.
870 Return 0 if all went well, and -1 if anything failed. */
872 emacs_set_tty (fd
, settings
, waitp
)
874 struct emacs_tty
*settings
;
877 /* Set the primary parameters - baud rate, character size, etcetera. */
880 /* We have those nifty POSIX tcmumbleattr functions.
881 William J. Smith <wjs@wiis.wang.com> writes:
882 "POSIX 1003.1 defines tcsetattr() to return success if it was
883 able to perform any of the requested actions, even if some
884 of the requested actions could not be performed.
885 We must read settings back to ensure tty setup properly.
886 AIX requires this to keep tty from hanging occasionally." */
887 /* This make sure that we don't loop indefinitely in here. */
888 for (i
= 0 ; i
< 10 ; i
++)
889 if (tcsetattr (fd
, waitp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
900 /* Get the current settings, and see if they're what we asked for. */
901 tcgetattr (fd
, &new);
902 /* We cannot use memcmp on the whole structure here because under
903 * aix386 the termios structure has some reserved field that may
906 if ( new.c_iflag
== settings
->main
.c_iflag
907 && new.c_oflag
== settings
->main
.c_oflag
908 && new.c_cflag
== settings
->main
.c_cflag
909 && new.c_lflag
== settings
->main
.c_lflag
910 && memcmp(new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
918 /* The SYSV-style interface? */
919 if (ioctl (fd
, waitp
? TCSETAW
: TCSETAF
, &settings
->main
) < 0)
924 /* Vehemently Monstrous System? :-) */
925 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
926 &settings
->main
.class, 12, 0, 0, 0, 0)
931 /* I give up - I hope you have the BSD ioctls. */
932 if (ioctl (fd
, (waitp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
939 /* Suivant - Do we have to get struct ltchars data? */
941 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
945 /* How about a struct tchars and a wordful of lmode bits? */
947 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
948 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
952 /* We have survived the tempest. */
957 /* The initial tty mode bits */
958 struct emacs_tty old_tty
;
960 int term_initted
; /* 1 if outer tty status has been recorded */
963 /* BSD 4.1 needs to keep track of the lmode bits in order to start
970 #endif /* F_SETOWN */
972 /* This may also be defined in stdio,
973 but if so, this does no harm,
974 and using the same name avoids wasting the other one's space. */
976 #if defined (USG) || defined (DGUX)
977 unsigned char _sobuf
[BUFSIZ
+8];
983 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
986 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
991 struct emacs_tty tty
;
995 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
996 extern int (*interrupt_signal
) ();
1005 input_ef
= get_kbd_event_flag ();
1006 /* LIB$GET_EF (&input_ef); */
1007 SYS$
CLREF (input_ef
);
1008 waiting_for_ast
= 0;
1010 timer_ef
= get_timer_event_flag ();
1011 /* LIB$GET_EF (&timer_ef); */
1012 SYS$
CLREF (timer_ef
);
1016 LIB$
GET_EF (&process_ef
);
1017 SYS$
CLREF (process_ef
);
1019 if (input_ef
/ 32 != process_ef
/ 32)
1020 croak ("Input and process event flags in different clusters.");
1022 if (input_ef
/ 32 != timer_ef
/ 32)
1023 croak ("Input and timer event flags in different clusters.");
1025 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1026 ((unsigned) 1 << (process_ef
% 32));
1028 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1029 ((unsigned) 1 << (timer_ef
% 32));
1031 sys_access_reinit ();
1033 #endif /* not VMS */
1036 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1037 narrow_foreground_group ();
1040 EMACS_GET_TTY (input_fd
, &old_tty
);
1042 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1046 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1047 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1048 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1050 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1052 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1053 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1055 tty
.main
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
1057 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1060 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1062 tty
.main
.c_iflag
&= ~IXANY
;
1066 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1067 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1069 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1073 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1074 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1077 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1078 /* Set up C-g for both SIGQUIT and SIGINT.
1079 We don't know which we will get, but we handle both alike
1080 so which one it really gives us does not matter. */
1081 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1082 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1083 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1085 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1088 #if defined (mips) || defined (HAVE_TCATTR)
1090 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1093 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1094 #endif /* V_DSUSP */
1095 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1096 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1099 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1102 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1103 #endif /* VREPRINT */
1105 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1106 #endif /* VWERASE */
1108 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1109 #endif /* VDISCARD */
1110 #endif /* mips or HAVE_TCATTR */
1113 /* AIX enhanced edit loses NULs, so disable it */
1114 tty
.main
.c_line
= 0;
1115 tty
.main
.c_iflag
&= ~ASCEDIT
;
1117 tty
.main
.c_cc
[VSTRT
] = 255;
1118 tty
.main
.c_cc
[VSTOP
] = 255;
1119 tty
.main
.c_cc
[VSUSP
] = 255;
1120 tty
.main
.c_cc
[VDSUSP
] = 255;
1121 #endif /* IBMR2AIX */
1122 /* Also, PTY overloads NUL and BREAK.
1123 don't ignore break, but don't signal either, so it looks like NUL.
1124 This really serves a purpose only if running in an XTERM window
1125 or via TELNET or the like, but does no harm elsewhere. */
1126 tty
.main
.c_iflag
&= ~IGNBRK
;
1127 tty
.main
.c_iflag
&= ~BRKINT
;
1129 #else /* if not HAVE_TERMIO */
1131 tty
.main
.tt_char
|= TT$M_NOECHO
;
1133 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1135 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1137 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1138 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1139 #else /* not VMS (BSD, that is) */
1140 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1142 tty
.main
.sg_flags
|= ANYP
;
1143 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1144 #endif /* not VMS (BSD, that is) */
1145 #endif /* not HAVE_TERMIO */
1147 /* If going to use CBREAK mode, we must request C-g to interrupt
1148 and turn off start and stop chars, etc. If not going to use
1149 CBREAK mode, do this anyway so as to turn off local flow
1150 control for user coming over network on 4.2; in this case,
1151 only t_stopc and t_startc really matter. */
1154 /* Note: if not using CBREAK mode, it makes no difference how we
1156 tty
.tchars
= new_tchars
;
1157 tty
.tchars
.t_intrc
= quit_char
;
1160 tty
.tchars
.t_startc
= '\021';
1161 tty
.tchars
.t_stopc
= '\023';
1164 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
1170 #define LNOFLSH 0100000
1173 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1175 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1176 anything, and leaving it in breaks the meta key. Go figure. */
1177 tty
.lmode
&= ~LLITOUT
;
1184 #endif /* HAVE_TCHARS */
1185 #endif /* not HAVE_TERMIO */
1188 tty
.ltchars
= new_ltchars
;
1189 #endif /* HAVE_LTCHARS */
1191 EMACS_SET_TTY (input_fd
, &tty
, 0);
1193 /* This code added to insure that, if flow-control is not to be used,
1194 we have an unlocked terminal at the start. */
1197 if (!flow_control
) ioctl (0, TCXONC
, 1);
1201 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
1209 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1210 to be only LF. This is the way that is done. */
1213 if (ioctl (1, HFTGETID
, &tty
) != -1)
1214 write (1, "\033[20l", 5);
1220 /* Appears to do nothing when in PASTHRU mode.
1221 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1222 interrupt_signal, oob_chars, 0, 0, 0, 0);
1224 queue_kbd_input (0);
1229 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1230 if (interrupt_input
)
1232 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
1233 fcntl (0, F_SETOWN
, getpid ());
1236 #endif /* F_GETOWN */
1237 #endif /* F_SETFL */
1240 if (interrupt_input
)
1244 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1248 /* This symbol is defined on recent USG systems.
1249 Someone says without this call USG won't really buffer the file
1250 even with a call to setbuf. */
1251 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1253 setbuf (stdout
, _sobuf
);
1255 set_terminal_modes ();
1256 if (term_initted
&& no_redraw_on_reenter
)
1258 if (display_completed
)
1259 direct_output_forward_char (0);
1265 if (FRAMEP (Vterminal_frame
))
1266 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1273 /* Return nonzero if safe to use tabs in output.
1274 At the time this is called, init_sys_modes has not been done yet. */
1278 struct emacs_tty tty
;
1280 EMACS_GET_TTY (input_fd
, &tty
);
1281 return EMACS_TTY_TABS_OK (&tty
);
1284 /* Get terminal size from system.
1285 Store number of lines into *heightp and width into *widthp.
1286 If zero or a negative number is stored, the value is not valid. */
1288 get_frame_size (widthp
, heightp
)
1289 int *widthp
, *heightp
;
1295 struct winsize size
;
1297 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1298 *widthp
= *heightp
= 0;
1301 *widthp
= size
.ws_col
;
1302 *heightp
= size
.ws_row
;
1308 /* SunOS - style. */
1309 struct ttysize size
;
1311 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1312 *widthp
= *heightp
= 0;
1315 *widthp
= size
.ts_cols
;
1316 *heightp
= size
.ts_lines
;
1322 struct sensemode tty
;
1324 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1325 &tty
.class, 12, 0, 0, 0, 0);
1326 *widthp
= tty
.scr_wid
;
1327 *heightp
= tty
.scr_len
;
1329 #else /* system doesn't know size */
1334 #endif /* not VMS */
1335 #endif /* not SunOS-style */
1336 #endif /* not BSD-style */
1340 /* Prepare the terminal for exiting Emacs; move the cursor to the
1341 bottom of the frame, turn off interrupt-driven I/O, etc. */
1351 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1353 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1354 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1355 /* clear_end_of_line may move the cursor */
1356 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1359 /* HFT devices normally use ^J as a LF/CR. We forced it to
1360 do the LF only. Now, we need to reset it. */
1363 if (ioctl (1, HFTGETID
, &tty
) != -1)
1364 write (1, "\033[20h", 5);
1368 reset_terminal_modes ();
1372 /* Avoid possible loss of output when changing terminal modes. */
1373 fsync (fileno (stdout
));
1378 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1379 if (interrupt_input
)
1382 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1384 #endif /* F_SETOWN */
1385 #endif /* F_SETFL */
1387 if (interrupt_input
)
1391 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1399 widen_foreground_group ();
1405 /* Set up the proper status flags for use of a pty. */
1410 /* I'm told that TOICREMOTE does not mean control chars
1411 "can't be sent" but rather that they don't have
1412 input-editing or signaling effects.
1413 That should be good, because we have other ways
1414 to do those things in Emacs.
1415 However, telnet mode seems not to work on 4.2.
1416 So TIOCREMOTE is turned off now. */
1418 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1419 will hang. In particular, the "timeout" feature (which
1420 causes a read to return if there is no data available)
1421 does this. Also it is known that telnet mode will hang
1422 in such a way that Emacs must be stopped (perhaps this
1423 is the same problem).
1425 If TIOCREMOTE is turned off, then there is a bug in
1426 hp-ux which sometimes loses data. Apparently the
1427 code which blocks the master process when the internal
1428 buffer fills up does not work. Other than this,
1429 though, everything else seems to work fine.
1431 Since the latter lossage is more benign, we may as well
1432 lose that way. -- cph */
1437 ioctl (fd
, FIONBIO
, &on
);
1442 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1443 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1444 /* cause EMACS not to die when it should, i.e., when its own controlling */
1445 /* tty goes away. I've complained to the AIX developers, and they may */
1446 /* change this behavior, but I'm not going to hold my breath. */
1447 signal (SIGHUP
, SIG_IGN
);
1450 #endif /* HAVE_PTYS */
1454 /* Assigning an input channel is done at the start of Emacs execution.
1455 This is called each time Emacs is resumed, also, but does nothing
1456 because input_chain is no longer zero. */
1464 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1470 /* Deassigning the input channel is done before exiting. */
1474 return SYS$
DASSGN (input_fd
);
1479 /* Request reading one character into the keyboard buffer.
1480 This is done as soon as the buffer becomes empty. */
1485 extern kbd_input_ast ();
1487 waiting_for_ast
= 0;
1489 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1490 &input_iosb
, kbd_input_ast
, 1,
1491 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1496 /* Ast routine that is called when keyboard input comes in
1497 in accord with the SYS$QIO above. */
1501 register int c
= -1;
1502 int old_errno
= errno
;
1503 extern EMACS_TIME
*input_available_clear_time
;
1505 if (waiting_for_ast
)
1506 SYS$
SETEF (input_ef
);
1507 waiting_for_ast
= 0;
1510 if (input_count
== 25)
1512 printf ("Ast # %d,", input_count
);
1513 printf (" iosb = %x, %x, %x, %x",
1514 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1517 if (input_iosb
.offset
)
1521 printf (", char = 0%o", c
);
1533 struct input_event e
;
1534 e
.kind
= ascii_keystroke
;
1535 XSET (e
.code
, Lisp_Int
, c
);
1537 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1539 e
.frame_or_window
= Qnil
;
1541 kbd_buffer_store_event (&e
);
1543 if (input_available_clear_time
)
1544 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1548 /* Wait until there is something in kbd_buffer. */
1550 wait_for_kbd_input ()
1552 extern int have_process_input
, process_exited
;
1554 /* If already something, avoid doing system calls. */
1555 if (detect_input_pending ())
1559 /* Clear a flag, and tell ast routine above to set it. */
1560 SYS$
CLREF (input_ef
);
1561 waiting_for_ast
= 1;
1562 /* Check for timing error: ast happened while we were doing that. */
1563 if (!detect_input_pending ())
1565 /* No timing error: wait for flag to be set. */
1566 set_waiting_for_input (0);
1567 SYS$
WFLOR (input_ef
, input_eflist
);
1568 clear_waiting_for_input (0);
1569 if (!detect_input_pending ())
1570 /* Check for subprocess input availability */
1572 int dsp
= have_process_input
|| process_exited
;
1574 SYS$
CLREF (process_ef
);
1575 if (have_process_input
)
1576 process_command_input ();
1581 update_mode_lines
++;
1582 redisplay_preserve_echo_area ();
1586 waiting_for_ast
= 0;
1589 /* Get rid of any pending QIO, when we are about to suspend
1590 or when we want to throw away pending input.
1591 We wait for a positive sign that the AST routine has run
1592 and therefore there is no I/O request queued when we return.
1593 SYS$SETAST is used to avoid a timing error. */
1598 printf ("At end_kbd_input.\n");
1602 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1604 SYS$
CANCEL (input_fd
);
1609 /* Clear a flag, and tell ast routine above to set it. */
1610 SYS$
CLREF (input_ef
);
1611 waiting_for_ast
= 1;
1613 SYS$
CANCEL (input_fd
);
1615 SYS$
WAITFR (input_ef
);
1616 waiting_for_ast
= 0;
1619 /* Wait for either input available or time interval expiry. */
1621 input_wait_timeout (timeval
)
1622 int timeval
; /* Time to wait, in seconds */
1625 static int zero
= 0;
1626 static int large
= -10000000;
1628 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1630 /* If already something, avoid doing system calls. */
1631 if (detect_input_pending ())
1635 /* Clear a flag, and tell ast routine above to set it. */
1636 SYS$
CLREF (input_ef
);
1637 waiting_for_ast
= 1;
1638 /* Check for timing error: ast happened while we were doing that. */
1639 if (!detect_input_pending ())
1641 /* No timing error: wait for flag to be set. */
1643 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1644 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1646 waiting_for_ast
= 0;
1649 /* The standard `sleep' routine works some other way
1650 and it stops working if you have ever quit out of it.
1651 This one continues to work. */
1657 static int zero
= 0;
1658 static int large
= -10000000;
1660 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1663 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1664 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1679 croak ("request sigio");
1684 croak ("unrequest sigio");
1689 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1694 #ifndef SYSTEM_MALLOC
1701 /* Some systems that cannot dump also cannot implement these. */
1704 * Return the address of the start of the text segment prior to
1705 * doing an unexec. After unexec the return value is undefined.
1706 * See crt0.c for further explanation and _start.
1710 #ifndef CANNOT_UNEXEC
1715 return ((char *) TEXT_START
);
1719 return ((char *) csrt
);
1720 #else /* not GOULD */
1721 extern int _start ();
1722 return ((char *) _start
);
1724 #endif /* TEXT_START */
1726 #endif /* not CANNOT_UNEXEC */
1729 * Return the address of the start of the data segment prior to
1730 * doing an unexec. After unexec the return value is undefined.
1731 * See crt0.c for further information and definition of data_start.
1733 * Apparently, on BSD systems this is etext at startup. On
1734 * USG systems (swapping) this is highly mmu dependent and
1735 * is also dependent on whether or not the program is running
1736 * with shared text. Generally there is a (possibly large)
1737 * gap between end of text and start of data with shared text.
1739 * On Uniplus+ systems with shared text, data starts at a
1740 * fixed address. Each port (from a given oem) is generally
1741 * different, and the specific value of the start of data can
1742 * be obtained via the UniPlus+ specific "uvar" system call,
1743 * however the method outlined in crt0.c seems to be more portable.
1745 * Probably what will have to happen when a USG unexec is available,
1746 * at least on UniPlus, is temacs will have to be made unshared so
1747 * that text and data are contiguous. Then once loadup is complete,
1748 * unexec will produce a shared executable where the data can be
1749 * at the normal shared text boundry and the startofdata variable
1750 * will be patched by unexec to the correct value.
1758 return ((char *) DATA_START
);
1760 #ifdef ORDINARY_LINK
1762 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1763 * data_start isn't defined. We take the address of environ, which
1764 * is known to live at or near the start of the system crt0.c, and
1765 * we don't sweat the handful of bytes that might lose.
1767 extern char **environ
;
1769 return((char *) &environ
);
1771 extern int data_start
;
1772 return ((char *) &data_start
);
1773 #endif /* ORDINARY_LINK */
1774 #endif /* DATA_START */
1776 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1779 /* Some systems that cannot dump also cannot implement these. */
1782 * Return the address of the end of the text segment prior to
1783 * doing an unexec. After unexec the return value is undefined.
1790 return ((char *) TEXT_END
);
1793 return ((char *) &etext
);
1798 * Return the address of the end of the data segment prior to
1799 * doing an unexec. After unexec the return value is undefined.
1806 return ((char *) DATA_END
);
1809 return ((char *) &edata
);
1813 #endif /* not CANNOT_DUMP */
1815 /* Get_system_name returns as its value
1816 a string for the Lisp function system-name to return. */
1822 /* Can't have this within the function since `static' is #defined to
1823 nothing for some USG systems. */
1825 #ifdef HAVE_GETHOSTNAME
1826 static char get_system_name_name
[256];
1827 #else /* not HAVE_GETHOSTNAME */
1828 static struct utsname get_system_name_name
;
1829 #endif /* not HAVE_GETHOSTNAME */
1836 #include <sys/socket.h>
1838 #endif /* HAVE_SOCKETS */
1839 #endif /* not VMS */
1840 #endif /* not USG */
1841 #endif /* not BSD4_1 */
1847 #ifdef HAVE_GETHOSTNAME
1848 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1849 return get_system_name_name
;
1850 #else /* not HAVE_GETHOSTNAME */
1851 uname (&get_system_name_name
);
1852 return (get_system_name_name
.nodename
);
1853 #endif /* not HAVE_GETHOSTNAME */
1857 #else /* not USG, not 4.1 */
1858 static char system_name_saved
[32];
1861 if ((sp
= egetenv ("SYS$NODE")) == 0)
1867 if ((end
= index (sp
, ':')) != 0)
1870 strcpy (system_name_saved
, sp
);
1872 gethostname (system_name_saved
, sizeof (system_name_saved
));
1874 /* Turn the hostname into the official, fully-qualified hostname.
1875 Don't do this if we're going to dump; this can confuse system
1876 libraries on some machines and make the dumped emacs core dump. */
1879 #endif /* not CANNOT_DUMP */
1882 hp
= gethostbyname (system_name_saved
);
1883 if (hp
&& strlen (hp
->h_name
) < sizeof(system_name_saved
))
1884 strcpy (system_name_saved
, hp
->h_name
);
1886 #endif /* HAVE_SOCKETS */
1887 #endif /* not VMS */
1888 return system_name_saved
;
1889 #endif /* not USG, not 4.1 */
1890 #endif /* not USG */
1894 #ifndef HAVE_GETHOSTNAME
1895 void gethostname(buf
, len
)
1900 s
= getenv ("SYS$NODE");
1904 strncpy (buf
, s
, len
- 2);
1905 buf
[len
- 1] = '\0';
1907 } /* static void gethostname */
1908 #endif /* ! HAVE_GETHOSTNAME */
1915 #ifdef HAVE_X_WINDOWS
1916 /* Cause explanatory error message at compile time,
1917 since the select emulation is not good enough for X. */
1918 int *x
= &x_windows_lose_if_no_select_system_call
;
1921 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1922 * Only checks read descriptors.
1924 /* How long to wait between checking fds in select */
1925 #define SELECT_PAUSE 1
1928 /* For longjmp'ing back to read_input_waiting. */
1930 jmp_buf read_alarm_throw
;
1932 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1933 The read_socket_hook function sets this to 1 while it is waiting. */
1935 int read_alarm_should_throw
;
1943 #else /* not BSD4_1 */
1944 signal (SIGALRM
, SIG_IGN
);
1945 #endif /* not BSD4_1 */
1946 if (read_alarm_should_throw
)
1947 longjmp (read_alarm_throw
, 1);
1950 /* Only rfds are checked. */
1952 select (nfds
, rfds
, wfds
, efds
, timeout
)
1954 int *rfds
, *wfds
, *efds
, *timeout
;
1956 int ravail
= 0, orfds
= 0, old_alarm
;
1957 int timeoutval
= timeout
? *timeout
: 100000;
1958 int *local_timeout
= &timeoutval
;
1959 extern int proc_buffered_char
[];
1960 #ifndef subprocesses
1961 int process_tick
= 0, update_tick
= 0;
1963 extern int process_tick
, update_tick
;
1965 SIGTYPE (*old_trap
) ();
1978 /* If we are looking only for the terminal, with no timeout,
1979 just read it and wait -- that's more efficient. */
1980 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1982 if (! detect_input_pending ())
1983 read_input_waiting ();
1988 /* Once a second, till the timer expires, check all the flagged read
1989 * descriptors to see if any input is available. If there is some then
1990 * set the corresponding bit in the return copy of rfds.
1994 register int to_check
, bit
, fd
;
1998 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
2002 int avail
= 0, status
= 0;
2005 avail
= detect_input_pending (); /* Special keyboard handler */
2009 status
= ioctl (fd
, FIONREAD
, &avail
);
2010 #else /* no FIONREAD */
2011 /* Hoping it will return -1 if nothing available
2012 or 0 if all 0 chars requested are read. */
2013 if (proc_buffered_char
[fd
] >= 0)
2017 avail
= read (fd
, &buf
, 1);
2019 proc_buffered_char
[fd
] = buf
;
2021 #endif /* no FIONREAD */
2023 if (status
>= 0 && avail
> 0)
2031 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2033 old_alarm
= alarm (0);
2034 old_trap
= signal (SIGALRM
, select_alarm
);
2036 alarm (SELECT_PAUSE
);
2037 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2038 while (select_alarmed
== 0 && *local_timeout
!= 0
2039 && process_tick
== update_tick
)
2041 /* If we are interested in terminal input,
2042 wait by reading the terminal.
2043 That makes instant wakeup for terminal input at least. */
2046 read_input_waiting ();
2047 if (detect_input_pending ())
2053 (*local_timeout
) -= SELECT_PAUSE
;
2054 /* Reset the old alarm if there was one */
2056 signal (SIGALRM
, old_trap
);
2059 /* Reset or forge an interrupt for the original handler. */
2060 old_alarm
-= SELECT_PAUSE
;
2062 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
2066 if (*local_timeout
== 0) /* Stop on timer being cleared */
2072 /* Read keyboard input into the standard buffer,
2073 waiting for at least one character. */
2075 /* Make all keyboard buffers much bigger when using X windows. */
2076 #ifdef HAVE_X_WINDOWS
2077 #define BUFFER_SIZE_FACTOR 16
2079 #define BUFFER_SIZE_FACTOR 1
2082 read_input_waiting ()
2084 char buf
[256 * BUFFER_SIZE_FACTOR
];
2085 struct input_event e
;
2087 extern int quit_char
;
2089 if (read_socket_hook
)
2091 read_alarm_should_throw
= 0;
2092 if (! setjmp (read_alarm_throw
))
2093 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
2098 nread
= read (fileno (stdin
), buf
, 1);
2100 /* Scan the chars for C-g and store them in kbd_buffer. */
2101 e
.kind
= ascii_keystroke
;
2102 e
.frame_or_window
= selected_frame
;
2104 for (i
= 0; i
< nread
; i
++)
2106 XSET (e
.code
, Lisp_Int
, buf
[i
]);
2107 kbd_buffer_store_event (&e
);
2108 /* Don't look at input that follows a C-g too closely.
2109 This reduces lossage due to autorepeat on C-g. */
2110 if (buf
[i
] == quit_char
)
2115 #endif /* not HAVE_SELECT */
2116 #endif /* not VMS */
2120 * Partially emulate 4.2 open call.
2121 * open is defined as this in 4.1.
2123 * - added by Michael Bloom @ Citicorp/TTI
2128 sys_open (path
, oflag
, mode
)
2132 if (oflag
& O_CREAT
)
2133 return creat (path
, mode
);
2135 return open (path
, oflag
);
2142 lmode
= LINTRUP
| lmode
;
2143 ioctl (0, TIOCLSET
, &lmode
);
2150 lmode
= ~LINTRUP
& lmode
;
2151 ioctl (0, TIOCLSET
, &lmode
);
2158 interrupts_deferred
= 0;
2165 interrupts_deferred
= 1;
2168 /* still inside #ifdef BSD4_1 */
2171 int sigheld
; /* Mask of held signals */
2176 sigheld
|= sigbit (signum
);
2183 sigheld
|= sigbit (signum
);
2189 sigheld
&= ~sigbit (signum
);
2193 sigfree () /* Free all held signals */
2196 for (i
= 0; i
< NSIG
; i
++)
2197 if (sigheld
& sigbit (i
))
2204 return 1 << (i
- 1);
2206 #endif /* subprocesses */
2209 /* POSIX signals support - DJB */
2210 /* Anyone with POSIX signals should have ANSI C declarations */
2212 #ifdef POSIX_SIGNALS
2214 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
2215 static struct sigaction new_action
, old_action
;
2219 sigemptyset (&empty_mask
);
2220 sigfillset (&full_mask
);
2224 sys_signal (int signal_number
, signal_handler_t action
)
2227 /* This gets us restartable system calls for efficiency.
2228 The "else" code will works as well. */
2229 return (berk_signal (signal_number
, action
));
2231 sigemptyset (&new_action
.sa_mask
);
2232 new_action
.sa_handler
= action
;
2233 new_action
.sa_flags
= 0;
2234 sigaction (signal_number
, &new_action
, &old_action
);
2235 return (old_action
.sa_handler
);
2240 /* If we're compiling with GCC, we don't need this function, since it
2241 can be written as a macro. */
2243 sys_sigmask (int sig
)
2246 sigemptyset (&mask
);
2247 sigaddset (&mask
, sig
);
2253 sys_sigpause (sigset_t new_mask
)
2255 /* pause emulating berk sigpause... */
2256 sigsuspend (&new_mask
);
2260 /* I'd like to have these guys return pointers to the mask storage in here,
2261 but there'd be trouble if the code was saving multiple masks. I'll be
2262 safe and pass the structure. It normally won't be more than 2 bytes
2266 sys_sigblock (sigset_t new_mask
)
2269 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2274 sys_sigunblock (sigset_t new_mask
)
2277 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2282 sys_sigsetmask (sigset_t new_mask
)
2285 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2289 #endif /* POSIX_SIGNALS */
2296 register int length
;
2300 long max_str
= 65535;
2302 while (length
> max_str
) {
2303 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2308 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2310 while (length
-- > 0)
2312 #endif /* not VMS */
2315 /* Saying `void' requires a declaration, above, where bcopy is used
2316 and that declaration causes pain for systems where bcopy is a macro. */
2317 bcopy (b1
, b2
, length
)
2320 register int length
;
2323 long max_str
= 65535;
2325 while (length
> max_str
) {
2326 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2332 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2334 while (length
-- > 0)
2336 #endif /* not VMS */
2340 bcmp (b1
, b2
, length
) /* This could be a macro! */
2343 register int length
;
2346 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2347 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2349 return STR$
COMPARE (&src1
, &src2
);
2351 while (length
-- > 0)
2356 #endif /* not VMS */
2358 #endif /* not BSTRING */
2363 * The BSD random returns numbers in the range of
2364 * 0 to 2e31 - 1. The USG rand returns numbers in the
2365 * range of 0 to 2e15 - 1. This is probably not significant
2372 /* Arrange to return a range centered on zero. */
2373 return (rand () << 15) + rand () - (1 << 29);
2387 /* Arrange to return a range centered on zero. */
2388 return (rand () << 15) + rand () - (1 << 29);
2399 #ifdef WRONG_NAME_INSQUE
2412 /* If any place else asks for the TERM variable,
2413 allow it to be overridden with the EMACS_TERM variable
2414 before attempting to translate the logical name TERM. As a last
2415 resort, ask for VAX C's special idea of the TERM variable. */
2422 static char buf
[256];
2423 static struct dsc$descriptor_s equiv
2424 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2425 static struct dsc$descriptor_s d_name
2426 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2429 if (!strcmp (name
, "TERM"))
2431 val
= (char *) getenv ("EMACS_TERM");
2436 d_name
.dsc$w_length
= strlen (name
);
2437 d_name
.dsc$a_pointer
= name
;
2438 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2440 char *str
= (char *) xmalloc (eqlen
+ 1);
2441 bcopy (buf
, str
, eqlen
);
2443 /* This is a storage leak, but a pain to fix. With luck,
2444 no one will ever notice. */
2447 return (char *) getenv (name
);
2452 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2453 to force a call on the debugger from within the image. */
2458 LIB$
SIGNAL (SS$_DEBUG
);
2464 #ifdef LINK_CRTL_SHARE
2465 #ifdef SHAREABLE_LIB_BUG
2466 /* Variables declared noshare and initialized in sharable libraries
2467 cannot be shared. The VMS linker incorrectly forces you to use a private
2468 version which is uninitialized... If not for this "feature", we
2469 could use the C library definition of sys_nerr and sys_errlist. */
2471 char *sys_errlist
[] =
2475 "no such file or directory",
2477 "interrupted system call",
2479 "no such device or address",
2480 "argument list too long",
2481 "exec format error",
2484 "no more processes",
2485 "not enough memory",
2486 "permission denied",
2488 "block device required",
2489 "mount devices busy",
2491 "cross-device link",
2496 "file table overflow",
2497 "too many open files",
2501 "no space left on device",
2503 "read-only file system",
2509 "vax/vms specific error code nontranslatable error"
2511 #endif /* SHAREABLE_LIB_BUG */
2512 #endif /* LINK_CRTL_SHARE */
2515 #ifdef INTERRUPTIBLE_OPEN
2519 sys_open (path
, oflag
, mode
)
2523 register int rtnval
;
2525 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2526 && (errno
== EINTR
));
2530 #endif /* INTERRUPTIBLE_OPEN */
2532 #ifdef INTERRUPTIBLE_CLOSE
2537 register int rtnval
;
2539 while ((rtnval
= close (fd
)) == -1
2540 && (errno
== EINTR
));
2544 #endif /* INTERRUPTIBLE_CLOSE */
2546 #ifdef INTERRUPTIBLE_IO
2549 sys_read (fildes
, buf
, nbyte
)
2554 register int rtnval
;
2556 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2557 && (errno
== EINTR
));
2562 sys_write (fildes
, buf
, nbyte
)
2567 register int rtnval
;
2569 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2570 && (errno
== EINTR
));
2574 #endif /* INTERRUPTIBLE_IO */
2578 * All of the following are for USG.
2580 * On USG systems the system calls are INTERRUPTIBLE by signals
2581 * that the user program has elected to catch. Thus the system call
2582 * must be retried in these cases. To handle this without massive
2583 * changes in the source code, we remap the standard system call names
2584 * to names for our own functions in sysdep.c that do the system call
2585 * with retries. Actually, for portability reasons, it is good
2586 * programming practice, as this example shows, to limit all actual
2587 * system calls to a single occurrence in the source. Sure, this
2588 * adds an extra level of function call overhead but it is almost
2589 * always negligible. Fred Fish, Unisoft Systems Inc.
2592 #ifndef HAVE_SYS_SIGLIST
2593 char *sys_siglist
[NSIG
+ 1] =
2596 /* AIX has changed the signals a bit */
2597 "bogus signal", /* 0 */
2598 "hangup", /* 1 SIGHUP */
2599 "interrupt", /* 2 SIGINT */
2600 "quit", /* 3 SIGQUIT */
2601 "illegal instruction", /* 4 SIGILL */
2602 "trace trap", /* 5 SIGTRAP */
2603 "IOT instruction", /* 6 SIGIOT */
2604 "crash likely", /* 7 SIGDANGER */
2605 "floating point exception", /* 8 SIGFPE */
2606 "kill", /* 9 SIGKILL */
2607 "bus error", /* 10 SIGBUS */
2608 "segmentation violation", /* 11 SIGSEGV */
2609 "bad argument to system call", /* 12 SIGSYS */
2610 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2611 "alarm clock", /* 14 SIGALRM */
2612 "software termination signum", /* 15 SIGTERM */
2613 "user defined signal 1", /* 16 SIGUSR1 */
2614 "user defined signal 2", /* 17 SIGUSR2 */
2615 "death of a child", /* 18 SIGCLD */
2616 "power-fail restart", /* 19 SIGPWR */
2617 "bogus signal", /* 20 */
2618 "bogus signal", /* 21 */
2619 "bogus signal", /* 22 */
2620 "bogus signal", /* 23 */
2621 "bogus signal", /* 24 */
2622 "LAN I/O interrupt", /* 25 SIGAIO */
2623 "PTY I/O interrupt", /* 26 SIGPTY */
2624 "I/O intervention required", /* 27 SIGIOINT */
2625 "HFT grant", /* 28 SIGGRANT */
2626 "HFT retract", /* 29 SIGRETRACT */
2627 "HFT sound done", /* 30 SIGSOUND */
2628 "HFT input ready", /* 31 SIGMSG */
2630 "bogus signal", /* 0 */
2631 "hangup", /* 1 SIGHUP */
2632 "interrupt", /* 2 SIGINT */
2633 "quit", /* 3 SIGQUIT */
2634 "illegal instruction", /* 4 SIGILL */
2635 "trace trap", /* 5 SIGTRAP */
2636 "IOT instruction", /* 6 SIGIOT */
2637 "EMT instruction", /* 7 SIGEMT */
2638 "floating point exception", /* 8 SIGFPE */
2639 "kill", /* 9 SIGKILL */
2640 "bus error", /* 10 SIGBUS */
2641 "segmentation violation", /* 11 SIGSEGV */
2642 "bad argument to system call", /* 12 SIGSYS */
2643 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2644 "alarm clock", /* 14 SIGALRM */
2645 "software termination signum", /* 15 SIGTERM */
2646 "user defined signal 1", /* 16 SIGUSR1 */
2647 "user defined signal 2", /* 17 SIGUSR2 */
2648 "death of a child", /* 18 SIGCLD */
2649 "power-fail restart", /* 19 SIGPWR */
2650 #endif /* not AIX */
2653 #endif /* HAVE_SYS_SIGLIST */
2656 * Warning, this function may not duplicate 4.2 action properly
2657 * under error conditions.
2661 /* In 4.1, param.h fails to define this. */
2662 #define MAXPATHLEN 1024
2671 char *npath
, *spath
;
2672 extern char *getcwd ();
2674 BLOCK_INPUT
; /* getcwd uses malloc */
2675 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2676 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2677 up to first slash. Should be harmless on other systems. */
2678 while (*npath
&& *npath
!= '/')
2680 strcpy (pathname
, npath
);
2681 free (spath
); /* getcwd uses malloc */
2686 #endif /* HAVE_GETWD */
2689 * Emulate rename using unlink/link. Note that this is
2690 * only partially correct. Also, doesn't enforce restriction
2691 * that files be of same type (regular->regular, dir->dir, etc).
2700 if (access (from
, 0) == 0)
2703 if (link (from
, to
) == 0)
2704 if (unlink (from
) == 0)
2715 * Substitute fork for vfork on USG flavors.
2723 #endif /* not HAVE_VFORK */
2725 #ifdef MISSING_UTIMES
2727 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2736 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2737 utimbuf structure defined anywhere but in the man page. */
2747 struct timeval tvp
[];
2750 utb
.actime
= tvp
[0].tv_sec
;
2751 utb
.modtime
= tvp
[1].tv_sec
;
2754 #endif /* IRIS_UTIME */
2760 /* HPUX curses library references perror, but as far as we know
2761 it won't be called. Anyway this definition will do for now. */
2767 #endif /* not HAVE_PERROR */
2773 * Emulate BSD dup2. First close newd if it already exists.
2774 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2775 * until we are, then close the unsuccessful ones.
2782 register int fd
, ret
;
2787 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2789 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2796 ret
= dup2 (old
,new);
2802 #endif /* not HAVE_DUP2 */
2805 * Gettimeofday. Simulate as much as possible. Only accurate
2806 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2807 * Only needed when subprocesses are defined.
2812 #ifndef HAVE_GETTIMEOFDAY
2816 gettimeofday (tp
, tzp
)
2818 struct timezone
*tzp
;
2820 extern long time ();
2822 tp
->tv_sec
= time ((long *)0);
2825 tzp
->tz_minuteswest
= -1;
2831 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2834 * This function will go away as soon as all the stubs fixed. (fnf)
2840 printf ("%s not yet implemented\r\n", badfunc
);
2849 char *sys_siglist
[NSIG
+ 1] =
2851 "null signal", /* 0 SIGNULL */
2852 "hangup", /* 1 SIGHUP */
2853 "interrupt", /* 2 SIGINT */
2854 "quit", /* 3 SIGQUIT */
2855 "illegal instruction", /* 4 SIGILL */
2856 "trace trap", /* 5 SIGTRAP */
2857 "abort termination", /* 6 SIGABRT */
2858 "SIGEMT", /* 7 SIGEMT */
2859 "floating point exception", /* 8 SIGFPE */
2860 "kill", /* 9 SIGKILL */
2861 "bus error", /* 10 SIGBUS */
2862 "segmentation violation", /* 11 SIGSEGV */
2863 "bad argument to system call", /* 12 SIGSYS */
2864 "write on a pipe with no reader", /* 13 SIGPIPE */
2865 "alarm clock", /* 14 SIGALRM */
2866 "software termination signal", /* 15 SIGTERM */
2867 "user defined signal 1", /* 16 SIGUSR1 */
2868 "user defined signal 2", /* 17 SIGUSR2 */
2869 "child stopped or terminated", /* 18 SIGCLD */
2870 "power-fail restart", /* 19 SIGPWR */
2871 "window size changed", /* 20 SIGWINCH */
2872 "undefined", /* 21 */
2873 "pollable event occurred", /* 22 SIGPOLL */
2874 "sendable stop signal not from tty", /* 23 SIGSTOP */
2875 "stop signal from tty", /* 24 SIGSTP */
2876 "continue a stopped process", /* 25 SIGCONT */
2877 "attempted background tty read", /* 26 SIGTTIN */
2878 "attempted background tty write", /* 27 SIGTTOU */
2879 "undefined", /* 28 */
2880 "undefined", /* 29 */
2881 "undefined", /* 30 */
2882 "undefined", /* 31 */
2883 "undefined", /* 32 */
2884 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2885 "I/O is possible", /* 34 SIGIO */
2886 "exceeded cpu time limit", /* 35 SIGXCPU */
2887 "exceeded file size limit", /* 36 SIGXFSZ */
2888 "virtual time alarm", /* 37 SIGVTALRM */
2889 "profiling time alarm", /* 38 SIGPROF */
2890 "undefined", /* 39 */
2891 "file record locks revoked", /* 40 SIGLOST */
2892 "undefined", /* 41 */
2893 "undefined", /* 42 */
2894 "undefined", /* 43 */
2895 "undefined", /* 44 */
2896 "undefined", /* 45 */
2897 "undefined", /* 46 */
2898 "undefined", /* 47 */
2899 "undefined", /* 48 */
2900 "undefined", /* 49 */
2901 "undefined", /* 50 */
2902 "undefined", /* 51 */
2903 "undefined", /* 52 */
2904 "undefined", /* 53 */
2905 "undefined", /* 54 */
2906 "undefined", /* 55 */
2907 "undefined", /* 56 */
2908 "undefined", /* 57 */
2909 "undefined", /* 58 */
2910 "undefined", /* 59 */
2911 "undefined", /* 60 */
2912 "undefined", /* 61 */
2913 "undefined", /* 62 */
2914 "undefined", /* 63 */
2915 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2921 /* Directory routines for systems that don't have them. */
2923 #ifdef SYSV_SYSTEM_DIR
2927 #ifndef HAVE_CLOSEDIR
2930 register DIR *dirp
; /* stream from opendir */
2932 sys_close (dirp
->dd_fd
);
2934 /* Some systems (like Solaris) allocate the buffer and the DIR all
2935 in one block. Why in the world are we freeing this ourselves
2937 #if ! (defined (sun) && defined (USG5_4))
2938 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2940 xfree ((char *) dirp
);
2942 #endif /* not HAVE_CLOSEDIR */
2943 #endif /* SYSV_SYSTEM_DIR */
2945 #ifdef NONSYSTEM_DIR_LIBRARY
2949 char *filename
; /* name of directory */
2951 register DIR *dirp
; /* -> malloc'ed storage */
2952 register int fd
; /* file descriptor for read */
2953 struct stat sbuf
; /* result of fstat */
2955 fd
= sys_open (filename
, 0);
2960 if (fstat (fd
, &sbuf
) < 0
2961 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2962 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2966 return 0; /* bad luck today */
2971 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2978 register DIR *dirp
; /* stream from opendir */
2980 sys_close (dirp
->dd_fd
);
2981 xfree ((char *) dirp
);
2989 ino_t od_ino
; /* inode */
2990 char od_name
[DIRSIZ
]; /* filename */
2992 #endif /* not VMS */
2994 struct direct dir_static
; /* simulated directory contents */
2999 register DIR *dirp
; /* stream from opendir */
3002 register struct olddir
*dp
; /* -> directory data */
3004 register struct dir$_name
*dp
; /* -> directory data */
3005 register struct dir$_version
*dv
; /* -> version data */
3010 if (dirp
->dd_loc
>= dirp
->dd_size
)
3011 dirp
->dd_loc
= dirp
->dd_size
= 0;
3013 if (dirp
->dd_size
== 0 /* refill buffer */
3014 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3018 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3019 dirp
->dd_loc
+= sizeof (struct olddir
);
3021 if (dp
->od_ino
!= 0) /* not deleted entry */
3023 dir_static
.d_ino
= dp
->od_ino
;
3024 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3025 dir_static
.d_name
[DIRSIZ
] = '\0';
3026 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3027 dir_static
.d_reclen
= sizeof (struct direct
)
3029 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3030 return &dir_static
; /* -> simulated structure */
3033 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3034 if (dirp
->dd_loc
== 0)
3035 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3036 : dp
->dir$b_namecount
;
3037 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3038 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3039 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3040 dir_static
.d_reclen
= sizeof (struct direct
)
3042 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3043 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3044 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3045 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3052 /* readdirver is just like readdir except it returns all versions of a file
3053 as separate entries. */
3058 register DIR *dirp
; /* stream from opendir */
3060 register struct dir$_name
*dp
; /* -> directory data */
3061 register struct dir$_version
*dv
; /* -> version data */
3063 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3064 dirp
->dd_loc
= dirp
->dd_size
= 0;
3066 if (dirp
->dd_size
== 0 /* refill buffer */
3067 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3070 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3071 if (dirp
->dd_loc
== 0)
3072 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3073 : dp
->dir$b_namecount
;
3074 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3075 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3076 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3077 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3078 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3079 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3080 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3081 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3087 #endif /* NONSYSTEM_DIR_LIBRARY */
3089 /* Functions for VMS */
3091 #include "vms-pwd.h"
3096 /* Return as a string the VMS error string pertaining to STATUS.
3097 Reuses the same static buffer each time it is called. */
3101 int status
; /* VMS status code */
3105 static char buf
[257];
3107 bufadr
[0] = sizeof buf
- 1;
3108 bufadr
[1] = (int) buf
;
3109 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3110 return "untranslatable VMS error status";
3118 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3119 * not work correctly. (It also doesn't work well in version 2.3.)
3124 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3125 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3129 unsigned short s_buflen
;
3130 unsigned short s_code
;
3132 unsigned short *s_retlenadr
;
3136 #define buflen s.s_buflen
3137 #define code s.s_code
3138 #define bufadr s.s_bufadr
3139 #define retlenadr s.s_retlenadr
3141 #define R_OK 4 /* test for read permission */
3142 #define W_OK 2 /* test for write permission */
3143 #define X_OK 1 /* test for execute (search) permission */
3144 #define F_OK 0 /* test for presence of file */
3147 sys_access (path
, mode
)
3151 static char *user
= NULL
;
3154 /* translate possible directory spec into .DIR file name, so brain-dead
3155 * access can treat the directory like a file. */
3156 if (directory_file_name (path
, dir_fn
))
3160 return access (path
, mode
);
3161 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3167 unsigned short int dummy
;
3169 static int constant
= ACL$C_FILE
;
3170 DESCRIPTOR (path_desc
, path
);
3171 DESCRIPTOR (user_desc
, user
);
3175 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3178 acces
|= CHP$M_READ
;
3180 acces
|= CHP$M_WRITE
;
3181 itemlst
[0].buflen
= sizeof (int);
3182 itemlst
[0].code
= CHP$_FLAGS
;
3183 itemlst
[0].bufadr
= (char *) &flags
;
3184 itemlst
[0].retlenadr
= &dummy
;
3185 itemlst
[1].buflen
= sizeof (int);
3186 itemlst
[1].code
= CHP$_ACCESS
;
3187 itemlst
[1].bufadr
= (char *) &acces
;
3188 itemlst
[1].retlenadr
= &dummy
;
3189 itemlst
[2].end
= CHP$_END
;
3190 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3191 return stat
== SS$_NORMAL
? 0 : -1;
3195 #else /* not VMS4_4 */
3198 #define ACE$M_WRITE 2
3199 #define ACE$C_KEYID 1
3201 static unsigned short memid
, grpid
;
3202 static unsigned int uic
;
3204 /* Called from init_sys_modes, so it happens not very often
3205 but at least each time Emacs is loaded. */
3206 sys_access_reinit ()
3212 sys_access (filename
, type
)
3218 int status
, size
, i
, typecode
, acl_controlled
;
3219 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3220 union prvdef prvmask
;
3222 /* Get UIC and GRP values for protection checking. */
3225 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3228 memid
= uic
& 0xFFFF;
3232 if (type
!= 2) /* not checking write access */
3233 return access (filename
, type
);
3235 /* Check write protection. */
3237 #define CHECKPRIV(bit) (prvmask.bit)
3238 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3240 /* Find privilege bits */
3241 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3243 error ("Unable to find privileges: %s", vmserrstr (status
));
3244 if (CHECKPRIV (PRV$V_BYPASS
))
3245 return 0; /* BYPASS enabled */
3247 fab
.fab$b_fac
= FAB$M_GET
;
3248 fab
.fab$l_fna
= filename
;
3249 fab
.fab$b_fns
= strlen (filename
);
3250 fab
.fab$l_xab
= &xab
;
3251 xab
= cc$rms_xabpro
;
3252 xab
.xab$l_aclbuf
= aclbuf
;
3253 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3254 status
= SYS$
OPEN (&fab
, 0, 0);
3257 SYS$
CLOSE (&fab
, 0, 0);
3258 /* Check system access */
3259 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
3261 /* Check ACL entries, if any */
3263 if (xab
.xab$w_acllen
> 0)
3266 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3267 while (*aclptr
&& aclptr
< aclend
)
3269 size
= (*aclptr
& 0xff) / 4;
3270 typecode
= (*aclptr
>> 8) & 0xff;
3271 if (typecode
== ACE$C_KEYID
)
3272 for (i
= size
- 1; i
> 1; i
--)
3273 if (aclptr
[i
] == uic
)
3276 if (aclptr
[1] & ACE$M_WRITE
)
3277 return 0; /* Write access through ACL */
3279 aclptr
= &aclptr
[size
];
3281 if (acl_controlled
) /* ACL specified, prohibits write access */
3284 /* No ACL entries specified, check normal protection */
3285 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3287 if (WRITEABLE (XAB$V_GRP
) &&
3288 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3289 return 0; /* Group writeable */
3290 if (WRITEABLE (XAB$V_OWN
) &&
3291 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3292 return 0; /* Owner writeable */
3294 return -1; /* Not writeable */
3296 #endif /* not VMS4_4 */
3299 static char vtbuf
[NAM$C_MAXRSS
+1];
3301 /* translate a vms file spec to a unix path */
3303 sys_translate_vms (vfile
)
3314 /* leading device or logical name is a root directory */
3315 if (p
= strchr (vfile
, ':'))
3324 if (*p
== '[' || *p
== '<')
3326 while (*++vfile
!= *p
+ 2)
3330 if (vfile
[-1] == *p
)
3353 static char utbuf
[NAM$C_MAXRSS
+1];
3355 /* translate a unix path to a VMS file spec */
3357 sys_translate_unix (ufile
)
3380 if (index (&ufile
[1], '/'))
3387 if (index (&ufile
[1], '/'))
3394 if (strncmp (ufile
, "./", 2) == 0)
3401 ufile
++; /* skip the dot */
3402 if (index (&ufile
[1], '/'))
3407 else if (strncmp (ufile
, "../", 3) == 0)
3415 ufile
+= 2; /* skip the dots */
3416 if (index (&ufile
[1], '/'))
3441 extern char *getcwd ();
3443 #define MAXPATHLEN 1024
3445 ptr
= xmalloc (MAXPATHLEN
);
3446 getcwd (ptr
, MAXPATHLEN
);
3447 strcpy (pathname
, ptr
);
3455 long item_code
= JPI$_OWNER
;
3456 unsigned long parent_id
;
3459 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3462 vaxc$errno
= status
;
3472 return (getgid () << 16) | getuid ();
3476 sys_read (fildes
, buf
, nbyte
)
3481 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3486 sys_write (fildes
, buf
, nbyte
)
3491 register int nwrote
, rtnval
= 0;
3493 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3499 return rtnval
? rtnval
: -1;
3500 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3501 return rtnval
? rtnval
: -1;
3502 return (rtnval
+ nwrote
);
3507 * VAX/VMS VAX C RTL really loses. It insists that records
3508 * end with a newline (carriage return) character, and if they
3509 * don't it adds one (nice of it isn't it!)
3511 * Thus we do this stupidity below.
3515 sys_write (fildes
, buf
, nbytes
)
3518 unsigned int nbytes
;
3525 fstat (fildes
, &st
);
3531 /* Handle fixed-length files with carriage control. */
3532 if (st
.st_fab_rfm
== FAB$C_FIX
3533 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3535 len
= st
.st_fab_mrs
;
3536 retval
= write (fildes
, p
, min (len
, nbytes
));
3539 retval
++; /* This skips the implied carriage control */
3543 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3544 while (*e
!= '\n' && e
> p
) e
--;
3545 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3546 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3548 retval
= write (fildes
, p
, len
);
3559 /* Create file NEW copying its attributes from file OLD. If
3560 OLD is 0 or does not exist, create based on the value of
3563 /* Protection value the file should ultimately have.
3564 Set by create_copy_attrs, and use by rename_sansversions. */
3565 static unsigned short int fab_final_pro
;
3568 creat_copy_attrs (old
, new)
3571 struct FAB fab
= cc$rms_fab
;
3572 struct XABPRO xabpro
;
3573 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3574 extern int vms_stmlf_recfm
;
3578 fab
.fab$b_fac
= FAB$M_GET
;
3579 fab
.fab$l_fna
= old
;
3580 fab
.fab$b_fns
= strlen (old
);
3581 fab
.fab$l_xab
= (char *) &xabpro
;
3582 xabpro
= cc$rms_xabpro
;
3583 xabpro
.xab$l_aclbuf
= aclbuf
;
3584 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3585 /* Call $OPEN to fill in the fab & xabpro fields. */
3586 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3588 SYS$
CLOSE (&fab
, 0, 0);
3589 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3590 if (xabpro
.xab$w_acllen
> 0)
3592 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3593 /* If the acl buffer was too short, redo open with longer one.
3594 Wouldn't need to do this if there were some system imposed
3595 limit on the size of an ACL, but I can't find any such. */
3597 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3598 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3599 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3600 SYS$
CLOSE (&fab
, 0, 0);
3606 xabpro
.xab$l_aclbuf
= 0;
3611 fab
.fab$l_fna
= new;
3612 fab
.fab$b_fns
= strlen (new);
3616 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3617 fab
.fab$b_rat
= FAB$M_CR
;
3620 /* Set the file protections such that we will be able to manipulate
3621 this file. Once we are done writing and renaming it, we will set
3622 the protections back. */
3624 fab_final_pro
= xabpro
.xab$w_pro
;
3626 SYS$
SETDFPROT (0, &fab_final_pro
);
3627 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3629 /* Create the new file with either default attrs or attrs copied
3631 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3633 SYS$
CLOSE (&fab
, 0, 0);
3634 /* As this is a "replacement" for creat, return a file descriptor
3635 opened for writing. */
3636 return open (new, O_WRONLY
);
3641 #include <varargs.h>
3644 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3648 sys_creat (va_alist
)
3651 va_list list_incrementer
;
3654 int rfd
; /* related file descriptor */
3655 int fd
; /* Our new file descriptor */
3662 extern int vms_stmlf_recfm
;
3665 va_start (list_incrementer
);
3666 name
= va_arg (list_incrementer
, char *);
3667 mode
= va_arg (list_incrementer
, int);
3669 rfd
= va_arg (list_incrementer
, int);
3670 va_end (list_incrementer
);
3673 /* Use information from the related file descriptor to set record
3674 format of the newly created file. */
3675 fstat (rfd
, &st_buf
);
3676 switch (st_buf
.st_fab_rfm
)
3679 strcpy (rfm
, "rfm = fix");
3680 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3681 strcpy (rat
, "rat = ");
3682 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3684 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3685 strcat (rat
, "ftn");
3686 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3687 strcat (rat
, "prn");
3688 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3689 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3690 strcat (rat
, ", blk");
3692 strcat (rat
, "blk");
3693 return creat (name
, 0, rfm
, rat
, mrs
);
3696 strcpy (rfm
, "rfm = vfc");
3697 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3698 strcpy (rat
, "rat = ");
3699 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3701 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3702 strcat (rat
, "ftn");
3703 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3704 strcat (rat
, "prn");
3705 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3706 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3707 strcat (rat
, ", blk");
3709 strcat (rat
, "blk");
3710 return creat (name
, 0, rfm
, rat
, fsz
);
3713 strcpy (rfm
, "rfm = stm");
3717 strcpy (rfm
, "rfm = stmcr");
3721 strcpy (rfm
, "rfm = stmlf");
3725 strcpy (rfm
, "rfm = udf");
3729 strcpy (rfm
, "rfm = var");
3732 strcpy (rat
, "rat = ");
3733 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3735 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3736 strcat (rat
, "ftn");
3737 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3738 strcat (rat
, "prn");
3739 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3740 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3741 strcat (rat
, ", blk");
3743 strcat (rat
, "blk");
3747 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3748 strcpy (rat
, "rat=cr");
3750 /* Until the VAX C RTL fixes the many bugs with modes, always use
3751 mode 0 to get the user's default protection. */
3752 fd
= creat (name
, 0, rfm
, rat
);
3753 if (fd
< 0 && errno
== EEXIST
)
3755 if (unlink (name
) < 0)
3756 report_file_error ("delete", build_string (name
));
3757 fd
= creat (name
, 0, rfm
, rat
);
3763 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3764 sys_fwrite (ptr
, size
, num
, fp
)
3765 register char * ptr
;
3768 register int tot
= num
* size
;
3775 * The VMS C library routine creat actually creates a new version of an
3776 * existing file rather than truncating the old version. There are times
3777 * when this is not the desired behavior, for instance, when writing an
3778 * auto save file (you only want one version), or when you don't have
3779 * write permission in the directory containing the file (but the file
3780 * itself is writable). Hence this routine, which is equivalent to
3781 * "close (creat (fn, 0));" on Unix if fn already exists.
3787 struct FAB xfab
= cc$rms_fab
;
3788 struct RAB xrab
= cc$rms_rab
;
3791 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3792 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3793 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3794 xfab
.fab$l_fna
= fn
;
3795 xfab
.fab$b_fns
= strlen (fn
);
3796 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3798 xrab
.rab$l_fab
= &xfab
;
3800 /* This gibberish opens the file, positions to the first record, and
3801 deletes all records from there until the end of file. */
3802 if ((SYS$
OPEN (&xfab
) & 01) == 01)
3804 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
3805 (SYS$
FIND (&xrab
) & 01) == 01 &&
3806 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
3817 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3818 SYSPRV or a readable SYSUAF.DAT. */
3824 * Routine to read the VMS User Authorization File and return
3825 * a specific user's record.
3828 static struct UAF retuaf
;
3831 get_uaf_name (uname
)
3838 uaf_fab
= cc$rms_fab
;
3839 uaf_rab
= cc$rms_rab
;
3840 /* initialize fab fields */
3841 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3842 uaf_fab
.fab$b_fns
= 21;
3843 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3844 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3845 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3846 /* initialize rab fields */
3847 uaf_rab
.rab$l_fab
= &uaf_fab
;
3848 /* open the User Authorization File */
3849 status
= SYS$
OPEN (&uaf_fab
);
3853 vaxc$errno
= status
;
3856 status
= SYS$
CONNECT (&uaf_rab
);
3860 vaxc$errno
= status
;
3863 /* read the requested record - index is in uname */
3864 uaf_rab
.rab$l_kbf
= uname
;
3865 uaf_rab
.rab$b_ksz
= strlen (uname
);
3866 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3867 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3868 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3869 status
= SYS$
GET (&uaf_rab
);
3873 vaxc$errno
= status
;
3876 /* close the User Authorization File */
3877 status
= SYS$
DISCONNECT (&uaf_rab
);
3881 vaxc$errno
= status
;
3884 status
= SYS$
CLOSE (&uaf_fab
);
3888 vaxc$errno
= status
;
3902 uaf_fab
= cc$rms_fab
;
3903 uaf_rab
= cc$rms_rab
;
3904 /* initialize fab fields */
3905 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3906 uaf_fab
.fab$b_fns
= 21;
3907 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3908 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3909 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3910 /* initialize rab fields */
3911 uaf_rab
.rab$l_fab
= &uaf_fab
;
3912 /* open the User Authorization File */
3913 status
= SYS$
OPEN (&uaf_fab
);
3917 vaxc$errno
= status
;
3920 status
= SYS$
CONNECT (&uaf_rab
);
3924 vaxc$errno
= status
;
3927 /* read the requested record - index is in uic */
3928 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3929 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3930 uaf_rab
.rab$b_ksz
= sizeof uic
;
3931 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3932 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3933 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3934 status
= SYS$
GET (&uaf_rab
);
3938 vaxc$errno
= status
;
3941 /* close the User Authorization File */
3942 status
= SYS$
DISCONNECT (&uaf_rab
);
3946 vaxc$errno
= status
;
3949 status
= SYS$
CLOSE (&uaf_fab
);
3953 vaxc$errno
= status
;
3959 static struct passwd retpw
;
3967 /* copy these out first because if the username is 32 chars, the next
3968 section will overwrite the first byte of the UIC */
3969 retpw
.pw_uid
= up
->uaf$w_mem
;
3970 retpw
.pw_gid
= up
->uaf$w_grp
;
3972 /* I suppose this is not the best sytle, to possibly overwrite one
3973 byte beyond the end of the field, but what the heck... */
3974 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3975 while (ptr
[-1] == ' ')
3978 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3980 /* the rest of these are counted ascii strings */
3981 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3982 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3983 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3984 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3985 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3986 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3987 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3988 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3992 #else /* not READ_SYSUAF */
3993 static struct passwd retpw
;
3994 #endif /* not READ_SYSUAF */
4005 unsigned char * full
;
4006 #endif /* READ_SYSUAF */
4011 if ('a' <= *ptr
&& *ptr
<= 'z')
4016 if (!(up
= get_uaf_name (name
)))
4018 return cnv_uaf_pw (up
);
4020 if (strcmp (name
, getenv ("USER")) == 0)
4022 retpw
.pw_uid
= getuid ();
4023 retpw
.pw_gid
= getgid ();
4024 strcpy (retpw
.pw_name
, name
);
4025 if (full
= egetenv ("FULLNAME"))
4026 strcpy (retpw
.pw_gecos
, full
);
4028 *retpw
.pw_gecos
= '\0';
4029 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4030 *retpw
.pw_shell
= '\0';
4035 #endif /* not READ_SYSUAF */
4045 if (!(up
= get_uaf_uic (uid
)))
4047 return cnv_uaf_pw (up
);
4049 if (uid
== sys_getuid ())
4050 return getpwnam (egetenv ("USER"));
4053 #endif /* not READ_SYSUAF */
4056 /* return total address space available to the current process. This is
4057 the sum of the current p0 size, p1 size and free page table entries
4062 unsigned long free_pages
;
4063 unsigned long frep0va
;
4064 unsigned long frep1va
;
4067 item_code
= JPI$_FREPTECNT
;
4068 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4071 vaxc$errno
= status
;
4076 item_code
= JPI$_FREP0VA
;
4077 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4080 vaxc$errno
= status
;
4083 item_code
= JPI$_FREP1VA
;
4084 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4087 vaxc$errno
= status
;
4091 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4094 define_logical_name (varname
, string
)
4098 struct dsc$descriptor_s strdsc
=
4099 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4100 struct dsc$descriptor_s envdsc
=
4101 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4102 struct dsc$descriptor_s lnmdsc
=
4103 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4105 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4108 delete_logical_name (varname
)
4111 struct dsc$descriptor_s envdsc
=
4112 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4113 struct dsc$descriptor_s lnmdsc
=
4114 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4116 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4127 error ("execvp system call not implemented");
4135 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4136 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4137 char from_esn
[NAM$C_MAXRSS
];
4138 char to_esn
[NAM$C_MAXRSS
];
4140 from_fab
.fab$l_fna
= from
;
4141 from_fab
.fab$b_fns
= strlen (from
);
4142 from_fab
.fab$l_nam
= &from_nam
;
4143 from_fab
.fab$l_fop
= FAB$M_NAM
;
4145 from_nam
.nam$l_esa
= from_esn
;
4146 from_nam
.nam$b_ess
= sizeof from_esn
;
4148 to_fab
.fab$l_fna
= to
;
4149 to_fab
.fab$b_fns
= strlen (to
);
4150 to_fab
.fab$l_nam
= &to_nam
;
4151 to_fab
.fab$l_fop
= FAB$M_NAM
;
4153 to_nam
.nam$l_esa
= to_esn
;
4154 to_nam
.nam$b_ess
= sizeof to_esn
;
4156 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4162 if (status
== RMS$_DEV
)
4166 vaxc$errno
= status
;
4171 /* This function renames a file like `rename', but it strips
4172 the version number from the "to" filename, such that the "to" file is
4173 will always be a new version. It also sets the file protection once it is
4174 finished. The protection that we will use is stored in fab_final_pro,
4175 and was set when we did a creat_copy_attrs to create the file that we
4178 We could use the chmod function, but Eunichs uses 3 bits per user category
4179 to describe the protection, and VMS uses 4 (write and delete are separate
4180 bits). To maintain portability, the VMS implementation of `chmod' wires
4181 the W and D bits together. */
4184 static struct fibdef fib
; /* We need this initialized to zero */
4185 char vms_file_written
[NAM$C_MAXRSS
];
4188 rename_sans_version (from
,to
)
4195 struct FAB to_fab
= cc$rms_fab
;
4196 struct NAM to_nam
= cc$rms_nam
;
4197 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4198 struct dsc$descriptor fib_attr
[2]
4199 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4200 char to_esn
[NAM$C_MAXRSS
];
4202 $
DESCRIPTOR (disk
,to_esn
);
4204 to_fab
.fab$l_fna
= to
;
4205 to_fab
.fab$b_fns
= strlen (to
);
4206 to_fab
.fab$l_nam
= &to_nam
;
4207 to_fab
.fab$l_fop
= FAB$M_NAM
;
4209 to_nam
.nam$l_esa
= to_esn
;
4210 to_nam
.nam$b_ess
= sizeof to_esn
;
4212 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4214 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4215 *(to_nam
.nam$l_ver
) = '\0';
4217 stat
= rename (from
, to_esn
);
4221 strcpy (vms_file_written
, to_esn
);
4223 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4224 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4226 /* Now set the file protection to the correct value */
4227 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4229 /* Copy these fields into the fib */
4230 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4231 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4232 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4234 SYS$
CLOSE (&to_fab
, 0, 0);
4236 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4239 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4240 0, 0, 0, &fib_attr
, 0);
4243 stat
= SYS$
DASSGN (chan
);
4246 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4256 unsigned short fid
[3];
4257 char esa
[NAM$C_MAXRSS
];
4260 fab
.fab$l_fop
= FAB$M_OFP
;
4261 fab
.fab$l_fna
= file
;
4262 fab
.fab$b_fns
= strlen (file
);
4263 fab
.fab$l_nam
= &nam
;
4266 nam
.nam$l_esa
= esa
;
4267 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4269 status
= SYS$
PARSE (&fab
);
4270 if ((status
& 1) == 0)
4273 vaxc$errno
= status
;
4276 status
= SYS$
SEARCH (&fab
);
4277 if ((status
& 1) == 0)
4280 vaxc$errno
= status
;
4284 fid
[0] = nam
.nam$w_fid
[0];
4285 fid
[1] = nam
.nam$w_fid
[1];
4286 fid
[2] = nam
.nam$w_fid
[2];
4288 fab
.fab$l_fna
= new;
4289 fab
.fab$b_fns
= strlen (new);
4291 status
= SYS$
PARSE (&fab
);
4292 if ((status
& 1) == 0)
4295 vaxc$errno
= status
;
4299 nam
.nam$w_fid
[0] = fid
[0];
4300 nam
.nam$w_fid
[1] = fid
[1];
4301 nam
.nam$w_fid
[2] = fid
[2];
4303 nam
.nam$l_esa
= nam
.nam$l_name
;
4304 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4306 status
= SYS$
ENTER (&fab
);
4307 if ((status
& 1) == 0)
4310 vaxc$errno
= status
;
4320 printf ("%s not yet implemented\r\n", badfunc
);
4328 /* Arrange to return a range centered on zero. */
4329 return rand () - (1 << 30);
4340 /* Called from init_sys_modes. */
4345 /* If we're not on an HFT we shouldn't do any of this. We determine
4346 if we are on an HFT by trying to get an HFT error code. If this
4347 call fails, we're not on an HFT. */
4349 if (ioctl (0, HFQERROR
, &junk
) < 0)
4351 #else /* not IBMR2AIX */
4352 if (ioctl (0, HFQEIO
, 0) < 0)
4354 #endif /* not IBMR2AIX */
4356 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4357 as the rubout key's ASCII code. Here this is changed. The bug is that
4358 there's no way to determine the old mapping, so in reset_sys_modes
4359 we need to assume that the normal map had been present. Of course, this
4360 code also doesn't help if on a terminal emulator which doesn't understand
4364 struct hfkeymap keymap
;
4366 buf
.hf_bufp
= (char *)&keymap
;
4367 buf
.hf_buflen
= sizeof (keymap
);
4368 keymap
.hf_nkeys
= 2;
4369 keymap
.hfkey
[0].hf_kpos
= 15;
4370 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4372 keymap
.hfkey
[0].hf_keyidh
= '<';
4373 #else /* not IBMR2AIX */
4374 keymap
.hfkey
[0].hf_page
= '<';
4375 #endif /* not IBMR2AIX */
4376 keymap
.hfkey
[0].hf_char
= 127;
4377 keymap
.hfkey
[1].hf_kpos
= 15;
4378 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4380 keymap
.hfkey
[1].hf_keyidh
= '<';
4381 #else /* not IBMR2AIX */
4382 keymap
.hfkey
[1].hf_page
= '<';
4383 #endif /* not IBMR2AIX */
4384 keymap
.hfkey
[1].hf_char
= 127;
4385 hftctl (0, HFSKBD
, &buf
);
4387 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4389 line_ins_del_ok
= char_ins_del_ok
= 0;
4392 /* Reset the rubout key to backspace. */
4397 struct hfkeymap keymap
;
4401 if (ioctl (0, HFQERROR
, &junk
) < 0)
4403 #else /* not IBMR2AIX */
4404 if (ioctl (0, HFQEIO
, 0) < 0)
4406 #endif /* not IBMR2AIX */
4408 buf
.hf_bufp
= (char *)&keymap
;
4409 buf
.hf_buflen
= sizeof (keymap
);
4410 keymap
.hf_nkeys
= 2;
4411 keymap
.hfkey
[0].hf_kpos
= 15;
4412 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4414 keymap
.hfkey
[0].hf_keyidh
= '<';
4415 #else /* not IBMR2AIX */
4416 keymap
.hfkey
[0].hf_page
= '<';
4417 #endif /* not IBMR2AIX */
4418 keymap
.hfkey
[0].hf_char
= 8;
4419 keymap
.hfkey
[1].hf_kpos
= 15;
4420 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4422 keymap
.hfkey
[1].hf_keyidh
= '<';
4423 #else /* not IBMR2AIX */
4424 keymap
.hfkey
[1].hf_page
= '<';
4425 #endif /* not IBMR2AIX */
4426 keymap
.hfkey
[1].hf_char
= 8;
4427 hftctl (0, HFSKBD
, &buf
);