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
971 #endif /* F_SETOWN */
972 #endif /* F_SETOWN_BUG */
974 /* This may also be defined in stdio,
975 but if so, this does no harm,
976 and using the same name avoids wasting the other one's space. */
978 #if defined (USG) || defined (DGUX)
979 unsigned char _sobuf
[BUFSIZ
+8];
985 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
988 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
993 struct emacs_tty tty
;
997 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
998 extern int (*interrupt_signal
) ();
1007 input_ef
= get_kbd_event_flag ();
1008 /* LIB$GET_EF (&input_ef); */
1009 SYS$
CLREF (input_ef
);
1010 waiting_for_ast
= 0;
1012 timer_ef
= get_timer_event_flag ();
1013 /* LIB$GET_EF (&timer_ef); */
1014 SYS$
CLREF (timer_ef
);
1018 LIB$
GET_EF (&process_ef
);
1019 SYS$
CLREF (process_ef
);
1021 if (input_ef
/ 32 != process_ef
/ 32)
1022 croak ("Input and process event flags in different clusters.");
1024 if (input_ef
/ 32 != timer_ef
/ 32)
1025 croak ("Input and timer event flags in different clusters.");
1027 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1028 ((unsigned) 1 << (process_ef
% 32));
1030 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1031 ((unsigned) 1 << (timer_ef
% 32));
1033 sys_access_reinit ();
1035 #endif /* not VMS */
1038 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1039 narrow_foreground_group ();
1042 EMACS_GET_TTY (input_fd
, &old_tty
);
1044 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1048 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1049 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1050 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1052 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1054 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1055 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1057 tty
.main
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
1059 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1062 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1064 tty
.main
.c_iflag
&= ~IXANY
;
1068 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1069 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1071 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1075 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1076 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1079 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1080 /* Set up C-g for both SIGQUIT and SIGINT.
1081 We don't know which we will get, but we handle both alike
1082 so which one it really gives us does not matter. */
1083 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1084 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1085 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1087 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1090 #if defined (mips) || defined (HAVE_TCATTR)
1092 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1095 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1096 #endif /* V_DSUSP */
1097 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1098 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1101 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1104 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1105 #endif /* VREPRINT */
1107 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1108 #endif /* VWERASE */
1110 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1111 #endif /* VDISCARD */
1112 #endif /* mips or HAVE_TCATTR */
1115 /* AIX enhanced edit loses NULs, so disable it */
1116 tty
.main
.c_line
= 0;
1117 tty
.main
.c_iflag
&= ~ASCEDIT
;
1119 tty
.main
.c_cc
[VSTRT
] = 255;
1120 tty
.main
.c_cc
[VSTOP
] = 255;
1121 tty
.main
.c_cc
[VSUSP
] = 255;
1122 tty
.main
.c_cc
[VDSUSP
] = 255;
1123 #endif /* IBMR2AIX */
1124 /* Also, PTY overloads NUL and BREAK.
1125 don't ignore break, but don't signal either, so it looks like NUL.
1126 This really serves a purpose only if running in an XTERM window
1127 or via TELNET or the like, but does no harm elsewhere. */
1128 tty
.main
.c_iflag
&= ~IGNBRK
;
1129 tty
.main
.c_iflag
&= ~BRKINT
;
1131 #else /* if not HAVE_TERMIO */
1133 tty
.main
.tt_char
|= TT$M_NOECHO
;
1135 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1137 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1139 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1140 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1141 #else /* not VMS (BSD, that is) */
1142 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1144 tty
.main
.sg_flags
|= ANYP
;
1145 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1146 #endif /* not VMS (BSD, that is) */
1147 #endif /* not HAVE_TERMIO */
1149 /* If going to use CBREAK mode, we must request C-g to interrupt
1150 and turn off start and stop chars, etc. If not going to use
1151 CBREAK mode, do this anyway so as to turn off local flow
1152 control for user coming over network on 4.2; in this case,
1153 only t_stopc and t_startc really matter. */
1156 /* Note: if not using CBREAK mode, it makes no difference how we
1158 tty
.tchars
= new_tchars
;
1159 tty
.tchars
.t_intrc
= quit_char
;
1162 tty
.tchars
.t_startc
= '\021';
1163 tty
.tchars
.t_stopc
= '\023';
1166 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
1172 #define LNOFLSH 0100000
1175 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1177 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1178 anything, and leaving it in breaks the meta key. Go figure. */
1179 tty
.lmode
&= ~LLITOUT
;
1186 #endif /* HAVE_TCHARS */
1187 #endif /* not HAVE_TERMIO */
1190 tty
.ltchars
= new_ltchars
;
1191 #endif /* HAVE_LTCHARS */
1193 EMACS_SET_TTY (input_fd
, &tty
, 0);
1195 /* This code added to insure that, if flow-control is not to be used,
1196 we have an unlocked terminal at the start. */
1199 if (!flow_control
) ioctl (0, TCXONC
, 1);
1203 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
1211 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1212 to be only LF. This is the way that is done. */
1215 if (ioctl (1, HFTGETID
, &tty
) != -1)
1216 write (1, "\033[20l", 5);
1222 /* Appears to do nothing when in PASTHRU mode.
1223 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1224 interrupt_signal, oob_chars, 0, 0, 0, 0);
1226 queue_kbd_input (0);
1231 #ifndef F_SETOWN_BUG
1232 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1233 if (interrupt_input
)
1235 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
1236 fcntl (0, F_SETOWN
, getpid ());
1239 #endif /* F_GETOWN */
1240 #endif /* F_SETOWN_BUG */
1241 #endif /* F_SETFL */
1244 if (interrupt_input
)
1248 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1252 /* This symbol is defined on recent USG systems.
1253 Someone says without this call USG won't really buffer the file
1254 even with a call to setbuf. */
1255 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1257 setbuf (stdout
, _sobuf
);
1259 set_terminal_modes ();
1260 if (term_initted
&& no_redraw_on_reenter
)
1262 if (display_completed
)
1263 direct_output_forward_char (0);
1269 if (FRAMEP (Vterminal_frame
))
1270 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1277 /* Return nonzero if safe to use tabs in output.
1278 At the time this is called, init_sys_modes has not been done yet. */
1282 struct emacs_tty tty
;
1284 EMACS_GET_TTY (input_fd
, &tty
);
1285 return EMACS_TTY_TABS_OK (&tty
);
1288 /* Get terminal size from system.
1289 Store number of lines into *heightp and width into *widthp.
1290 If zero or a negative number is stored, the value is not valid. */
1292 get_frame_size (widthp
, heightp
)
1293 int *widthp
, *heightp
;
1299 struct winsize size
;
1301 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1302 *widthp
= *heightp
= 0;
1305 *widthp
= size
.ws_col
;
1306 *heightp
= size
.ws_row
;
1312 /* SunOS - style. */
1313 struct ttysize size
;
1315 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1316 *widthp
= *heightp
= 0;
1319 *widthp
= size
.ts_cols
;
1320 *heightp
= size
.ts_lines
;
1326 struct sensemode tty
;
1328 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1329 &tty
.class, 12, 0, 0, 0, 0);
1330 *widthp
= tty
.scr_wid
;
1331 *heightp
= tty
.scr_len
;
1333 #else /* system doesn't know size */
1338 #endif /* not VMS */
1339 #endif /* not SunOS-style */
1340 #endif /* not BSD-style */
1344 /* Prepare the terminal for exiting Emacs; move the cursor to the
1345 bottom of the frame, turn off interrupt-driven I/O, etc. */
1355 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1357 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1358 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1359 /* clear_end_of_line may move the cursor */
1360 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1363 /* HFT devices normally use ^J as a LF/CR. We forced it to
1364 do the LF only. Now, we need to reset it. */
1367 if (ioctl (1, HFTGETID
, &tty
) != -1)
1368 write (1, "\033[20h", 5);
1372 reset_terminal_modes ();
1376 /* Avoid possible loss of output when changing terminal modes. */
1377 fsync (fileno (stdout
));
1382 #ifndef F_SETOWN_BUG
1383 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1384 if (interrupt_input
)
1387 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1389 #endif /* F_SETOWN */
1390 #endif /* F_SETOWN_BUG */
1391 #endif /* F_SETFL */
1393 if (interrupt_input
)
1397 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1405 widen_foreground_group ();
1411 /* Set up the proper status flags for use of a pty. */
1416 /* I'm told that TOICREMOTE does not mean control chars
1417 "can't be sent" but rather that they don't have
1418 input-editing or signaling effects.
1419 That should be good, because we have other ways
1420 to do those things in Emacs.
1421 However, telnet mode seems not to work on 4.2.
1422 So TIOCREMOTE is turned off now. */
1424 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1425 will hang. In particular, the "timeout" feature (which
1426 causes a read to return if there is no data available)
1427 does this. Also it is known that telnet mode will hang
1428 in such a way that Emacs must be stopped (perhaps this
1429 is the same problem).
1431 If TIOCREMOTE is turned off, then there is a bug in
1432 hp-ux which sometimes loses data. Apparently the
1433 code which blocks the master process when the internal
1434 buffer fills up does not work. Other than this,
1435 though, everything else seems to work fine.
1437 Since the latter lossage is more benign, we may as well
1438 lose that way. -- cph */
1443 ioctl (fd
, FIONBIO
, &on
);
1448 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1449 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1450 /* cause EMACS not to die when it should, i.e., when its own controlling */
1451 /* tty goes away. I've complained to the AIX developers, and they may */
1452 /* change this behavior, but I'm not going to hold my breath. */
1453 signal (SIGHUP
, SIG_IGN
);
1456 #endif /* HAVE_PTYS */
1460 /* Assigning an input channel is done at the start of Emacs execution.
1461 This is called each time Emacs is resumed, also, but does nothing
1462 because input_chain is no longer zero. */
1470 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1476 /* Deassigning the input channel is done before exiting. */
1480 return SYS$
DASSGN (input_fd
);
1485 /* Request reading one character into the keyboard buffer.
1486 This is done as soon as the buffer becomes empty. */
1491 extern kbd_input_ast ();
1493 waiting_for_ast
= 0;
1495 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1496 &input_iosb
, kbd_input_ast
, 1,
1497 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1502 /* Ast routine that is called when keyboard input comes in
1503 in accord with the SYS$QIO above. */
1507 register int c
= -1;
1508 int old_errno
= errno
;
1509 extern EMACS_TIME
*input_available_clear_time
;
1511 if (waiting_for_ast
)
1512 SYS$
SETEF (input_ef
);
1513 waiting_for_ast
= 0;
1516 if (input_count
== 25)
1518 printf ("Ast # %d,", input_count
);
1519 printf (" iosb = %x, %x, %x, %x",
1520 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1523 if (input_iosb
.offset
)
1527 printf (", char = 0%o", c
);
1539 struct input_event e
;
1540 e
.kind
= ascii_keystroke
;
1541 XSET (e
.code
, Lisp_Int
, c
);
1543 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1545 e
.frame_or_window
= Qnil
;
1547 kbd_buffer_store_event (&e
);
1549 if (input_available_clear_time
)
1550 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1554 /* Wait until there is something in kbd_buffer. */
1556 wait_for_kbd_input ()
1558 extern int have_process_input
, process_exited
;
1560 /* If already something, avoid doing system calls. */
1561 if (detect_input_pending ())
1565 /* Clear a flag, and tell ast routine above to set it. */
1566 SYS$
CLREF (input_ef
);
1567 waiting_for_ast
= 1;
1568 /* Check for timing error: ast happened while we were doing that. */
1569 if (!detect_input_pending ())
1571 /* No timing error: wait for flag to be set. */
1572 set_waiting_for_input (0);
1573 SYS$
WFLOR (input_ef
, input_eflist
);
1574 clear_waiting_for_input (0);
1575 if (!detect_input_pending ())
1576 /* Check for subprocess input availability */
1578 int dsp
= have_process_input
|| process_exited
;
1580 SYS$
CLREF (process_ef
);
1581 if (have_process_input
)
1582 process_command_input ();
1587 update_mode_lines
++;
1588 redisplay_preserve_echo_area ();
1592 waiting_for_ast
= 0;
1595 /* Get rid of any pending QIO, when we are about to suspend
1596 or when we want to throw away pending input.
1597 We wait for a positive sign that the AST routine has run
1598 and therefore there is no I/O request queued when we return.
1599 SYS$SETAST is used to avoid a timing error. */
1604 printf ("At end_kbd_input.\n");
1608 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1610 SYS$
CANCEL (input_fd
);
1615 /* Clear a flag, and tell ast routine above to set it. */
1616 SYS$
CLREF (input_ef
);
1617 waiting_for_ast
= 1;
1619 SYS$
CANCEL (input_fd
);
1621 SYS$
WAITFR (input_ef
);
1622 waiting_for_ast
= 0;
1625 /* Wait for either input available or time interval expiry. */
1627 input_wait_timeout (timeval
)
1628 int timeval
; /* Time to wait, in seconds */
1631 static int zero
= 0;
1632 static int large
= -10000000;
1634 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1636 /* If already something, avoid doing system calls. */
1637 if (detect_input_pending ())
1641 /* Clear a flag, and tell ast routine above to set it. */
1642 SYS$
CLREF (input_ef
);
1643 waiting_for_ast
= 1;
1644 /* Check for timing error: ast happened while we were doing that. */
1645 if (!detect_input_pending ())
1647 /* No timing error: wait for flag to be set. */
1649 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1650 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1652 waiting_for_ast
= 0;
1655 /* The standard `sleep' routine works some other way
1656 and it stops working if you have ever quit out of it.
1657 This one continues to work. */
1663 static int zero
= 0;
1664 static int large
= -10000000;
1666 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1669 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1670 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1685 croak ("request sigio");
1690 croak ("unrequest sigio");
1695 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1700 #ifndef SYSTEM_MALLOC
1707 /* Some systems that cannot dump also cannot implement these. */
1710 * Return the address of the start of the text segment prior to
1711 * doing an unexec. After unexec the return value is undefined.
1712 * See crt0.c for further explanation and _start.
1716 #ifndef CANNOT_UNEXEC
1721 return ((char *) TEXT_START
);
1725 return ((char *) csrt
);
1726 #else /* not GOULD */
1727 extern int _start ();
1728 return ((char *) _start
);
1730 #endif /* TEXT_START */
1732 #endif /* not CANNOT_UNEXEC */
1735 * Return the address of the start of the data segment prior to
1736 * doing an unexec. After unexec the return value is undefined.
1737 * See crt0.c for further information and definition of data_start.
1739 * Apparently, on BSD systems this is etext at startup. On
1740 * USG systems (swapping) this is highly mmu dependent and
1741 * is also dependent on whether or not the program is running
1742 * with shared text. Generally there is a (possibly large)
1743 * gap between end of text and start of data with shared text.
1745 * On Uniplus+ systems with shared text, data starts at a
1746 * fixed address. Each port (from a given oem) is generally
1747 * different, and the specific value of the start of data can
1748 * be obtained via the UniPlus+ specific "uvar" system call,
1749 * however the method outlined in crt0.c seems to be more portable.
1751 * Probably what will have to happen when a USG unexec is available,
1752 * at least on UniPlus, is temacs will have to be made unshared so
1753 * that text and data are contiguous. Then once loadup is complete,
1754 * unexec will produce a shared executable where the data can be
1755 * at the normal shared text boundry and the startofdata variable
1756 * will be patched by unexec to the correct value.
1764 return ((char *) DATA_START
);
1766 #ifdef ORDINARY_LINK
1768 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1769 * data_start isn't defined. We take the address of environ, which
1770 * is known to live at or near the start of the system crt0.c, and
1771 * we don't sweat the handful of bytes that might lose.
1773 extern char **environ
;
1775 return((char *) &environ
);
1777 extern int data_start
;
1778 return ((char *) &data_start
);
1779 #endif /* ORDINARY_LINK */
1780 #endif /* DATA_START */
1782 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1785 /* Some systems that cannot dump also cannot implement these. */
1788 * Return the address of the end of the text segment prior to
1789 * doing an unexec. After unexec the return value is undefined.
1796 return ((char *) TEXT_END
);
1799 return ((char *) &etext
);
1804 * Return the address of the end of the data segment prior to
1805 * doing an unexec. After unexec the return value is undefined.
1812 return ((char *) DATA_END
);
1815 return ((char *) &edata
);
1819 #endif /* not CANNOT_DUMP */
1821 /* Get_system_name returns as its value
1822 a string for the Lisp function system-name to return. */
1828 /* Can't have this within the function since `static' is #defined to
1829 nothing for some USG systems. */
1831 #ifdef HAVE_GETHOSTNAME
1832 static char get_system_name_name
[256];
1833 #else /* not HAVE_GETHOSTNAME */
1834 static struct utsname get_system_name_name
;
1835 #endif /* not HAVE_GETHOSTNAME */
1842 #include <sys/socket.h>
1844 #endif /* HAVE_SOCKETS */
1845 #endif /* not VMS */
1846 #endif /* not USG */
1847 #endif /* not BSD4_1 */
1853 #ifdef HAVE_GETHOSTNAME
1854 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1855 return get_system_name_name
;
1856 #else /* not HAVE_GETHOSTNAME */
1857 uname (&get_system_name_name
);
1858 return (get_system_name_name
.nodename
);
1859 #endif /* not HAVE_GETHOSTNAME */
1863 #else /* not USG, not 4.1 */
1864 static char system_name_saved
[32];
1867 if ((sp
= egetenv ("SYS$NODE")) == 0)
1873 if ((end
= index (sp
, ':')) != 0)
1876 strcpy (system_name_saved
, sp
);
1878 gethostname (system_name_saved
, sizeof (system_name_saved
));
1880 /* Turn the hostname into the official, fully-qualified hostname.
1881 Don't do this if we're going to dump; this can confuse system
1882 libraries on some machines and make the dumped emacs core dump. */
1885 #endif /* not CANNOT_DUMP */
1888 hp
= gethostbyname (system_name_saved
);
1889 if (hp
&& strlen (hp
->h_name
) < sizeof(system_name_saved
))
1890 strcpy (system_name_saved
, hp
->h_name
);
1892 #endif /* HAVE_SOCKETS */
1893 #endif /* not VMS */
1894 return system_name_saved
;
1895 #endif /* not USG, not 4.1 */
1896 #endif /* not USG */
1900 #ifndef HAVE_GETHOSTNAME
1901 void gethostname(buf
, len
)
1906 s
= getenv ("SYS$NODE");
1910 strncpy (buf
, s
, len
- 2);
1911 buf
[len
- 1] = '\0';
1913 } /* static void gethostname */
1914 #endif /* ! HAVE_GETHOSTNAME */
1921 #ifdef HAVE_X_WINDOWS
1922 /* Cause explanatory error message at compile time,
1923 since the select emulation is not good enough for X. */
1924 int *x
= &x_windows_lose_if_no_select_system_call
;
1927 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1928 * Only checks read descriptors.
1930 /* How long to wait between checking fds in select */
1931 #define SELECT_PAUSE 1
1934 /* For longjmp'ing back to read_input_waiting. */
1936 jmp_buf read_alarm_throw
;
1938 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1939 The read_socket_hook function sets this to 1 while it is waiting. */
1941 int read_alarm_should_throw
;
1949 #else /* not BSD4_1 */
1950 signal (SIGALRM
, SIG_IGN
);
1951 #endif /* not BSD4_1 */
1952 if (read_alarm_should_throw
)
1953 longjmp (read_alarm_throw
, 1);
1956 /* Only rfds are checked. */
1958 select (nfds
, rfds
, wfds
, efds
, timeout
)
1960 int *rfds
, *wfds
, *efds
, *timeout
;
1962 int ravail
= 0, orfds
= 0, old_alarm
;
1963 int timeoutval
= timeout
? *timeout
: 100000;
1964 int *local_timeout
= &timeoutval
;
1965 extern int proc_buffered_char
[];
1966 #ifndef subprocesses
1967 int process_tick
= 0, update_tick
= 0;
1969 extern int process_tick
, update_tick
;
1971 SIGTYPE (*old_trap
) ();
1984 /* If we are looking only for the terminal, with no timeout,
1985 just read it and wait -- that's more efficient. */
1986 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1988 if (! detect_input_pending ())
1989 read_input_waiting ();
1994 /* Once a second, till the timer expires, check all the flagged read
1995 * descriptors to see if any input is available. If there is some then
1996 * set the corresponding bit in the return copy of rfds.
2000 register int to_check
, bit
, fd
;
2004 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
2008 int avail
= 0, status
= 0;
2011 avail
= detect_input_pending (); /* Special keyboard handler */
2015 status
= ioctl (fd
, FIONREAD
, &avail
);
2016 #else /* no FIONREAD */
2017 /* Hoping it will return -1 if nothing available
2018 or 0 if all 0 chars requested are read. */
2019 if (proc_buffered_char
[fd
] >= 0)
2023 avail
= read (fd
, &buf
, 1);
2025 proc_buffered_char
[fd
] = buf
;
2027 #endif /* no FIONREAD */
2029 if (status
>= 0 && avail
> 0)
2037 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2039 old_alarm
= alarm (0);
2040 old_trap
= signal (SIGALRM
, select_alarm
);
2042 alarm (SELECT_PAUSE
);
2043 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2044 while (select_alarmed
== 0 && *local_timeout
!= 0
2045 && process_tick
== update_tick
)
2047 /* If we are interested in terminal input,
2048 wait by reading the terminal.
2049 That makes instant wakeup for terminal input at least. */
2052 read_input_waiting ();
2053 if (detect_input_pending ())
2059 (*local_timeout
) -= SELECT_PAUSE
;
2060 /* Reset the old alarm if there was one */
2062 signal (SIGALRM
, old_trap
);
2065 /* Reset or forge an interrupt for the original handler. */
2066 old_alarm
-= SELECT_PAUSE
;
2068 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
2072 if (*local_timeout
== 0) /* Stop on timer being cleared */
2078 /* Read keyboard input into the standard buffer,
2079 waiting for at least one character. */
2081 /* Make all keyboard buffers much bigger when using X windows. */
2082 #ifdef HAVE_X_WINDOWS
2083 #define BUFFER_SIZE_FACTOR 16
2085 #define BUFFER_SIZE_FACTOR 1
2088 read_input_waiting ()
2090 char buf
[256 * BUFFER_SIZE_FACTOR
];
2091 struct input_event e
;
2093 extern int quit_char
;
2095 if (read_socket_hook
)
2097 read_alarm_should_throw
= 0;
2098 if (! setjmp (read_alarm_throw
))
2099 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
2104 nread
= read (fileno (stdin
), buf
, 1);
2106 /* Scan the chars for C-g and store them in kbd_buffer. */
2107 e
.kind
= ascii_keystroke
;
2108 e
.frame_or_window
= selected_frame
;
2110 for (i
= 0; i
< nread
; i
++)
2112 XSET (e
.code
, Lisp_Int
, buf
[i
]);
2113 kbd_buffer_store_event (&e
);
2114 /* Don't look at input that follows a C-g too closely.
2115 This reduces lossage due to autorepeat on C-g. */
2116 if (buf
[i
] == quit_char
)
2121 #endif /* not HAVE_SELECT */
2122 #endif /* not VMS */
2126 * Partially emulate 4.2 open call.
2127 * open is defined as this in 4.1.
2129 * - added by Michael Bloom @ Citicorp/TTI
2134 sys_open (path
, oflag
, mode
)
2138 if (oflag
& O_CREAT
)
2139 return creat (path
, mode
);
2141 return open (path
, oflag
);
2148 lmode
= LINTRUP
| lmode
;
2149 ioctl (0, TIOCLSET
, &lmode
);
2156 lmode
= ~LINTRUP
& lmode
;
2157 ioctl (0, TIOCLSET
, &lmode
);
2164 interrupts_deferred
= 0;
2171 interrupts_deferred
= 1;
2174 /* still inside #ifdef BSD4_1 */
2177 int sigheld
; /* Mask of held signals */
2182 sigheld
|= sigbit (signum
);
2189 sigheld
|= sigbit (signum
);
2195 sigheld
&= ~sigbit (signum
);
2199 sigfree () /* Free all held signals */
2202 for (i
= 0; i
< NSIG
; i
++)
2203 if (sigheld
& sigbit (i
))
2210 return 1 << (i
- 1);
2212 #endif /* subprocesses */
2215 /* POSIX signals support - DJB */
2216 /* Anyone with POSIX signals should have ANSI C declarations */
2218 #ifdef POSIX_SIGNALS
2220 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
2221 static struct sigaction new_action
, old_action
;
2225 sigemptyset (&empty_mask
);
2226 sigfillset (&full_mask
);
2230 sys_signal (int signal_number
, signal_handler_t action
)
2233 /* This gets us restartable system calls for efficiency.
2234 The "else" code will works as well. */
2235 return (berk_signal (signal_number
, action
));
2237 sigemptyset (&new_action
.sa_mask
);
2238 new_action
.sa_handler
= action
;
2239 new_action
.sa_flags
= 0;
2240 sigaction (signal_number
, &new_action
, &old_action
);
2241 return (old_action
.sa_handler
);
2246 /* If we're compiling with GCC, we don't need this function, since it
2247 can be written as a macro. */
2249 sys_sigmask (int sig
)
2252 sigemptyset (&mask
);
2253 sigaddset (&mask
, sig
);
2259 sys_sigpause (sigset_t new_mask
)
2261 /* pause emulating berk sigpause... */
2262 sigsuspend (&new_mask
);
2266 /* I'd like to have these guys return pointers to the mask storage in here,
2267 but there'd be trouble if the code was saving multiple masks. I'll be
2268 safe and pass the structure. It normally won't be more than 2 bytes
2272 sys_sigblock (sigset_t new_mask
)
2275 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2280 sys_sigunblock (sigset_t new_mask
)
2283 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2288 sys_sigsetmask (sigset_t new_mask
)
2291 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2295 #endif /* POSIX_SIGNALS */
2302 register int length
;
2306 long max_str
= 65535;
2308 while (length
> max_str
) {
2309 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2314 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2316 while (length
-- > 0)
2318 #endif /* not VMS */
2321 /* Saying `void' requires a declaration, above, where bcopy is used
2322 and that declaration causes pain for systems where bcopy is a macro. */
2323 bcopy (b1
, b2
, length
)
2326 register int length
;
2329 long max_str
= 65535;
2331 while (length
> max_str
) {
2332 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2338 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2340 while (length
-- > 0)
2342 #endif /* not VMS */
2346 bcmp (b1
, b2
, length
) /* This could be a macro! */
2349 register int length
;
2352 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2353 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2355 return STR$
COMPARE (&src1
, &src2
);
2357 while (length
-- > 0)
2362 #endif /* not VMS */
2364 #endif /* not BSTRING */
2369 * The BSD random returns numbers in the range of
2370 * 0 to 2e31 - 1. The USG rand returns numbers in the
2371 * range of 0 to 2e15 - 1. This is probably not significant
2378 /* Arrange to return a range centered on zero. */
2379 return (rand () << 15) + rand () - (1 << 29);
2393 /* Arrange to return a range centered on zero. */
2394 return (rand () << 15) + rand () - (1 << 29);
2405 #ifdef WRONG_NAME_INSQUE
2418 /* If any place else asks for the TERM variable,
2419 allow it to be overridden with the EMACS_TERM variable
2420 before attempting to translate the logical name TERM. As a last
2421 resort, ask for VAX C's special idea of the TERM variable. */
2428 static char buf
[256];
2429 static struct dsc$descriptor_s equiv
2430 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2431 static struct dsc$descriptor_s d_name
2432 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2435 if (!strcmp (name
, "TERM"))
2437 val
= (char *) getenv ("EMACS_TERM");
2442 d_name
.dsc$w_length
= strlen (name
);
2443 d_name
.dsc$a_pointer
= name
;
2444 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2446 char *str
= (char *) xmalloc (eqlen
+ 1);
2447 bcopy (buf
, str
, eqlen
);
2449 /* This is a storage leak, but a pain to fix. With luck,
2450 no one will ever notice. */
2453 return (char *) getenv (name
);
2458 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2459 to force a call on the debugger from within the image. */
2464 LIB$
SIGNAL (SS$_DEBUG
);
2470 #ifdef LINK_CRTL_SHARE
2471 #ifdef SHAREABLE_LIB_BUG
2472 /* Variables declared noshare and initialized in sharable libraries
2473 cannot be shared. The VMS linker incorrectly forces you to use a private
2474 version which is uninitialized... If not for this "feature", we
2475 could use the C library definition of sys_nerr and sys_errlist. */
2477 char *sys_errlist
[] =
2481 "no such file or directory",
2483 "interrupted system call",
2485 "no such device or address",
2486 "argument list too long",
2487 "exec format error",
2490 "no more processes",
2491 "not enough memory",
2492 "permission denied",
2494 "block device required",
2495 "mount devices busy",
2497 "cross-device link",
2502 "file table overflow",
2503 "too many open files",
2507 "no space left on device",
2509 "read-only file system",
2515 "vax/vms specific error code nontranslatable error"
2517 #endif /* SHAREABLE_LIB_BUG */
2518 #endif /* LINK_CRTL_SHARE */
2521 #ifdef INTERRUPTIBLE_OPEN
2525 sys_open (path
, oflag
, mode
)
2529 register int rtnval
;
2531 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2532 && (errno
== EINTR
));
2536 #endif /* INTERRUPTIBLE_OPEN */
2538 #ifdef INTERRUPTIBLE_CLOSE
2543 register int rtnval
;
2545 while ((rtnval
= close (fd
)) == -1
2546 && (errno
== EINTR
));
2550 #endif /* INTERRUPTIBLE_CLOSE */
2552 #ifdef INTERRUPTIBLE_IO
2555 sys_read (fildes
, buf
, nbyte
)
2560 register int rtnval
;
2562 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2563 && (errno
== EINTR
));
2568 sys_write (fildes
, buf
, nbyte
)
2573 register int rtnval
;
2575 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2576 && (errno
== EINTR
));
2580 #endif /* INTERRUPTIBLE_IO */
2585 * Substitute fork for vfork on USG flavors.
2593 #endif /* not HAVE_VFORK */
2597 * All of the following are for USG.
2599 * On USG systems the system calls are INTERRUPTIBLE by signals
2600 * that the user program has elected to catch. Thus the system call
2601 * must be retried in these cases. To handle this without massive
2602 * changes in the source code, we remap the standard system call names
2603 * to names for our own functions in sysdep.c that do the system call
2604 * with retries. Actually, for portability reasons, it is good
2605 * programming practice, as this example shows, to limit all actual
2606 * system calls to a single occurrence in the source. Sure, this
2607 * adds an extra level of function call overhead but it is almost
2608 * always negligible. Fred Fish, Unisoft Systems Inc.
2611 #ifndef HAVE_SYS_SIGLIST
2612 char *sys_siglist
[NSIG
+ 1] =
2615 /* AIX has changed the signals a bit */
2616 "bogus signal", /* 0 */
2617 "hangup", /* 1 SIGHUP */
2618 "interrupt", /* 2 SIGINT */
2619 "quit", /* 3 SIGQUIT */
2620 "illegal instruction", /* 4 SIGILL */
2621 "trace trap", /* 5 SIGTRAP */
2622 "IOT instruction", /* 6 SIGIOT */
2623 "crash likely", /* 7 SIGDANGER */
2624 "floating point exception", /* 8 SIGFPE */
2625 "kill", /* 9 SIGKILL */
2626 "bus error", /* 10 SIGBUS */
2627 "segmentation violation", /* 11 SIGSEGV */
2628 "bad argument to system call", /* 12 SIGSYS */
2629 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2630 "alarm clock", /* 14 SIGALRM */
2631 "software termination signum", /* 15 SIGTERM */
2632 "user defined signal 1", /* 16 SIGUSR1 */
2633 "user defined signal 2", /* 17 SIGUSR2 */
2634 "death of a child", /* 18 SIGCLD */
2635 "power-fail restart", /* 19 SIGPWR */
2636 "bogus signal", /* 20 */
2637 "bogus signal", /* 21 */
2638 "bogus signal", /* 22 */
2639 "bogus signal", /* 23 */
2640 "bogus signal", /* 24 */
2641 "LAN I/O interrupt", /* 25 SIGAIO */
2642 "PTY I/O interrupt", /* 26 SIGPTY */
2643 "I/O intervention required", /* 27 SIGIOINT */
2644 "HFT grant", /* 28 SIGGRANT */
2645 "HFT retract", /* 29 SIGRETRACT */
2646 "HFT sound done", /* 30 SIGSOUND */
2647 "HFT input ready", /* 31 SIGMSG */
2649 "bogus signal", /* 0 */
2650 "hangup", /* 1 SIGHUP */
2651 "interrupt", /* 2 SIGINT */
2652 "quit", /* 3 SIGQUIT */
2653 "illegal instruction", /* 4 SIGILL */
2654 "trace trap", /* 5 SIGTRAP */
2655 "IOT instruction", /* 6 SIGIOT */
2656 "EMT instruction", /* 7 SIGEMT */
2657 "floating point exception", /* 8 SIGFPE */
2658 "kill", /* 9 SIGKILL */
2659 "bus error", /* 10 SIGBUS */
2660 "segmentation violation", /* 11 SIGSEGV */
2661 "bad argument to system call", /* 12 SIGSYS */
2662 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2663 "alarm clock", /* 14 SIGALRM */
2664 "software termination signum", /* 15 SIGTERM */
2665 "user defined signal 1", /* 16 SIGUSR1 */
2666 "user defined signal 2", /* 17 SIGUSR2 */
2667 "death of a child", /* 18 SIGCLD */
2668 "power-fail restart", /* 19 SIGPWR */
2669 #endif /* not AIX */
2672 #endif /* HAVE_SYS_SIGLIST */
2675 * Warning, this function may not duplicate 4.2 action properly
2676 * under error conditions.
2680 /* In 4.1, param.h fails to define this. */
2681 #define MAXPATHLEN 1024
2690 char *npath
, *spath
;
2691 extern char *getcwd ();
2693 BLOCK_INPUT
; /* getcwd uses malloc */
2694 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2695 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2696 up to first slash. Should be harmless on other systems. */
2697 while (*npath
&& *npath
!= '/')
2699 strcpy (pathname
, npath
);
2700 free (spath
); /* getcwd uses malloc */
2705 #endif /* HAVE_GETWD */
2708 * Emulate rename using unlink/link. Note that this is
2709 * only partially correct. Also, doesn't enforce restriction
2710 * that files be of same type (regular->regular, dir->dir, etc).
2719 if (access (from
, 0) == 0)
2722 if (link (from
, to
) == 0)
2723 if (unlink (from
) == 0)
2731 #ifdef MISSING_UTIMES
2733 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2742 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2743 utimbuf structure defined anywhere but in the man page. */
2753 struct timeval tvp
[];
2756 utb
.actime
= tvp
[0].tv_sec
;
2757 utb
.modtime
= tvp
[1].tv_sec
;
2760 #endif /* IRIS_UTIME */
2766 /* HPUX curses library references perror, but as far as we know
2767 it won't be called. Anyway this definition will do for now. */
2773 #endif /* not HAVE_PERROR */
2779 * Emulate BSD dup2. First close newd if it already exists.
2780 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2781 * until we are, then close the unsuccessful ones.
2788 register int fd
, ret
;
2793 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2795 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2802 ret
= dup2 (old
,new);
2808 #endif /* not HAVE_DUP2 */
2811 * Gettimeofday. Simulate as much as possible. Only accurate
2812 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2813 * Only needed when subprocesses are defined.
2818 #ifndef HAVE_GETTIMEOFDAY
2822 gettimeofday (tp
, tzp
)
2824 struct timezone
*tzp
;
2826 extern long time ();
2828 tp
->tv_sec
= time ((long *)0);
2831 tzp
->tz_minuteswest
= -1;
2837 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2840 * This function will go away as soon as all the stubs fixed. (fnf)
2846 printf ("%s not yet implemented\r\n", badfunc
);
2855 char *sys_siglist
[NSIG
+ 1] =
2857 "null signal", /* 0 SIGNULL */
2858 "hangup", /* 1 SIGHUP */
2859 "interrupt", /* 2 SIGINT */
2860 "quit", /* 3 SIGQUIT */
2861 "illegal instruction", /* 4 SIGILL */
2862 "trace trap", /* 5 SIGTRAP */
2863 "abort termination", /* 6 SIGABRT */
2864 "SIGEMT", /* 7 SIGEMT */
2865 "floating point exception", /* 8 SIGFPE */
2866 "kill", /* 9 SIGKILL */
2867 "bus error", /* 10 SIGBUS */
2868 "segmentation violation", /* 11 SIGSEGV */
2869 "bad argument to system call", /* 12 SIGSYS */
2870 "write on a pipe with no reader", /* 13 SIGPIPE */
2871 "alarm clock", /* 14 SIGALRM */
2872 "software termination signal", /* 15 SIGTERM */
2873 "user defined signal 1", /* 16 SIGUSR1 */
2874 "user defined signal 2", /* 17 SIGUSR2 */
2875 "child stopped or terminated", /* 18 SIGCLD */
2876 "power-fail restart", /* 19 SIGPWR */
2877 "window size changed", /* 20 SIGWINCH */
2878 "undefined", /* 21 */
2879 "pollable event occurred", /* 22 SIGPOLL */
2880 "sendable stop signal not from tty", /* 23 SIGSTOP */
2881 "stop signal from tty", /* 24 SIGSTP */
2882 "continue a stopped process", /* 25 SIGCONT */
2883 "attempted background tty read", /* 26 SIGTTIN */
2884 "attempted background tty write", /* 27 SIGTTOU */
2885 "undefined", /* 28 */
2886 "undefined", /* 29 */
2887 "undefined", /* 30 */
2888 "undefined", /* 31 */
2889 "undefined", /* 32 */
2890 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2891 "I/O is possible", /* 34 SIGIO */
2892 "exceeded cpu time limit", /* 35 SIGXCPU */
2893 "exceeded file size limit", /* 36 SIGXFSZ */
2894 "virtual time alarm", /* 37 SIGVTALRM */
2895 "profiling time alarm", /* 38 SIGPROF */
2896 "undefined", /* 39 */
2897 "file record locks revoked", /* 40 SIGLOST */
2898 "undefined", /* 41 */
2899 "undefined", /* 42 */
2900 "undefined", /* 43 */
2901 "undefined", /* 44 */
2902 "undefined", /* 45 */
2903 "undefined", /* 46 */
2904 "undefined", /* 47 */
2905 "undefined", /* 48 */
2906 "undefined", /* 49 */
2907 "undefined", /* 50 */
2908 "undefined", /* 51 */
2909 "undefined", /* 52 */
2910 "undefined", /* 53 */
2911 "undefined", /* 54 */
2912 "undefined", /* 55 */
2913 "undefined", /* 56 */
2914 "undefined", /* 57 */
2915 "undefined", /* 58 */
2916 "undefined", /* 59 */
2917 "undefined", /* 60 */
2918 "undefined", /* 61 */
2919 "undefined", /* 62 */
2920 "undefined", /* 63 */
2921 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2927 /* Directory routines for systems that don't have them. */
2929 #ifdef SYSV_SYSTEM_DIR
2933 #ifndef HAVE_CLOSEDIR
2936 register DIR *dirp
; /* stream from opendir */
2938 sys_close (dirp
->dd_fd
);
2940 /* Some systems (like Solaris) allocate the buffer and the DIR all
2941 in one block. Why in the world are we freeing this ourselves
2943 #if ! (defined (sun) && defined (USG5_4))
2944 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2946 xfree ((char *) dirp
);
2948 #endif /* not HAVE_CLOSEDIR */
2949 #endif /* SYSV_SYSTEM_DIR */
2951 #ifdef NONSYSTEM_DIR_LIBRARY
2955 char *filename
; /* name of directory */
2957 register DIR *dirp
; /* -> malloc'ed storage */
2958 register int fd
; /* file descriptor for read */
2959 struct stat sbuf
; /* result of fstat */
2961 fd
= sys_open (filename
, 0);
2966 if (fstat (fd
, &sbuf
) < 0
2967 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2968 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2972 return 0; /* bad luck today */
2977 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2984 register DIR *dirp
; /* stream from opendir */
2986 sys_close (dirp
->dd_fd
);
2987 xfree ((char *) dirp
);
2995 ino_t od_ino
; /* inode */
2996 char od_name
[DIRSIZ
]; /* filename */
2998 #endif /* not VMS */
3000 struct direct dir_static
; /* simulated directory contents */
3005 register DIR *dirp
; /* stream from opendir */
3008 register struct olddir
*dp
; /* -> directory data */
3010 register struct dir$_name
*dp
; /* -> directory data */
3011 register struct dir$_version
*dv
; /* -> version data */
3016 if (dirp
->dd_loc
>= dirp
->dd_size
)
3017 dirp
->dd_loc
= dirp
->dd_size
= 0;
3019 if (dirp
->dd_size
== 0 /* refill buffer */
3020 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3024 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3025 dirp
->dd_loc
+= sizeof (struct olddir
);
3027 if (dp
->od_ino
!= 0) /* not deleted entry */
3029 dir_static
.d_ino
= dp
->od_ino
;
3030 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3031 dir_static
.d_name
[DIRSIZ
] = '\0';
3032 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3033 dir_static
.d_reclen
= sizeof (struct direct
)
3035 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3036 return &dir_static
; /* -> simulated structure */
3039 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3040 if (dirp
->dd_loc
== 0)
3041 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3042 : dp
->dir$b_namecount
;
3043 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3044 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3045 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3046 dir_static
.d_reclen
= sizeof (struct direct
)
3048 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3049 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3050 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3051 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3058 /* readdirver is just like readdir except it returns all versions of a file
3059 as separate entries. */
3064 register DIR *dirp
; /* stream from opendir */
3066 register struct dir$_name
*dp
; /* -> directory data */
3067 register struct dir$_version
*dv
; /* -> version data */
3069 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3070 dirp
->dd_loc
= dirp
->dd_size
= 0;
3072 if (dirp
->dd_size
== 0 /* refill buffer */
3073 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3076 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3077 if (dirp
->dd_loc
== 0)
3078 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3079 : dp
->dir$b_namecount
;
3080 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3081 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3082 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3083 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3084 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3085 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3086 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3087 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3093 #endif /* NONSYSTEM_DIR_LIBRARY */
3096 /* mkdir and rmdir functions, for systems which don't have them. */
3100 * Written by Robert Rother, Mariah Corporation, August 1985.
3102 * If you want it, it's yours. All I ask in return is that if you
3103 * figure out how to do this in a Bourne Shell script you send me
3105 * sdcsvax!rmr or rmr@uscd
3107 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3108 * subroutine. 11Mar86; hoptoad!gnu
3110 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3111 * subroutine didn't return EEXIST. It does now.
3118 mkdir (dpath
, dmode
)
3123 struct stat statbuf
;
3125 if (stat (dpath
, &statbuf
) == 0)
3127 errno
= EEXIST
; /* Stat worked, so it already exists */
3131 /* If stat fails for a reason other than non-existence, return error */
3132 if (errno
!= ENOENT
)
3135 switch (cpid
= fork ())
3138 case -1: /* Error in fork() */
3139 return (-1); /* Errno is set already */
3141 case 0: /* Child process */
3143 * Cheap hack to set mode of new directory. Since this
3144 * child process is going away anyway, we zap its umask.
3145 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3146 * directory. Does anybody care?
3148 status
= umask (0); /* Get current umask */
3149 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3150 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3151 _exit (-1); /* Can't exec /bin/mkdir */
3153 default: /* Parent process */
3154 while (cpid
!= wait (&status
)); /* Wait for kid to finish */
3157 if (WIFSIGNALED (status
) || WEXITSTATUS (status
) != 0)
3159 errno
= EIO
; /* We don't know why, but */
3160 return -1; /* /bin/mkdir failed */
3165 #endif /* not HAVE_MKDIR */
3173 struct stat statbuf
;
3175 if (stat (dpath
, &statbuf
) != 0)
3177 /* Stat just set errno. We don't have to */
3181 switch (cpid
= fork ())
3184 case -1: /* Error in fork() */
3185 return (-1); /* Errno is set already */
3187 case 0: /* Child process */
3188 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
3189 _exit (-1); /* Can't exec /bin/mkdir */
3191 default: /* Parent process */
3192 while (cpid
!= wait (&status
)); /* Wait for kid to finish */
3195 if (WIFSIGNALED (status
) || WEXITSTATUS (status
) != 0)
3197 errno
= EIO
; /* We don't know why, but */
3198 return -1; /* /bin/mkdir failed */
3203 #endif /* !HAVE_RMDIR */
3207 /* Functions for VMS */
3209 #include "vms-pwd.h"
3214 /* Return as a string the VMS error string pertaining to STATUS.
3215 Reuses the same static buffer each time it is called. */
3219 int status
; /* VMS status code */
3223 static char buf
[257];
3225 bufadr
[0] = sizeof buf
- 1;
3226 bufadr
[1] = (int) buf
;
3227 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3228 return "untranslatable VMS error status";
3236 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3237 * not work correctly. (It also doesn't work well in version 2.3.)
3242 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3243 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3247 unsigned short s_buflen
;
3248 unsigned short s_code
;
3250 unsigned short *s_retlenadr
;
3254 #define buflen s.s_buflen
3255 #define code s.s_code
3256 #define bufadr s.s_bufadr
3257 #define retlenadr s.s_retlenadr
3259 #define R_OK 4 /* test for read permission */
3260 #define W_OK 2 /* test for write permission */
3261 #define X_OK 1 /* test for execute (search) permission */
3262 #define F_OK 0 /* test for presence of file */
3265 sys_access (path
, mode
)
3269 static char *user
= NULL
;
3272 /* translate possible directory spec into .DIR file name, so brain-dead
3273 * access can treat the directory like a file. */
3274 if (directory_file_name (path
, dir_fn
))
3278 return access (path
, mode
);
3279 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3285 unsigned short int dummy
;
3287 static int constant
= ACL$C_FILE
;
3288 DESCRIPTOR (path_desc
, path
);
3289 DESCRIPTOR (user_desc
, user
);
3293 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3296 acces
|= CHP$M_READ
;
3298 acces
|= CHP$M_WRITE
;
3299 itemlst
[0].buflen
= sizeof (int);
3300 itemlst
[0].code
= CHP$_FLAGS
;
3301 itemlst
[0].bufadr
= (char *) &flags
;
3302 itemlst
[0].retlenadr
= &dummy
;
3303 itemlst
[1].buflen
= sizeof (int);
3304 itemlst
[1].code
= CHP$_ACCESS
;
3305 itemlst
[1].bufadr
= (char *) &acces
;
3306 itemlst
[1].retlenadr
= &dummy
;
3307 itemlst
[2].end
= CHP$_END
;
3308 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3309 return stat
== SS$_NORMAL
? 0 : -1;
3313 #else /* not VMS4_4 */
3316 #define ACE$M_WRITE 2
3317 #define ACE$C_KEYID 1
3319 static unsigned short memid
, grpid
;
3320 static unsigned int uic
;
3322 /* Called from init_sys_modes, so it happens not very often
3323 but at least each time Emacs is loaded. */
3324 sys_access_reinit ()
3330 sys_access (filename
, type
)
3336 int status
, size
, i
, typecode
, acl_controlled
;
3337 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3338 union prvdef prvmask
;
3340 /* Get UIC and GRP values for protection checking. */
3343 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3346 memid
= uic
& 0xFFFF;
3350 if (type
!= 2) /* not checking write access */
3351 return access (filename
, type
);
3353 /* Check write protection. */
3355 #define CHECKPRIV(bit) (prvmask.bit)
3356 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3358 /* Find privilege bits */
3359 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3361 error ("Unable to find privileges: %s", vmserrstr (status
));
3362 if (CHECKPRIV (PRV$V_BYPASS
))
3363 return 0; /* BYPASS enabled */
3365 fab
.fab$b_fac
= FAB$M_GET
;
3366 fab
.fab$l_fna
= filename
;
3367 fab
.fab$b_fns
= strlen (filename
);
3368 fab
.fab$l_xab
= &xab
;
3369 xab
= cc$rms_xabpro
;
3370 xab
.xab$l_aclbuf
= aclbuf
;
3371 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3372 status
= SYS$
OPEN (&fab
, 0, 0);
3375 SYS$
CLOSE (&fab
, 0, 0);
3376 /* Check system access */
3377 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
3379 /* Check ACL entries, if any */
3381 if (xab
.xab$w_acllen
> 0)
3384 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3385 while (*aclptr
&& aclptr
< aclend
)
3387 size
= (*aclptr
& 0xff) / 4;
3388 typecode
= (*aclptr
>> 8) & 0xff;
3389 if (typecode
== ACE$C_KEYID
)
3390 for (i
= size
- 1; i
> 1; i
--)
3391 if (aclptr
[i
] == uic
)
3394 if (aclptr
[1] & ACE$M_WRITE
)
3395 return 0; /* Write access through ACL */
3397 aclptr
= &aclptr
[size
];
3399 if (acl_controlled
) /* ACL specified, prohibits write access */
3402 /* No ACL entries specified, check normal protection */
3403 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3405 if (WRITEABLE (XAB$V_GRP
) &&
3406 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3407 return 0; /* Group writeable */
3408 if (WRITEABLE (XAB$V_OWN
) &&
3409 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3410 return 0; /* Owner writeable */
3412 return -1; /* Not writeable */
3414 #endif /* not VMS4_4 */
3417 static char vtbuf
[NAM$C_MAXRSS
+1];
3419 /* translate a vms file spec to a unix path */
3421 sys_translate_vms (vfile
)
3432 /* leading device or logical name is a root directory */
3433 if (p
= strchr (vfile
, ':'))
3442 if (*p
== '[' || *p
== '<')
3444 while (*++vfile
!= *p
+ 2)
3448 if (vfile
[-1] == *p
)
3471 static char utbuf
[NAM$C_MAXRSS
+1];
3473 /* translate a unix path to a VMS file spec */
3475 sys_translate_unix (ufile
)
3498 if (index (&ufile
[1], '/'))
3505 if (index (&ufile
[1], '/'))
3512 if (strncmp (ufile
, "./", 2) == 0)
3519 ufile
++; /* skip the dot */
3520 if (index (&ufile
[1], '/'))
3525 else if (strncmp (ufile
, "../", 3) == 0)
3533 ufile
+= 2; /* skip the dots */
3534 if (index (&ufile
[1], '/'))
3559 extern char *getcwd ();
3561 #define MAXPATHLEN 1024
3563 ptr
= xmalloc (MAXPATHLEN
);
3564 getcwd (ptr
, MAXPATHLEN
);
3565 strcpy (pathname
, ptr
);
3573 long item_code
= JPI$_OWNER
;
3574 unsigned long parent_id
;
3577 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3580 vaxc$errno
= status
;
3590 return (getgid () << 16) | getuid ();
3594 sys_read (fildes
, buf
, nbyte
)
3599 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3604 sys_write (fildes
, buf
, nbyte
)
3609 register int nwrote
, rtnval
= 0;
3611 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3617 return rtnval
? rtnval
: -1;
3618 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3619 return rtnval
? rtnval
: -1;
3620 return (rtnval
+ nwrote
);
3625 * VAX/VMS VAX C RTL really loses. It insists that records
3626 * end with a newline (carriage return) character, and if they
3627 * don't it adds one (nice of it isn't it!)
3629 * Thus we do this stupidity below.
3633 sys_write (fildes
, buf
, nbytes
)
3636 unsigned int nbytes
;
3643 fstat (fildes
, &st
);
3649 /* Handle fixed-length files with carriage control. */
3650 if (st
.st_fab_rfm
== FAB$C_FIX
3651 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3653 len
= st
.st_fab_mrs
;
3654 retval
= write (fildes
, p
, min (len
, nbytes
));
3657 retval
++; /* This skips the implied carriage control */
3661 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3662 while (*e
!= '\n' && e
> p
) e
--;
3663 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3664 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3666 retval
= write (fildes
, p
, len
);
3677 /* Create file NEW copying its attributes from file OLD. If
3678 OLD is 0 or does not exist, create based on the value of
3681 /* Protection value the file should ultimately have.
3682 Set by create_copy_attrs, and use by rename_sansversions. */
3683 static unsigned short int fab_final_pro
;
3686 creat_copy_attrs (old
, new)
3689 struct FAB fab
= cc$rms_fab
;
3690 struct XABPRO xabpro
;
3691 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3692 extern int vms_stmlf_recfm
;
3696 fab
.fab$b_fac
= FAB$M_GET
;
3697 fab
.fab$l_fna
= old
;
3698 fab
.fab$b_fns
= strlen (old
);
3699 fab
.fab$l_xab
= (char *) &xabpro
;
3700 xabpro
= cc$rms_xabpro
;
3701 xabpro
.xab$l_aclbuf
= aclbuf
;
3702 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3703 /* Call $OPEN to fill in the fab & xabpro fields. */
3704 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3706 SYS$
CLOSE (&fab
, 0, 0);
3707 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3708 if (xabpro
.xab$w_acllen
> 0)
3710 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3711 /* If the acl buffer was too short, redo open with longer one.
3712 Wouldn't need to do this if there were some system imposed
3713 limit on the size of an ACL, but I can't find any such. */
3715 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3716 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3717 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3718 SYS$
CLOSE (&fab
, 0, 0);
3724 xabpro
.xab$l_aclbuf
= 0;
3729 fab
.fab$l_fna
= new;
3730 fab
.fab$b_fns
= strlen (new);
3734 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3735 fab
.fab$b_rat
= FAB$M_CR
;
3738 /* Set the file protections such that we will be able to manipulate
3739 this file. Once we are done writing and renaming it, we will set
3740 the protections back. */
3742 fab_final_pro
= xabpro
.xab$w_pro
;
3744 SYS$
SETDFPROT (0, &fab_final_pro
);
3745 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3747 /* Create the new file with either default attrs or attrs copied
3749 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3751 SYS$
CLOSE (&fab
, 0, 0);
3752 /* As this is a "replacement" for creat, return a file descriptor
3753 opened for writing. */
3754 return open (new, O_WRONLY
);
3759 #include <varargs.h>
3762 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3766 sys_creat (va_alist
)
3769 va_list list_incrementer
;
3772 int rfd
; /* related file descriptor */
3773 int fd
; /* Our new file descriptor */
3780 extern int vms_stmlf_recfm
;
3783 va_start (list_incrementer
);
3784 name
= va_arg (list_incrementer
, char *);
3785 mode
= va_arg (list_incrementer
, int);
3787 rfd
= va_arg (list_incrementer
, int);
3788 va_end (list_incrementer
);
3791 /* Use information from the related file descriptor to set record
3792 format of the newly created file. */
3793 fstat (rfd
, &st_buf
);
3794 switch (st_buf
.st_fab_rfm
)
3797 strcpy (rfm
, "rfm = fix");
3798 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3799 strcpy (rat
, "rat = ");
3800 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3802 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3803 strcat (rat
, "ftn");
3804 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3805 strcat (rat
, "prn");
3806 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3807 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3808 strcat (rat
, ", blk");
3810 strcat (rat
, "blk");
3811 return creat (name
, 0, rfm
, rat
, mrs
);
3814 strcpy (rfm
, "rfm = vfc");
3815 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3816 strcpy (rat
, "rat = ");
3817 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3819 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3820 strcat (rat
, "ftn");
3821 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3822 strcat (rat
, "prn");
3823 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3824 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3825 strcat (rat
, ", blk");
3827 strcat (rat
, "blk");
3828 return creat (name
, 0, rfm
, rat
, fsz
);
3831 strcpy (rfm
, "rfm = stm");
3835 strcpy (rfm
, "rfm = stmcr");
3839 strcpy (rfm
, "rfm = stmlf");
3843 strcpy (rfm
, "rfm = udf");
3847 strcpy (rfm
, "rfm = var");
3850 strcpy (rat
, "rat = ");
3851 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3853 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3854 strcat (rat
, "ftn");
3855 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3856 strcat (rat
, "prn");
3857 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3858 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3859 strcat (rat
, ", blk");
3861 strcat (rat
, "blk");
3865 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3866 strcpy (rat
, "rat=cr");
3868 /* Until the VAX C RTL fixes the many bugs with modes, always use
3869 mode 0 to get the user's default protection. */
3870 fd
= creat (name
, 0, rfm
, rat
);
3871 if (fd
< 0 && errno
== EEXIST
)
3873 if (unlink (name
) < 0)
3874 report_file_error ("delete", build_string (name
));
3875 fd
= creat (name
, 0, rfm
, rat
);
3881 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3882 sys_fwrite (ptr
, size
, num
, fp
)
3883 register char * ptr
;
3886 register int tot
= num
* size
;
3893 * The VMS C library routine creat actually creates a new version of an
3894 * existing file rather than truncating the old version. There are times
3895 * when this is not the desired behavior, for instance, when writing an
3896 * auto save file (you only want one version), or when you don't have
3897 * write permission in the directory containing the file (but the file
3898 * itself is writable). Hence this routine, which is equivalent to
3899 * "close (creat (fn, 0));" on Unix if fn already exists.
3905 struct FAB xfab
= cc$rms_fab
;
3906 struct RAB xrab
= cc$rms_rab
;
3909 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3910 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3911 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3912 xfab
.fab$l_fna
= fn
;
3913 xfab
.fab$b_fns
= strlen (fn
);
3914 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3916 xrab
.rab$l_fab
= &xfab
;
3918 /* This gibberish opens the file, positions to the first record, and
3919 deletes all records from there until the end of file. */
3920 if ((SYS$
OPEN (&xfab
) & 01) == 01)
3922 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
3923 (SYS$
FIND (&xrab
) & 01) == 01 &&
3924 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
3935 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3936 SYSPRV or a readable SYSUAF.DAT. */
3942 * Routine to read the VMS User Authorization File and return
3943 * a specific user's record.
3946 static struct UAF retuaf
;
3949 get_uaf_name (uname
)
3956 uaf_fab
= cc$rms_fab
;
3957 uaf_rab
= cc$rms_rab
;
3958 /* initialize fab fields */
3959 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3960 uaf_fab
.fab$b_fns
= 21;
3961 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3962 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3963 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3964 /* initialize rab fields */
3965 uaf_rab
.rab$l_fab
= &uaf_fab
;
3966 /* open the User Authorization File */
3967 status
= SYS$
OPEN (&uaf_fab
);
3971 vaxc$errno
= status
;
3974 status
= SYS$
CONNECT (&uaf_rab
);
3978 vaxc$errno
= status
;
3981 /* read the requested record - index is in uname */
3982 uaf_rab
.rab$l_kbf
= uname
;
3983 uaf_rab
.rab$b_ksz
= strlen (uname
);
3984 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3985 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3986 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3987 status
= SYS$
GET (&uaf_rab
);
3991 vaxc$errno
= status
;
3994 /* close the User Authorization File */
3995 status
= SYS$
DISCONNECT (&uaf_rab
);
3999 vaxc$errno
= status
;
4002 status
= SYS$
CLOSE (&uaf_fab
);
4006 vaxc$errno
= status
;
4020 uaf_fab
= cc$rms_fab
;
4021 uaf_rab
= cc$rms_rab
;
4022 /* initialize fab fields */
4023 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4024 uaf_fab
.fab$b_fns
= 21;
4025 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4026 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4027 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4028 /* initialize rab fields */
4029 uaf_rab
.rab$l_fab
= &uaf_fab
;
4030 /* open the User Authorization File */
4031 status
= SYS$
OPEN (&uaf_fab
);
4035 vaxc$errno
= status
;
4038 status
= SYS$
CONNECT (&uaf_rab
);
4042 vaxc$errno
= status
;
4045 /* read the requested record - index is in uic */
4046 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4047 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4048 uaf_rab
.rab$b_ksz
= sizeof uic
;
4049 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4050 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4051 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4052 status
= SYS$
GET (&uaf_rab
);
4056 vaxc$errno
= status
;
4059 /* close the User Authorization File */
4060 status
= SYS$
DISCONNECT (&uaf_rab
);
4064 vaxc$errno
= status
;
4067 status
= SYS$
CLOSE (&uaf_fab
);
4071 vaxc$errno
= status
;
4077 static struct passwd retpw
;
4085 /* copy these out first because if the username is 32 chars, the next
4086 section will overwrite the first byte of the UIC */
4087 retpw
.pw_uid
= up
->uaf$w_mem
;
4088 retpw
.pw_gid
= up
->uaf$w_grp
;
4090 /* I suppose this is not the best sytle, to possibly overwrite one
4091 byte beyond the end of the field, but what the heck... */
4092 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4093 while (ptr
[-1] == ' ')
4096 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4098 /* the rest of these are counted ascii strings */
4099 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4100 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4101 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4102 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4103 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4104 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4105 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4106 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4110 #else /* not READ_SYSUAF */
4111 static struct passwd retpw
;
4112 #endif /* not READ_SYSUAF */
4123 unsigned char * full
;
4124 #endif /* READ_SYSUAF */
4129 if ('a' <= *ptr
&& *ptr
<= 'z')
4134 if (!(up
= get_uaf_name (name
)))
4136 return cnv_uaf_pw (up
);
4138 if (strcmp (name
, getenv ("USER")) == 0)
4140 retpw
.pw_uid
= getuid ();
4141 retpw
.pw_gid
= getgid ();
4142 strcpy (retpw
.pw_name
, name
);
4143 if (full
= egetenv ("FULLNAME"))
4144 strcpy (retpw
.pw_gecos
, full
);
4146 *retpw
.pw_gecos
= '\0';
4147 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4148 *retpw
.pw_shell
= '\0';
4153 #endif /* not READ_SYSUAF */
4163 if (!(up
= get_uaf_uic (uid
)))
4165 return cnv_uaf_pw (up
);
4167 if (uid
== sys_getuid ())
4168 return getpwnam (egetenv ("USER"));
4171 #endif /* not READ_SYSUAF */
4174 /* return total address space available to the current process. This is
4175 the sum of the current p0 size, p1 size and free page table entries
4180 unsigned long free_pages
;
4181 unsigned long frep0va
;
4182 unsigned long frep1va
;
4185 item_code
= JPI$_FREPTECNT
;
4186 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4189 vaxc$errno
= status
;
4194 item_code
= JPI$_FREP0VA
;
4195 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4198 vaxc$errno
= status
;
4201 item_code
= JPI$_FREP1VA
;
4202 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4205 vaxc$errno
= status
;
4209 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4212 define_logical_name (varname
, string
)
4216 struct dsc$descriptor_s strdsc
=
4217 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4218 struct dsc$descriptor_s envdsc
=
4219 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4220 struct dsc$descriptor_s lnmdsc
=
4221 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4223 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4226 delete_logical_name (varname
)
4229 struct dsc$descriptor_s envdsc
=
4230 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4231 struct dsc$descriptor_s lnmdsc
=
4232 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4234 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4245 error ("execvp system call not implemented");
4253 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4254 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4255 char from_esn
[NAM$C_MAXRSS
];
4256 char to_esn
[NAM$C_MAXRSS
];
4258 from_fab
.fab$l_fna
= from
;
4259 from_fab
.fab$b_fns
= strlen (from
);
4260 from_fab
.fab$l_nam
= &from_nam
;
4261 from_fab
.fab$l_fop
= FAB$M_NAM
;
4263 from_nam
.nam$l_esa
= from_esn
;
4264 from_nam
.nam$b_ess
= sizeof from_esn
;
4266 to_fab
.fab$l_fna
= to
;
4267 to_fab
.fab$b_fns
= strlen (to
);
4268 to_fab
.fab$l_nam
= &to_nam
;
4269 to_fab
.fab$l_fop
= FAB$M_NAM
;
4271 to_nam
.nam$l_esa
= to_esn
;
4272 to_nam
.nam$b_ess
= sizeof to_esn
;
4274 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4280 if (status
== RMS$_DEV
)
4284 vaxc$errno
= status
;
4289 /* This function renames a file like `rename', but it strips
4290 the version number from the "to" filename, such that the "to" file is
4291 will always be a new version. It also sets the file protection once it is
4292 finished. The protection that we will use is stored in fab_final_pro,
4293 and was set when we did a creat_copy_attrs to create the file that we
4296 We could use the chmod function, but Eunichs uses 3 bits per user category
4297 to describe the protection, and VMS uses 4 (write and delete are separate
4298 bits). To maintain portability, the VMS implementation of `chmod' wires
4299 the W and D bits together. */
4302 static struct fibdef fib
; /* We need this initialized to zero */
4303 char vms_file_written
[NAM$C_MAXRSS
];
4306 rename_sans_version (from
,to
)
4313 struct FAB to_fab
= cc$rms_fab
;
4314 struct NAM to_nam
= cc$rms_nam
;
4315 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4316 struct dsc$descriptor fib_attr
[2]
4317 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4318 char to_esn
[NAM$C_MAXRSS
];
4320 $
DESCRIPTOR (disk
,to_esn
);
4322 to_fab
.fab$l_fna
= to
;
4323 to_fab
.fab$b_fns
= strlen (to
);
4324 to_fab
.fab$l_nam
= &to_nam
;
4325 to_fab
.fab$l_fop
= FAB$M_NAM
;
4327 to_nam
.nam$l_esa
= to_esn
;
4328 to_nam
.nam$b_ess
= sizeof to_esn
;
4330 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4332 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4333 *(to_nam
.nam$l_ver
) = '\0';
4335 stat
= rename (from
, to_esn
);
4339 strcpy (vms_file_written
, to_esn
);
4341 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4342 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4344 /* Now set the file protection to the correct value */
4345 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4347 /* Copy these fields into the fib */
4348 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4349 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4350 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4352 SYS$
CLOSE (&to_fab
, 0, 0);
4354 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4357 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4358 0, 0, 0, &fib_attr
, 0);
4361 stat
= SYS$
DASSGN (chan
);
4364 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4374 unsigned short fid
[3];
4375 char esa
[NAM$C_MAXRSS
];
4378 fab
.fab$l_fop
= FAB$M_OFP
;
4379 fab
.fab$l_fna
= file
;
4380 fab
.fab$b_fns
= strlen (file
);
4381 fab
.fab$l_nam
= &nam
;
4384 nam
.nam$l_esa
= esa
;
4385 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4387 status
= SYS$
PARSE (&fab
);
4388 if ((status
& 1) == 0)
4391 vaxc$errno
= status
;
4394 status
= SYS$
SEARCH (&fab
);
4395 if ((status
& 1) == 0)
4398 vaxc$errno
= status
;
4402 fid
[0] = nam
.nam$w_fid
[0];
4403 fid
[1] = nam
.nam$w_fid
[1];
4404 fid
[2] = nam
.nam$w_fid
[2];
4406 fab
.fab$l_fna
= new;
4407 fab
.fab$b_fns
= strlen (new);
4409 status
= SYS$
PARSE (&fab
);
4410 if ((status
& 1) == 0)
4413 vaxc$errno
= status
;
4417 nam
.nam$w_fid
[0] = fid
[0];
4418 nam
.nam$w_fid
[1] = fid
[1];
4419 nam
.nam$w_fid
[2] = fid
[2];
4421 nam
.nam$l_esa
= nam
.nam$l_name
;
4422 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4424 status
= SYS$
ENTER (&fab
);
4425 if ((status
& 1) == 0)
4428 vaxc$errno
= status
;
4438 printf ("%s not yet implemented\r\n", badfunc
);
4446 /* Arrange to return a range centered on zero. */
4447 return rand () - (1 << 30);
4458 /* Called from init_sys_modes. */
4463 /* If we're not on an HFT we shouldn't do any of this. We determine
4464 if we are on an HFT by trying to get an HFT error code. If this
4465 call fails, we're not on an HFT. */
4467 if (ioctl (0, HFQERROR
, &junk
) < 0)
4469 #else /* not IBMR2AIX */
4470 if (ioctl (0, HFQEIO
, 0) < 0)
4472 #endif /* not IBMR2AIX */
4474 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4475 as the rubout key's ASCII code. Here this is changed. The bug is that
4476 there's no way to determine the old mapping, so in reset_sys_modes
4477 we need to assume that the normal map had been present. Of course, this
4478 code also doesn't help if on a terminal emulator which doesn't understand
4482 struct hfkeymap keymap
;
4484 buf
.hf_bufp
= (char *)&keymap
;
4485 buf
.hf_buflen
= sizeof (keymap
);
4486 keymap
.hf_nkeys
= 2;
4487 keymap
.hfkey
[0].hf_kpos
= 15;
4488 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4490 keymap
.hfkey
[0].hf_keyidh
= '<';
4491 #else /* not IBMR2AIX */
4492 keymap
.hfkey
[0].hf_page
= '<';
4493 #endif /* not IBMR2AIX */
4494 keymap
.hfkey
[0].hf_char
= 127;
4495 keymap
.hfkey
[1].hf_kpos
= 15;
4496 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4498 keymap
.hfkey
[1].hf_keyidh
= '<';
4499 #else /* not IBMR2AIX */
4500 keymap
.hfkey
[1].hf_page
= '<';
4501 #endif /* not IBMR2AIX */
4502 keymap
.hfkey
[1].hf_char
= 127;
4503 hftctl (0, HFSKBD
, &buf
);
4505 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4507 line_ins_del_ok
= char_ins_del_ok
= 0;
4510 /* Reset the rubout key to backspace. */
4515 struct hfkeymap keymap
;
4519 if (ioctl (0, HFQERROR
, &junk
) < 0)
4521 #else /* not IBMR2AIX */
4522 if (ioctl (0, HFQEIO
, 0) < 0)
4524 #endif /* not IBMR2AIX */
4526 buf
.hf_bufp
= (char *)&keymap
;
4527 buf
.hf_buflen
= sizeof (keymap
);
4528 keymap
.hf_nkeys
= 2;
4529 keymap
.hfkey
[0].hf_kpos
= 15;
4530 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4532 keymap
.hfkey
[0].hf_keyidh
= '<';
4533 #else /* not IBMR2AIX */
4534 keymap
.hfkey
[0].hf_page
= '<';
4535 #endif /* not IBMR2AIX */
4536 keymap
.hfkey
[0].hf_char
= 8;
4537 keymap
.hfkey
[1].hf_kpos
= 15;
4538 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4540 keymap
.hfkey
[1].hf_keyidh
= '<';
4541 #else /* not IBMR2AIX */
4542 keymap
.hfkey
[1].hf_page
= '<';
4543 #endif /* not IBMR2AIX */
4544 keymap
.hfkey
[1].hf_char
= 8;
4545 hftctl (0, HFSKBD
, &buf
);