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>
120 #ifdef BROKEN_TIOCGWINSZ
125 #include <sys/utsname.h>
127 #ifndef MEMORY_IN_STRING_H
132 #include <sys/sioctl.h>
135 #include <sys/stream.h>
136 #include <sys/ptem.h>
138 #endif /* TIOCGWINSZ */
141 extern int quit_char
;
145 #include "termhooks.h"
146 #include "termchar.h"
147 #include "termopts.h"
148 #include "dispextern.h"
151 #ifdef NONSYSTEM_DIR_LIBRARY
153 #endif /* NONSYSTEM_DIR_LIBRARY */
155 #include "syssignal.h"
158 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
164 #define LNOFLSH 0100000
167 static int baud_convert
[] =
172 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
173 1800, 2400, 4800, 9600, 19200, 38400
179 /* The file descriptor for Emacs's input terminal.
180 Under Unix, this is normaly zero except when using X;
181 under VMS, we place the input channel number here.
182 This allows us to write more code that works for both VMS and Unix. */
185 /* Specify a different file descriptor for further input operations. */
194 /* Discard pending input on descriptor input_fd. */
198 struct emacs_tty buf
;
203 /* Discarding input is not safe when the input could contain
204 replies from the X server. So don't do it. */
205 if (read_socket_hook
)
210 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
211 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
217 ioctl (input_fd
, TIOCFLUSH
, &zero
);
219 #else /* not Apollo */
220 EMACS_GET_TTY (input_fd
, &buf
);
221 EMACS_SET_TTY (input_fd
, &buf
, 0);
222 #endif /* not Apollo */
228 /* Arrange for character C to be read as the next input from
234 /* Should perhaps error if in batch mode */
236 ioctl (input_fd
, TIOCSTI
, &c
);
237 #else /* no TIOCSTI */
238 error ("Cannot stuff terminal input characters in this version of Unix");
239 #endif /* no TIOCSTI */
253 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
254 &sg
.class, 12, 0, 0, 0, 0 );
255 ospeed
= sg
.xmit_baud
;
261 tcgetattr (input_fd
, &sg
);
262 ospeed
= cfgetospeed (&sg
);
263 #else /* neither VMS nor TERMIOS */
269 tcgetattr (input_fd
, &sg
);
271 ioctl (input_fd
, TCGETA
, &sg
);
273 ospeed
= sg
.c_cflag
& CBAUD
;
274 #else /* neither VMS nor TERMIOS nor TERMIO */
277 sg
.sg_ospeed
= B9600
;
278 if (ioctl (input_fd
, TIOCGETP
, &sg
) < 0)
280 ospeed
= sg
.sg_ospeed
;
281 #endif /* not HAVE_TERMIO */
282 #endif /* not HAVE_TERMIOS */
286 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
287 ? baud_convert
[ospeed
] : 9600);
293 set_exclusive_use (fd
)
297 ioctl (fd
, FIOCLEX
, 0);
299 /* Ok to do nothing if this feature does not exist */
304 wait_without_blocking ()
307 wait3 (0, WNOHANG
| WUNTRACED
, 0);
309 croak ("wait_without_blocking");
311 synch_process_alive
= 0;
314 #endif /* not subprocesses */
316 int wait_debugging
; /* Set nonzero to make following function work under dbx
317 (at least for bsd). */
320 wait_for_termination_signal ()
323 /* Wait for subprocess with process id `pid' to terminate and
324 make sure it will get eliminated (not remain forever as a zombie) */
326 wait_for_termination (pid
)
335 status
= SYS$
FORCEX (&pid
, 0, 0);
338 #if defined (BSD) || (defined (HPUX) && !defined (HPUX_5))
339 /* Note that kill returns -1 even if the process is just a zombie now.
340 But inevitably a SIGCHLD interrupt should be generated
341 and child_sig will do wait3 and make the process go away. */
342 /* There is some indication that there is a bug involved with
343 termination of subprocesses, perhaps involving a kernel bug too,
344 but no idea what it is. Just as a hunch we signal SIGCHLD to see
345 if that causes the problem to go away or get worse. */
346 sigsetmask (sigmask (SIGCHLD
));
347 if (0 > kill (pid
, 0))
349 sigsetmask (SIGEMPTYMASK
);
350 kill (getpid (), SIGCHLD
);
356 sigpause (SIGEMPTYMASK
);
357 #else /* not BSD, and not HPUX version >= 6 */
358 #if defined (UNIPLUS)
359 if (0 > kill (pid
, 0))
362 #else /* neither BSD nor UNIPLUS: random sysV */
363 #ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
364 sigblock (sigmask (SIGCHLD
));
365 if (0 > kill (pid
, 0))
367 sigunblock (sigmask (SIGCHLD
));
370 sigpause (SIGEMPTYMASK
);
371 #else /* not POSIX_SIGNALS */
372 #ifdef HAVE_SYSV_SIGPAUSE
374 if (0 > kill (pid
, 0))
380 #else /* not HAVE_SYSV_SIGPAUSE */
381 if (0 > kill (pid
, 0))
383 /* Using sleep instead of pause avoids timing error.
384 If the inferior dies just before the sleep,
385 we lose just one second. */
387 #endif /* not HAVE_SYSV_SIGPAUSE */
388 #endif /* not POSIX_SIGNALS */
389 #endif /* not UNIPLUS */
390 #endif /* not BSD, and not HPUX version >= 6 */
392 #else /* not subprocesses */
394 if (kill (pid
, 0) < 0)
400 if (status
== pid
|| status
== -1)
403 #endif /* not subprocesses */
410 * flush any pending output
411 * (may flush input as well; it does not matter the way we use it)
414 flush_pending_output (channel
)
418 /* If we try this, we get hit with SIGTTIN, because
419 the child's tty belongs to the child's pgrp. */
422 ioctl (channel
, TCFLSH
, 1);
426 /* 3rd arg should be ignored
427 but some 4.2 kernels actually want the address of an int
428 and nonzero means something different. */
429 ioctl (channel
, TIOCFLUSH
, &zero
);
436 /* Set up the terminal at the other end of a pseudo-terminal that
437 we will be controlling an inferior through.
438 It should not echo or do line-editing, since that is done
439 in Emacs. No padding needed for insertion into an Emacs buffer. */
441 child_setup_tty (out
)
446 EMACS_GET_TTY (out
, &s
);
448 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
449 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
450 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
451 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
452 /* No output delays */
453 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
454 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
455 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
457 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
459 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CSIZE
) | CS8
; /* Don't strip 8th bit */
461 /* Said to be unnecessary: */
462 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
463 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
466 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
467 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
468 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
469 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
472 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
476 /* AIX enhanced edit loses NULs, so disable it */
479 s
.main
.c_iflag
&= ~ASCEDIT
;
481 /* Also, PTY overloads NUL and BREAK.
482 don't ignore break, but don't signal either, so it looks like NUL. */
483 s
.main
.c_iflag
&= ~IGNBRK
;
484 s
.main
.c_iflag
&= ~BRKINT
;
485 /* QUIT and INTR work better as signals, so disable character forms */
486 s
.main
.c_cc
[VINTR
] = 0377;
487 #ifdef SIGNALS_VIA_CHARACTERS
488 /* the QUIT and INTR character are used in process_send_signal
489 so set them here to something useful. */
490 if (s
.main
.c_cc
[VQUIT
] == 0377)
491 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
492 if (s
.main
.c_cc
[VINTR
] == 0377)
493 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
494 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
495 /* QUIT and INTR work better as signals, so disable character forms */
496 s
.main
.c_cc
[VQUIT
] = 0377;
497 s
.main
.c_cc
[VINTR
] = 0377;
498 s
.main
.c_lflag
&= ~ISIG
;
499 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
500 s
.main
.c_cc
[VEOL
] = 0377;
501 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
504 #else /* not HAVE_TERMIO */
506 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
508 s
.main
.sg_flags
|= LPASS8
;
509 s
.main
.sg_erase
= 0377;
510 s
.main
.sg_kill
= 0377;
511 s
.lmode
= LLITOUT
| s
.lmode
; /* Don't strip 8th bit */
513 #endif /* not HAVE_TERMIO */
515 EMACS_SET_TTY (out
, &s
, 0);
524 ioctl (out
, FIOASYNC
, &zero
);
530 #endif /* subprocesses */
536 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
539 /* Record a signal code and the handler for it. */
543 SIGTYPE (*handler
) ();
546 /* Suspend the Emacs process; give terminal to its superior. */
551 /* "Foster" parentage allows emacs to return to a subprocess that attached
552 to the current emacs as a cheaper than starting a whole new process. This
553 is set up by KEPTEDITOR.COM. */
554 unsigned long parent_id
, foster_parent_id
;
557 fpid_string
= getenv ("EMACS_PARENT_PID");
558 if (fpid_string
!= NULL
)
560 sscanf (fpid_string
, "%x", &foster_parent_id
);
561 if (foster_parent_id
!= 0)
562 parent_id
= foster_parent_id
;
564 parent_id
= getppid ();
567 parent_id
= getppid ();
569 xfree (fpid_string
); /* On VMS, this was malloc'd */
571 if (parent_id
&& parent_id
!= 0xffffffff)
573 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
574 int status
= LIB$
ATTACH (&parent_id
) & 1;
575 signal (SIGINT
, oldsig
);
584 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
585 d_prompt
.a
= "Emacs: "; /* Just a reminder */
586 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
594 int pgrp
= EMACS_GETPGRP (0);
595 EMACS_KILLPG (pgrp
, SIGTSTP
);
598 #else /* No SIGTSTP */
599 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
600 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
601 kill (getpid (), SIGQUIT
);
603 #else /* No SIGTSTP or USG_JOBCTRL */
605 /* On a system where suspending is not implemented,
606 instead fork a subshell and let it talk directly to the terminal
609 struct save_signal saved_handlers
[5];
611 saved_handlers
[0].code
= SIGINT
;
612 saved_handlers
[1].code
= SIGQUIT
;
613 saved_handlers
[2].code
= SIGTERM
;
615 saved_handlers
[3].code
= SIGIO
;
616 saved_handlers
[4].code
= 0;
618 saved_handlers
[3].code
= 0;
622 error ("Can't spawn subshell");
627 sh
= (char *) egetenv ("SHELL");
630 /* Use our buffer's default directory for the subshell. */
636 /* mentioning current_buffer->buffer would mean including buffer.h,
637 which somehow wedges the hp compiler. So instead... */
639 dir
= intern ("default-directory");
641 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
643 dir
= Fsymbol_value (dir
);
644 if (XTYPE (dir
) != Lisp_String
)
647 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
648 len
= XSTRING (dir
)->size
;
649 bcopy (XSTRING (dir
)->data
, str
, len
);
650 if (str
[len
- 1] != '/') str
[len
++] = '/';
656 close_process_descs (); /* Close Emacs's pipes/ptys */
661 extern int emacs_priority
;
664 nice (-emacs_priority
);
669 write (1, "Can't execute subshell", 22);
673 save_signal_handlers (saved_handlers
);
674 synch_process_alive
= 1;
675 wait_for_termination (pid
);
676 restore_signal_handlers (saved_handlers
);
678 #endif /* no USG_JOBCTRL */
679 #endif /* no SIGTSTP */
683 save_signal_handlers (saved_handlers
)
684 struct save_signal
*saved_handlers
;
686 while (saved_handlers
->code
)
688 saved_handlers
->handler
689 = (SIGTYPE (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
694 restore_signal_handlers (saved_handlers
)
695 struct save_signal
*saved_handlers
;
697 while (saved_handlers
->code
)
699 signal (saved_handlers
->code
, saved_handlers
->handler
);
711 old_fcntl_flags
= fcntl (input_fd
, F_GETFL
, 0) & ~FASYNC
;
721 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
726 sigunblock (sigmask (SIGWINCH
));
728 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
| FASYNC
);
730 interrupts_deferred
= 0;
736 sigblock (sigmask (SIGWINCH
));
738 fcntl (input_fd
, F_SETFL
, old_fcntl_flags
);
739 interrupts_deferred
= 1;
742 #else /* no FASYNC */
743 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
748 ioctl (input_fd
, FIOASYNC
, &on
);
749 interrupts_deferred
= 0;
756 ioctl (input_fd
, FIOASYNC
, &off
);
757 interrupts_deferred
= 1;
760 #else /* not FASYNC, not STRIDE */
764 croak ("request_sigio");
769 croak ("unrequest_sigio");
776 /* Saving and restoring the process group of Emacs's terminal. */
780 /* The process group of which Emacs was a member when it initially
783 If Emacs was in its own process group (i.e. inherited_pgroup ==
784 getpid ()), then we know we're running under a shell with job
785 control (Emacs would never be run as part of a pipeline).
788 If Emacs was not in its own process group, then we know we're
789 running under a shell (or a caller) that doesn't know how to
790 separate itself from Emacs (like sh). Emacs must be in its own
791 process group in order to receive SIGIO correctly. In this
792 situation, we put ourselves in our own pgroup, forcibly set the
793 tty's pgroup to our pgroup, and make sure to restore and reinstate
794 the tty's pgroup just like any other terminal setting. If
795 inherited_group was not the tty's pgroup, then we'll get a
796 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
797 it goes foreground in the future, which is what should happen. */
798 int inherited_pgroup
;
800 /* Split off the foreground process group to Emacs alone.
801 When we are in the foreground, but not started in our own process
802 group, redirect the TTY to point to our own process group. We need
803 to be in our own process group to receive SIGIO properly. */
804 narrow_foreground_group ()
808 setpgrp (0, inherited_pgroup
);
809 if (inherited_pgroup
!= me
)
810 EMACS_SET_TTY_PGRP (input_fd
, &me
);
814 /* Set the tty to our original foreground group. */
815 widen_foreground_group ()
817 if (inherited_pgroup
!= getpid ())
818 EMACS_SET_TTY_PGRP (input_fd
, &inherited_pgroup
);
819 setpgrp (0, inherited_pgroup
);
824 /* Getting and setting emacs_tty structures. */
826 /* Set *TC to the parameters associated with the terminal FD.
827 Return zero if all's well, or -1 if we ran into an error we
828 couldn't deal with. */
830 emacs_get_tty (fd
, settings
)
832 struct emacs_tty
*settings
;
834 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
836 /* We have those nifty POSIX tcmumbleattr functions. */
837 if (tcgetattr (fd
, &settings
->main
) < 0)
842 /* The SYSV-style interface? */
843 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
848 /* Vehemently Monstrous System? :-) */
849 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
850 &settings
->main
.class, 12, 0, 0, 0, 0)
855 /* I give up - I hope you have the BSD ioctls. */
856 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
863 /* Suivant - Do we have to get struct ltchars data? */
865 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
869 /* How about a struct tchars and a wordful of lmode bits? */
871 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
872 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
876 /* We have survived the tempest. */
881 /* Set the parameters of the tty on FD according to the contents of
882 *SETTINGS. If WAITP is non-zero, we wait for all queued output to
883 be written before making the change; otherwise, we forget any
884 queued input and make the change immediately.
885 Return 0 if all went well, and -1 if anything failed. */
887 emacs_set_tty (fd
, settings
, waitp
)
889 struct emacs_tty
*settings
;
892 /* Set the primary parameters - baud rate, character size, etcetera. */
895 /* We have those nifty POSIX tcmumbleattr functions.
896 William J. Smith <wjs@wiis.wang.com> writes:
897 "POSIX 1003.1 defines tcsetattr() to return success if it was
898 able to perform any of the requested actions, even if some
899 of the requested actions could not be performed.
900 We must read settings back to ensure tty setup properly.
901 AIX requires this to keep tty from hanging occasionally." */
902 /* This make sure that we don't loop indefinitely in here. */
903 for (i
= 0 ; i
< 10 ; i
++)
904 if (tcsetattr (fd
, waitp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
915 /* Get the current settings, and see if they're what we asked for. */
916 tcgetattr (fd
, &new);
917 /* We cannot use memcmp on the whole structure here because under
918 * aix386 the termios structure has some reserved field that may
921 if ( new.c_iflag
== settings
->main
.c_iflag
922 && new.c_oflag
== settings
->main
.c_oflag
923 && new.c_cflag
== settings
->main
.c_cflag
924 && new.c_lflag
== settings
->main
.c_lflag
925 && memcmp(new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
933 /* The SYSV-style interface? */
934 if (ioctl (fd
, waitp
? TCSETAW
: TCSETAF
, &settings
->main
) < 0)
939 /* Vehemently Monstrous System? :-) */
940 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
941 &settings
->main
.class, 12, 0, 0, 0, 0)
946 /* I give up - I hope you have the BSD ioctls. */
947 if (ioctl (fd
, (waitp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
954 /* Suivant - Do we have to get struct ltchars data? */
956 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
960 /* How about a struct tchars and a wordful of lmode bits? */
962 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
963 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
967 /* We have survived the tempest. */
972 /* The initial tty mode bits */
973 struct emacs_tty old_tty
;
975 int term_initted
; /* 1 if outer tty status has been recorded */
978 /* BSD 4.1 needs to keep track of the lmode bits in order to start
986 #endif /* F_SETOWN */
987 #endif /* F_SETOWN_BUG */
989 /* This may also be defined in stdio,
990 but if so, this does no harm,
991 and using the same name avoids wasting the other one's space. */
993 #if defined (USG) || defined (DGUX)
994 unsigned char _sobuf
[BUFSIZ
+8];
1000 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
1003 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
1008 struct emacs_tty tty
;
1012 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
1013 extern int (*interrupt_signal
) ();
1022 input_ef
= get_kbd_event_flag ();
1023 /* LIB$GET_EF (&input_ef); */
1024 SYS$
CLREF (input_ef
);
1025 waiting_for_ast
= 0;
1027 timer_ef
= get_timer_event_flag ();
1028 /* LIB$GET_EF (&timer_ef); */
1029 SYS$
CLREF (timer_ef
);
1033 LIB$
GET_EF (&process_ef
);
1034 SYS$
CLREF (process_ef
);
1036 if (input_ef
/ 32 != process_ef
/ 32)
1037 croak ("Input and process event flags in different clusters.");
1039 if (input_ef
/ 32 != timer_ef
/ 32)
1040 croak ("Input and timer event flags in different clusters.");
1042 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1043 ((unsigned) 1 << (process_ef
% 32));
1045 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1046 ((unsigned) 1 << (timer_ef
% 32));
1048 sys_access_reinit ();
1050 #endif /* not VMS */
1053 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1054 narrow_foreground_group ();
1057 EMACS_GET_TTY (input_fd
, &old_tty
);
1059 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1063 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1064 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1065 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1067 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1069 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1070 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1072 tty
.main
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
1074 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1077 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1079 tty
.main
.c_iflag
&= ~IXANY
;
1083 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1084 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1086 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1090 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1091 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1094 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1095 /* Set up C-g for both SIGQUIT and SIGINT.
1096 We don't know which we will get, but we handle both alike
1097 so which one it really gives us does not matter. */
1098 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1099 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1100 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1102 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1105 #if defined (mips) || defined (HAVE_TCATTR)
1107 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1110 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1111 #endif /* V_DSUSP */
1112 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1113 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1116 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1119 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1120 #endif /* VREPRINT */
1122 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1123 #endif /* VWERASE */
1125 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1126 #endif /* VDISCARD */
1127 #endif /* mips or HAVE_TCATTR */
1130 /* AIX enhanced edit loses NULs, so disable it */
1131 tty
.main
.c_line
= 0;
1132 tty
.main
.c_iflag
&= ~ASCEDIT
;
1134 tty
.main
.c_cc
[VSTRT
] = 255;
1135 tty
.main
.c_cc
[VSTOP
] = 255;
1136 tty
.main
.c_cc
[VSUSP
] = 255;
1137 tty
.main
.c_cc
[VDSUSP
] = 255;
1138 #endif /* IBMR2AIX */
1139 /* Also, PTY overloads NUL and BREAK.
1140 don't ignore break, but don't signal either, so it looks like NUL.
1141 This really serves a purpose only if running in an XTERM window
1142 or via TELNET or the like, but does no harm elsewhere. */
1143 tty
.main
.c_iflag
&= ~IGNBRK
;
1144 tty
.main
.c_iflag
&= ~BRKINT
;
1146 #else /* if not HAVE_TERMIO */
1148 tty
.main
.tt_char
|= TT$M_NOECHO
;
1150 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1152 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1154 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1155 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1156 #else /* not VMS (BSD, that is) */
1157 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1159 tty
.main
.sg_flags
|= ANYP
;
1160 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1161 #endif /* not VMS (BSD, that is) */
1162 #endif /* not HAVE_TERMIO */
1164 /* If going to use CBREAK mode, we must request C-g to interrupt
1165 and turn off start and stop chars, etc. If not going to use
1166 CBREAK mode, do this anyway so as to turn off local flow
1167 control for user coming over network on 4.2; in this case,
1168 only t_stopc and t_startc really matter. */
1171 /* Note: if not using CBREAK mode, it makes no difference how we
1173 tty
.tchars
= new_tchars
;
1174 tty
.tchars
.t_intrc
= quit_char
;
1177 tty
.tchars
.t_startc
= '\021';
1178 tty
.tchars
.t_stopc
= '\023';
1181 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1183 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1184 anything, and leaving it in breaks the meta key. Go figure. */
1185 tty
.lmode
&= ~LLITOUT
;
1192 #endif /* HAVE_TCHARS */
1193 #endif /* not HAVE_TERMIO */
1196 tty
.ltchars
= new_ltchars
;
1197 #endif /* HAVE_LTCHARS */
1199 EMACS_SET_TTY (input_fd
, &tty
, 0);
1201 /* This code added to insure that, if flow-control is not to be used,
1202 we have an unlocked terminal at the start. */
1205 if (!flow_control
) ioctl (input_fd
, TCXONC
, 1);
1209 if (!flow_control
) ioctl (input_fd
, TIOCSTART
, 0);
1217 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1218 to be only LF. This is the way that is done. */
1221 if (ioctl (1, HFTGETID
, &tty
) != -1)
1222 write (1, "\033[20l", 5);
1228 /* Appears to do nothing when in PASTHRU mode.
1229 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1230 interrupt_signal, oob_chars, 0, 0, 0, 0);
1232 queue_kbd_input (0);
1237 #ifndef F_SETOWN_BUG
1238 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1239 if (interrupt_input
)
1241 old_fcntl_owner
= fcntl (input_fd
, F_GETOWN
, 0);
1242 fcntl (input_fd
, F_SETOWN
, getpid ());
1245 #endif /* F_GETOWN */
1246 #endif /* F_SETOWN_BUG */
1247 #endif /* F_SETFL */
1250 if (interrupt_input
)
1254 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1258 /* This symbol is defined on recent USG systems.
1259 Someone says without this call USG won't really buffer the file
1260 even with a call to setbuf. */
1261 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1263 setbuf (stdout
, _sobuf
);
1265 set_terminal_modes ();
1266 if (term_initted
&& no_redraw_on_reenter
)
1268 if (display_completed
)
1269 direct_output_forward_char (0);
1275 if (FRAMEP (Vterminal_frame
))
1276 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1283 /* Return nonzero if safe to use tabs in output.
1284 At the time this is called, init_sys_modes has not been done yet. */
1288 struct emacs_tty tty
;
1290 EMACS_GET_TTY (input_fd
, &tty
);
1291 return EMACS_TTY_TABS_OK (&tty
);
1294 /* Get terminal size from system.
1295 Store number of lines into *heightp and width into *widthp.
1296 If zero or a negative number is stored, the value is not valid. */
1298 get_frame_size (widthp
, heightp
)
1299 int *widthp
, *heightp
;
1305 struct winsize size
;
1307 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1308 *widthp
= *heightp
= 0;
1311 *widthp
= size
.ws_col
;
1312 *heightp
= size
.ws_row
;
1318 /* SunOS - style. */
1319 struct ttysize size
;
1321 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1322 *widthp
= *heightp
= 0;
1325 *widthp
= size
.ts_cols
;
1326 *heightp
= size
.ts_lines
;
1332 struct sensemode tty
;
1334 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1335 &tty
.class, 12, 0, 0, 0, 0);
1336 *widthp
= tty
.scr_wid
;
1337 *heightp
= tty
.scr_len
;
1339 #else /* system doesn't know size */
1344 #endif /* not VMS */
1345 #endif /* not SunOS-style */
1346 #endif /* not BSD-style */
1350 /* Prepare the terminal for exiting Emacs; move the cursor to the
1351 bottom of the frame, turn off interrupt-driven I/O, etc. */
1361 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1363 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1364 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1365 /* clear_end_of_line may move the cursor */
1366 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1369 /* HFT devices normally use ^J as a LF/CR. We forced it to
1370 do the LF only. Now, we need to reset it. */
1373 if (ioctl (1, HFTGETID
, &tty
) != -1)
1374 write (1, "\033[20h", 5);
1378 reset_terminal_modes ();
1382 /* Avoid possible loss of output when changing terminal modes. */
1383 fsync (fileno (stdout
));
1388 #ifndef F_SETOWN_BUG
1389 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1390 if (interrupt_input
)
1393 fcntl (input_fd
, F_SETOWN
, old_fcntl_owner
);
1395 #endif /* F_SETOWN */
1396 #endif /* F_SETOWN_BUG */
1397 #endif /* F_SETFL */
1399 if (interrupt_input
)
1403 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1411 widen_foreground_group ();
1417 /* Set up the proper status flags for use of a pty. */
1422 /* I'm told that TOICREMOTE does not mean control chars
1423 "can't be sent" but rather that they don't have
1424 input-editing or signaling effects.
1425 That should be good, because we have other ways
1426 to do those things in Emacs.
1427 However, telnet mode seems not to work on 4.2.
1428 So TIOCREMOTE is turned off now. */
1430 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1431 will hang. In particular, the "timeout" feature (which
1432 causes a read to return if there is no data available)
1433 does this. Also it is known that telnet mode will hang
1434 in such a way that Emacs must be stopped (perhaps this
1435 is the same problem).
1437 If TIOCREMOTE is turned off, then there is a bug in
1438 hp-ux which sometimes loses data. Apparently the
1439 code which blocks the master process when the internal
1440 buffer fills up does not work. Other than this,
1441 though, everything else seems to work fine.
1443 Since the latter lossage is more benign, we may as well
1444 lose that way. -- cph */
1449 ioctl (fd
, FIONBIO
, &on
);
1454 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1455 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1456 /* cause EMACS not to die when it should, i.e., when its own controlling */
1457 /* tty goes away. I've complained to the AIX developers, and they may */
1458 /* change this behavior, but I'm not going to hold my breath. */
1459 signal (SIGHUP
, SIG_IGN
);
1462 #endif /* HAVE_PTYS */
1466 /* Assigning an input channel is done at the start of Emacs execution.
1467 This is called each time Emacs is resumed, also, but does nothing
1468 because input_chain is no longer zero. */
1476 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1482 /* Deassigning the input channel is done before exiting. */
1486 return SYS$
DASSGN (input_fd
);
1491 /* Request reading one character into the keyboard buffer.
1492 This is done as soon as the buffer becomes empty. */
1497 extern kbd_input_ast ();
1499 waiting_for_ast
= 0;
1501 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1502 &input_iosb
, kbd_input_ast
, 1,
1503 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1508 /* Ast routine that is called when keyboard input comes in
1509 in accord with the SYS$QIO above. */
1513 register int c
= -1;
1514 int old_errno
= errno
;
1515 extern EMACS_TIME
*input_available_clear_time
;
1517 if (waiting_for_ast
)
1518 SYS$
SETEF (input_ef
);
1519 waiting_for_ast
= 0;
1522 if (input_count
== 25)
1524 printf ("Ast # %d,", input_count
);
1525 printf (" iosb = %x, %x, %x, %x",
1526 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1529 if (input_iosb
.offset
)
1533 printf (", char = 0%o", c
);
1545 struct input_event e
;
1546 e
.kind
= ascii_keystroke
;
1547 XSET (e
.code
, Lisp_Int
, c
);
1549 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1551 e
.frame_or_window
= Qnil
;
1553 kbd_buffer_store_event (&e
);
1555 if (input_available_clear_time
)
1556 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1560 /* Wait until there is something in kbd_buffer. */
1562 wait_for_kbd_input ()
1564 extern int have_process_input
, process_exited
;
1566 /* If already something, avoid doing system calls. */
1567 if (detect_input_pending ())
1571 /* Clear a flag, and tell ast routine above to set it. */
1572 SYS$
CLREF (input_ef
);
1573 waiting_for_ast
= 1;
1574 /* Check for timing error: ast happened while we were doing that. */
1575 if (!detect_input_pending ())
1577 /* No timing error: wait for flag to be set. */
1578 set_waiting_for_input (0);
1579 SYS$
WFLOR (input_ef
, input_eflist
);
1580 clear_waiting_for_input (0);
1581 if (!detect_input_pending ())
1582 /* Check for subprocess input availability */
1584 int dsp
= have_process_input
|| process_exited
;
1586 SYS$
CLREF (process_ef
);
1587 if (have_process_input
)
1588 process_command_input ();
1593 update_mode_lines
++;
1594 prepare_menu_bars ();
1595 redisplay_preserve_echo_area ();
1599 waiting_for_ast
= 0;
1602 /* Get rid of any pending QIO, when we are about to suspend
1603 or when we want to throw away pending input.
1604 We wait for a positive sign that the AST routine has run
1605 and therefore there is no I/O request queued when we return.
1606 SYS$SETAST is used to avoid a timing error. */
1611 printf ("At end_kbd_input.\n");
1615 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1617 SYS$
CANCEL (input_fd
);
1622 /* Clear a flag, and tell ast routine above to set it. */
1623 SYS$
CLREF (input_ef
);
1624 waiting_for_ast
= 1;
1626 SYS$
CANCEL (input_fd
);
1628 SYS$
WAITFR (input_ef
);
1629 waiting_for_ast
= 0;
1632 /* Wait for either input available or time interval expiry. */
1634 input_wait_timeout (timeval
)
1635 int timeval
; /* Time to wait, in seconds */
1638 static int zero
= 0;
1639 static int large
= -10000000;
1641 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1643 /* If already something, avoid doing system calls. */
1644 if (detect_input_pending ())
1648 /* Clear a flag, and tell ast routine above to set it. */
1649 SYS$
CLREF (input_ef
);
1650 waiting_for_ast
= 1;
1651 /* Check for timing error: ast happened while we were doing that. */
1652 if (!detect_input_pending ())
1654 /* No timing error: wait for flag to be set. */
1656 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1657 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1659 waiting_for_ast
= 0;
1662 /* The standard `sleep' routine works some other way
1663 and it stops working if you have ever quit out of it.
1664 This one continues to work. */
1670 static int zero
= 0;
1671 static int large
= -10000000;
1673 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1676 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1677 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1692 croak ("request sigio");
1697 croak ("unrequest sigio");
1702 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1707 #ifndef SYSTEM_MALLOC
1714 /* Some systems that cannot dump also cannot implement these. */
1717 * Return the address of the start of the text segment prior to
1718 * doing an unexec. After unexec the return value is undefined.
1719 * See crt0.c for further explanation and _start.
1723 #ifndef CANNOT_UNEXEC
1728 return ((char *) TEXT_START
);
1732 return ((char *) csrt
);
1733 #else /* not GOULD */
1734 extern int _start ();
1735 return ((char *) _start
);
1737 #endif /* TEXT_START */
1739 #endif /* not CANNOT_UNEXEC */
1742 * Return the address of the start of the data segment prior to
1743 * doing an unexec. After unexec the return value is undefined.
1744 * See crt0.c for further information and definition of data_start.
1746 * Apparently, on BSD systems this is etext at startup. On
1747 * USG systems (swapping) this is highly mmu dependent and
1748 * is also dependent on whether or not the program is running
1749 * with shared text. Generally there is a (possibly large)
1750 * gap between end of text and start of data with shared text.
1752 * On Uniplus+ systems with shared text, data starts at a
1753 * fixed address. Each port (from a given oem) is generally
1754 * different, and the specific value of the start of data can
1755 * be obtained via the UniPlus+ specific "uvar" system call,
1756 * however the method outlined in crt0.c seems to be more portable.
1758 * Probably what will have to happen when a USG unexec is available,
1759 * at least on UniPlus, is temacs will have to be made unshared so
1760 * that text and data are contiguous. Then once loadup is complete,
1761 * unexec will produce a shared executable where the data can be
1762 * at the normal shared text boundry and the startofdata variable
1763 * will be patched by unexec to the correct value.
1771 return ((char *) DATA_START
);
1773 #ifdef ORDINARY_LINK
1775 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1776 * data_start isn't defined. We take the address of environ, which
1777 * is known to live at or near the start of the system crt0.c, and
1778 * we don't sweat the handful of bytes that might lose.
1780 extern char **environ
;
1782 return((char *) &environ
);
1784 extern int data_start
;
1785 return ((char *) &data_start
);
1786 #endif /* ORDINARY_LINK */
1787 #endif /* DATA_START */
1789 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1792 /* Some systems that cannot dump also cannot implement these. */
1795 * Return the address of the end of the text segment prior to
1796 * doing an unexec. After unexec the return value is undefined.
1803 return ((char *) TEXT_END
);
1806 return ((char *) &etext
);
1811 * Return the address of the end of the data segment prior to
1812 * doing an unexec. After unexec the return value is undefined.
1819 return ((char *) DATA_END
);
1822 return ((char *) &edata
);
1826 #endif /* not CANNOT_DUMP */
1828 /* Get_system_name returns as its value
1829 a string for the Lisp function system-name to return. */
1835 /* Can't have this within the function since `static' is #defined to
1836 nothing for some USG systems. */
1838 #ifdef HAVE_GETHOSTNAME
1839 static char get_system_name_name
[256];
1840 #else /* not HAVE_GETHOSTNAME */
1841 static struct utsname get_system_name_name
;
1842 #endif /* not HAVE_GETHOSTNAME */
1849 #include <sys/socket.h>
1851 #endif /* HAVE_SOCKETS */
1852 #endif /* not VMS */
1853 #endif /* not USG */
1854 #endif /* not BSD4_1 */
1860 #ifdef HAVE_GETHOSTNAME
1861 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1862 return get_system_name_name
;
1863 #else /* not HAVE_GETHOSTNAME */
1864 uname (&get_system_name_name
);
1865 return (get_system_name_name
.nodename
);
1866 #endif /* not HAVE_GETHOSTNAME */
1870 #else /* not USG, not 4.1 */
1871 static char system_name_saved
[32];
1874 if ((sp
= egetenv ("SYS$NODE")) == 0)
1880 if ((end
= index (sp
, ':')) != 0)
1883 strcpy (system_name_saved
, sp
);
1885 gethostname (system_name_saved
, sizeof (system_name_saved
));
1887 /* Turn the hostname into the official, fully-qualified hostname.
1888 Don't do this if we're going to dump; this can confuse system
1889 libraries on some machines and make the dumped emacs core dump. */
1892 #endif /* not CANNOT_DUMP */
1895 hp
= gethostbyname (system_name_saved
);
1896 if (hp
&& strlen (hp
->h_name
) < sizeof(system_name_saved
))
1897 strcpy (system_name_saved
, hp
->h_name
);
1899 #endif /* HAVE_SOCKETS */
1900 #endif /* not VMS */
1901 return system_name_saved
;
1902 #endif /* not USG, not 4.1 */
1903 #endif /* not USG */
1907 #ifndef HAVE_GETHOSTNAME
1908 void gethostname(buf
, len
)
1913 s
= getenv ("SYS$NODE");
1917 strncpy (buf
, s
, len
- 2);
1918 buf
[len
- 1] = '\0';
1920 } /* static void gethostname */
1921 #endif /* ! HAVE_GETHOSTNAME */
1928 #ifdef HAVE_X_WINDOWS
1929 /* Cause explanatory error message at compile time,
1930 since the select emulation is not good enough for X. */
1931 int *x
= &x_windows_lose_if_no_select_system_call
;
1934 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1935 * Only checks read descriptors.
1937 /* How long to wait between checking fds in select */
1938 #define SELECT_PAUSE 1
1941 /* For longjmp'ing back to read_input_waiting. */
1943 jmp_buf read_alarm_throw
;
1945 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1946 The read_socket_hook function sets this to 1 while it is waiting. */
1948 int read_alarm_should_throw
;
1956 #else /* not BSD4_1 */
1957 signal (SIGALRM
, SIG_IGN
);
1958 #endif /* not BSD4_1 */
1959 if (read_alarm_should_throw
)
1960 longjmp (read_alarm_throw
, 1);
1963 /* Only rfds are checked. */
1965 select (nfds
, rfds
, wfds
, efds
, timeout
)
1967 int *rfds
, *wfds
, *efds
, *timeout
;
1969 int ravail
= 0, orfds
= 0, old_alarm
;
1970 int timeoutval
= timeout
? *timeout
: 100000;
1971 int *local_timeout
= &timeoutval
;
1972 extern int proc_buffered_char
[];
1973 #ifndef subprocesses
1974 int process_tick
= 0, update_tick
= 0;
1976 extern int process_tick
, update_tick
;
1978 SIGTYPE (*old_trap
) ();
1991 /* If we are looking only for the terminal, with no timeout,
1992 just read it and wait -- that's more efficient. */
1993 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1995 if (! detect_input_pending ())
1996 read_input_waiting ();
2001 /* Once a second, till the timer expires, check all the flagged read
2002 * descriptors to see if any input is available. If there is some then
2003 * set the corresponding bit in the return copy of rfds.
2007 register int to_check
, bit
, fd
;
2011 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
2015 int avail
= 0, status
= 0;
2018 avail
= detect_input_pending (); /* Special keyboard handler */
2022 status
= ioctl (fd
, FIONREAD
, &avail
);
2023 #else /* no FIONREAD */
2024 /* Hoping it will return -1 if nothing available
2025 or 0 if all 0 chars requested are read. */
2026 if (proc_buffered_char
[fd
] >= 0)
2030 avail
= read (fd
, &buf
, 1);
2032 proc_buffered_char
[fd
] = buf
;
2034 #endif /* no FIONREAD */
2036 if (status
>= 0 && avail
> 0)
2044 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2046 old_alarm
= alarm (0);
2047 old_trap
= signal (SIGALRM
, select_alarm
);
2049 alarm (SELECT_PAUSE
);
2050 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2051 while (select_alarmed
== 0 && *local_timeout
!= 0
2052 && process_tick
== update_tick
)
2054 /* If we are interested in terminal input,
2055 wait by reading the terminal.
2056 That makes instant wakeup for terminal input at least. */
2059 read_input_waiting ();
2060 if (detect_input_pending ())
2066 (*local_timeout
) -= SELECT_PAUSE
;
2067 /* Reset the old alarm if there was one */
2069 signal (SIGALRM
, old_trap
);
2072 /* Reset or forge an interrupt for the original handler. */
2073 old_alarm
-= SELECT_PAUSE
;
2075 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
2079 if (*local_timeout
== 0) /* Stop on timer being cleared */
2085 /* Read keyboard input into the standard buffer,
2086 waiting for at least one character. */
2088 /* Make all keyboard buffers much bigger when using X windows. */
2089 #ifdef HAVE_X_WINDOWS
2090 #define BUFFER_SIZE_FACTOR 16
2092 #define BUFFER_SIZE_FACTOR 1
2095 read_input_waiting ()
2097 struct input_event e
;
2099 extern int quit_char
;
2101 if (read_socket_hook
)
2103 struct input_event buf
[256];
2105 read_alarm_should_throw
= 0;
2106 if (! setjmp (read_alarm_throw
))
2107 nread
= (*read_socket_hook
) (0, buf
, 256, 1, 0);
2111 /* Scan the chars for C-g and store them in kbd_buffer. */
2112 for (i
= 0; i
< nread
; i
++)
2114 kbd_buffer_store_event (&buf
[i
]);
2115 /* Don't look at input that follows a C-g too closely.
2116 This reduces lossage due to autorepeat on C-g. */
2117 if (buf
[i
].kind
== ascii_keystroke
2118 && XINT(buf
[i
].code
) == quit_char
)
2125 nread
= read (fileno (stdin
), buf
, 1);
2127 /* Scan the chars for C-g and store them in kbd_buffer. */
2128 e
.kind
= ascii_keystroke
;
2129 e
.frame_or_window
= selected_frame
;
2131 for (i
= 0; i
< nread
; i
++)
2133 /* Convert chars > 0177 to meta events if desired.
2134 We do this under the same conditions that read_avail_input does. */
2135 if (read_socket_hook
== 0)
2137 /* If the user says she has a meta key, then believe her. */
2138 if (meta_key
== 1 && (buf
[i
] & 0x80))
2139 e
.modifiers
= meta_modifier
;
2144 XSET (e
.code
, Lisp_Int
, buf
[i
]);
2145 kbd_buffer_store_event (&e
);
2146 /* Don't look at input that follows a C-g too closely.
2147 This reduces lossage due to autorepeat on C-g. */
2148 if (buf
[i
] == quit_char
)
2154 #endif /* not HAVE_SELECT */
2155 #endif /* not VMS */
2159 * Partially emulate 4.2 open call.
2160 * open is defined as this in 4.1.
2162 * - added by Michael Bloom @ Citicorp/TTI
2167 sys_open (path
, oflag
, mode
)
2171 if (oflag
& O_CREAT
)
2172 return creat (path
, mode
);
2174 return open (path
, oflag
);
2181 lmode
= LINTRUP
| lmode
;
2182 ioctl (0, TIOCLSET
, &lmode
);
2189 lmode
= ~LINTRUP
& lmode
;
2190 ioctl (0, TIOCLSET
, &lmode
);
2197 interrupts_deferred
= 0;
2204 interrupts_deferred
= 1;
2207 /* still inside #ifdef BSD4_1 */
2210 int sigheld
; /* Mask of held signals */
2215 sigheld
|= sigbit (signum
);
2222 sigheld
|= sigbit (signum
);
2228 sigheld
&= ~sigbit (signum
);
2232 sigfree () /* Free all held signals */
2235 for (i
= 0; i
< NSIG
; i
++)
2236 if (sigheld
& sigbit (i
))
2243 return 1 << (i
- 1);
2245 #endif /* subprocesses */
2248 /* POSIX signals support - DJB */
2249 /* Anyone with POSIX signals should have ANSI C declarations */
2251 #ifdef POSIX_SIGNALS
2253 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
2254 static struct sigaction new_action
, old_action
;
2258 sigemptyset (&empty_mask
);
2259 sigfillset (&full_mask
);
2263 sys_signal (int signal_number
, signal_handler_t action
)
2266 /* This gets us restartable system calls for efficiency.
2267 The "else" code will works as well. */
2268 return (berk_signal (signal_number
, action
));
2270 sigemptyset (&new_action
.sa_mask
);
2271 new_action
.sa_handler
= action
;
2272 new_action
.sa_flags
= 0;
2273 sigaction (signal_number
, &new_action
, &old_action
);
2274 return (old_action
.sa_handler
);
2279 /* If we're compiling with GCC, we don't need this function, since it
2280 can be written as a macro. */
2282 sys_sigmask (int sig
)
2285 sigemptyset (&mask
);
2286 sigaddset (&mask
, sig
);
2292 sys_sigpause (sigset_t new_mask
)
2294 /* pause emulating berk sigpause... */
2295 sigsuspend (&new_mask
);
2299 /* I'd like to have these guys return pointers to the mask storage in here,
2300 but there'd be trouble if the code was saving multiple masks. I'll be
2301 safe and pass the structure. It normally won't be more than 2 bytes
2305 sys_sigblock (sigset_t new_mask
)
2308 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2313 sys_sigunblock (sigset_t new_mask
)
2316 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2321 sys_sigsetmask (sigset_t new_mask
)
2324 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2328 #endif /* POSIX_SIGNALS */
2337 register int length
;
2341 long max_str
= 65535;
2343 while (length
> max_str
) {
2344 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2349 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2351 while (length
-- > 0)
2353 #endif /* not VMS */
2356 #endif /* no bzero */
2359 /* Saying `void' requires a declaration, above, where bcopy is used
2360 and that declaration causes pain for systems where bcopy is a macro. */
2361 bcopy (b1
, b2
, length
)
2364 register int length
;
2367 long max_str
= 65535;
2369 while (length
> max_str
) {
2370 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2376 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2378 while (length
-- > 0)
2380 #endif /* not VMS */
2382 #endif /* no bcopy */
2386 bcmp (b1
, b2
, length
) /* This could be a macro! */
2389 register int length
;
2392 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2393 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2395 return STR$
COMPARE (&src1
, &src2
);
2397 while (length
-- > 0)
2402 #endif /* not VMS */
2404 #endif /* no bcmp */
2406 #endif /* not BSTRING */
2411 * The BSD random returns numbers in the range of
2412 * 0 to 2e31 - 1. The USG rand returns numbers in the
2413 * range of 0 to 2e15 - 1. This is probably not significant
2420 /* Arrange to return a range centered on zero. */
2421 return (rand () << 15) + rand () - (1 << 29);
2435 /* Arrange to return a range centered on zero. */
2436 return (rand () << 15) + rand () - (1 << 29);
2447 #ifdef WRONG_NAME_INSQUE
2460 /* If any place else asks for the TERM variable,
2461 allow it to be overridden with the EMACS_TERM variable
2462 before attempting to translate the logical name TERM. As a last
2463 resort, ask for VAX C's special idea of the TERM variable. */
2470 static char buf
[256];
2471 static struct dsc$descriptor_s equiv
2472 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2473 static struct dsc$descriptor_s d_name
2474 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2477 if (!strcmp (name
, "TERM"))
2479 val
= (char *) getenv ("EMACS_TERM");
2484 d_name
.dsc$w_length
= strlen (name
);
2485 d_name
.dsc$a_pointer
= name
;
2486 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2488 char *str
= (char *) xmalloc (eqlen
+ 1);
2489 bcopy (buf
, str
, eqlen
);
2491 /* This is a storage leak, but a pain to fix. With luck,
2492 no one will ever notice. */
2495 return (char *) getenv (name
);
2500 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2501 to force a call on the debugger from within the image. */
2506 LIB$
SIGNAL (SS$_DEBUG
);
2512 #ifdef LINK_CRTL_SHARE
2513 #ifdef SHAREABLE_LIB_BUG
2514 /* Variables declared noshare and initialized in sharable libraries
2515 cannot be shared. The VMS linker incorrectly forces you to use a private
2516 version which is uninitialized... If not for this "feature", we
2517 could use the C library definition of sys_nerr and sys_errlist. */
2519 char *sys_errlist
[] =
2523 "no such file or directory",
2525 "interrupted system call",
2527 "no such device or address",
2528 "argument list too long",
2529 "exec format error",
2532 "no more processes",
2533 "not enough memory",
2534 "permission denied",
2536 "block device required",
2537 "mount devices busy",
2539 "cross-device link",
2544 "file table overflow",
2545 "too many open files",
2549 "no space left on device",
2551 "read-only file system",
2557 "vax/vms specific error code nontranslatable error"
2559 #endif /* SHAREABLE_LIB_BUG */
2560 #endif /* LINK_CRTL_SHARE */
2563 #ifdef INTERRUPTIBLE_OPEN
2567 sys_open (path
, oflag
, mode
)
2571 register int rtnval
;
2573 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2574 && (errno
== EINTR
));
2578 #endif /* INTERRUPTIBLE_OPEN */
2580 #ifdef INTERRUPTIBLE_CLOSE
2585 register int rtnval
;
2587 while ((rtnval
= close (fd
)) == -1
2588 && (errno
== EINTR
));
2592 #endif /* INTERRUPTIBLE_CLOSE */
2594 #ifdef INTERRUPTIBLE_IO
2597 sys_read (fildes
, buf
, nbyte
)
2602 register int rtnval
;
2604 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2605 && (errno
== EINTR
));
2610 sys_write (fildes
, buf
, nbyte
)
2615 register int rtnval
, bytes_written
;
2621 rtnval
= write (fildes
, buf
, nbyte
);
2633 bytes_written
+= rtnval
;
2635 return (bytes_written
);
2638 #endif /* INTERRUPTIBLE_IO */
2643 * Substitute fork for vfork on USG flavors.
2651 #endif /* not HAVE_VFORK */
2655 * All of the following are for USG.
2657 * On USG systems the system calls are INTERRUPTIBLE by signals
2658 * that the user program has elected to catch. Thus the system call
2659 * must be retried in these cases. To handle this without massive
2660 * changes in the source code, we remap the standard system call names
2661 * to names for our own functions in sysdep.c that do the system call
2662 * with retries. Actually, for portability reasons, it is good
2663 * programming practice, as this example shows, to limit all actual
2664 * system calls to a single occurrence in the source. Sure, this
2665 * adds an extra level of function call overhead but it is almost
2666 * always negligible. Fred Fish, Unisoft Systems Inc.
2669 #ifndef HAVE_SYS_SIGLIST
2670 char *sys_siglist
[NSIG
+ 1] =
2673 /* AIX has changed the signals a bit */
2674 "bogus signal", /* 0 */
2675 "hangup", /* 1 SIGHUP */
2676 "interrupt", /* 2 SIGINT */
2677 "quit", /* 3 SIGQUIT */
2678 "illegal instruction", /* 4 SIGILL */
2679 "trace trap", /* 5 SIGTRAP */
2680 "IOT instruction", /* 6 SIGIOT */
2681 "crash likely", /* 7 SIGDANGER */
2682 "floating point exception", /* 8 SIGFPE */
2683 "kill", /* 9 SIGKILL */
2684 "bus error", /* 10 SIGBUS */
2685 "segmentation violation", /* 11 SIGSEGV */
2686 "bad argument to system call", /* 12 SIGSYS */
2687 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2688 "alarm clock", /* 14 SIGALRM */
2689 "software termination signum", /* 15 SIGTERM */
2690 "user defined signal 1", /* 16 SIGUSR1 */
2691 "user defined signal 2", /* 17 SIGUSR2 */
2692 "death of a child", /* 18 SIGCLD */
2693 "power-fail restart", /* 19 SIGPWR */
2694 "bogus signal", /* 20 */
2695 "bogus signal", /* 21 */
2696 "bogus signal", /* 22 */
2697 "bogus signal", /* 23 */
2698 "bogus signal", /* 24 */
2699 "LAN I/O interrupt", /* 25 SIGAIO */
2700 "PTY I/O interrupt", /* 26 SIGPTY */
2701 "I/O intervention required", /* 27 SIGIOINT */
2702 "HFT grant", /* 28 SIGGRANT */
2703 "HFT retract", /* 29 SIGRETRACT */
2704 "HFT sound done", /* 30 SIGSOUND */
2705 "HFT input ready", /* 31 SIGMSG */
2707 "bogus signal", /* 0 */
2708 "hangup", /* 1 SIGHUP */
2709 "interrupt", /* 2 SIGINT */
2710 "quit", /* 3 SIGQUIT */
2711 "illegal instruction", /* 4 SIGILL */
2712 "trace trap", /* 5 SIGTRAP */
2713 "IOT instruction", /* 6 SIGIOT */
2714 "EMT instruction", /* 7 SIGEMT */
2715 "floating point exception", /* 8 SIGFPE */
2716 "kill", /* 9 SIGKILL */
2717 "bus error", /* 10 SIGBUS */
2718 "segmentation violation", /* 11 SIGSEGV */
2719 "bad argument to system call", /* 12 SIGSYS */
2720 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2721 "alarm clock", /* 14 SIGALRM */
2722 "software termination signum", /* 15 SIGTERM */
2723 "user defined signal 1", /* 16 SIGUSR1 */
2724 "user defined signal 2", /* 17 SIGUSR2 */
2725 "death of a child", /* 18 SIGCLD */
2726 "power-fail restart", /* 19 SIGPWR */
2727 #endif /* not AIX */
2730 #endif /* HAVE_SYS_SIGLIST */
2733 * Warning, this function may not duplicate 4.2 action properly
2734 * under error conditions.
2738 /* In 4.1, param.h fails to define this. */
2739 #define MAXPATHLEN 1024
2748 char *npath
, *spath
;
2749 extern char *getcwd ();
2751 BLOCK_INPUT
; /* getcwd uses malloc */
2752 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2755 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2756 up to first slash. Should be harmless on other systems. */
2757 while (*npath
&& *npath
!= '/')
2759 strcpy (pathname
, npath
);
2760 free (spath
); /* getcwd uses malloc */
2765 #endif /* HAVE_GETWD */
2768 * Emulate rename using unlink/link. Note that this is
2769 * only partially correct. Also, doesn't enforce restriction
2770 * that files be of same type (regular->regular, dir->dir, etc).
2779 if (access (from
, 0) == 0)
2782 if (link (from
, to
) == 0)
2783 if (unlink (from
) == 0)
2791 #ifdef MISSING_UTIMES
2793 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2802 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2803 utimbuf structure defined anywhere but in the man page. */
2813 struct timeval tvp
[];
2816 utb
.actime
= tvp
[0].tv_sec
;
2817 utb
.modtime
= tvp
[1].tv_sec
;
2820 #endif /* IRIS_UTIME */
2826 /* HPUX curses library references perror, but as far as we know
2827 it won't be called. Anyway this definition will do for now. */
2833 #endif /* not HAVE_PERROR */
2839 * Emulate BSD dup2. First close newd if it already exists.
2840 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2841 * until we are, then close the unsuccessful ones.
2848 register int fd
, ret
;
2853 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2855 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2862 ret
= dup2 (old
,new);
2868 #endif /* not HAVE_DUP2 */
2871 * Gettimeofday. Simulate as much as possible. Only accurate
2872 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2873 * Only needed when subprocesses are defined.
2878 #ifndef HAVE_GETTIMEOFDAY
2882 gettimeofday (tp
, tzp
)
2884 struct timezone
*tzp
;
2886 extern long time ();
2888 tp
->tv_sec
= time ((long *)0);
2891 tzp
->tz_minuteswest
= -1;
2897 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2900 * This function will go away as soon as all the stubs fixed. (fnf)
2906 printf ("%s not yet implemented\r\n", badfunc
);
2915 char *sys_siglist
[NSIG
+ 1] =
2917 "null signal", /* 0 SIGNULL */
2918 "hangup", /* 1 SIGHUP */
2919 "interrupt", /* 2 SIGINT */
2920 "quit", /* 3 SIGQUIT */
2921 "illegal instruction", /* 4 SIGILL */
2922 "trace trap", /* 5 SIGTRAP */
2923 "abort termination", /* 6 SIGABRT */
2924 "SIGEMT", /* 7 SIGEMT */
2925 "floating point exception", /* 8 SIGFPE */
2926 "kill", /* 9 SIGKILL */
2927 "bus error", /* 10 SIGBUS */
2928 "segmentation violation", /* 11 SIGSEGV */
2929 "bad argument to system call", /* 12 SIGSYS */
2930 "write on a pipe with no reader", /* 13 SIGPIPE */
2931 "alarm clock", /* 14 SIGALRM */
2932 "software termination signal", /* 15 SIGTERM */
2933 "user defined signal 1", /* 16 SIGUSR1 */
2934 "user defined signal 2", /* 17 SIGUSR2 */
2935 "child stopped or terminated", /* 18 SIGCLD */
2936 "power-fail restart", /* 19 SIGPWR */
2937 "window size changed", /* 20 SIGWINCH */
2938 "undefined", /* 21 */
2939 "pollable event occurred", /* 22 SIGPOLL */
2940 "sendable stop signal not from tty", /* 23 SIGSTOP */
2941 "stop signal from tty", /* 24 SIGSTP */
2942 "continue a stopped process", /* 25 SIGCONT */
2943 "attempted background tty read", /* 26 SIGTTIN */
2944 "attempted background tty write", /* 27 SIGTTOU */
2945 "undefined", /* 28 */
2946 "undefined", /* 29 */
2947 "undefined", /* 30 */
2948 "undefined", /* 31 */
2949 "undefined", /* 32 */
2950 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2951 "I/O is possible", /* 34 SIGIO */
2952 "exceeded cpu time limit", /* 35 SIGXCPU */
2953 "exceeded file size limit", /* 36 SIGXFSZ */
2954 "virtual time alarm", /* 37 SIGVTALRM */
2955 "profiling time alarm", /* 38 SIGPROF */
2956 "undefined", /* 39 */
2957 "file record locks revoked", /* 40 SIGLOST */
2958 "undefined", /* 41 */
2959 "undefined", /* 42 */
2960 "undefined", /* 43 */
2961 "undefined", /* 44 */
2962 "undefined", /* 45 */
2963 "undefined", /* 46 */
2964 "undefined", /* 47 */
2965 "undefined", /* 48 */
2966 "undefined", /* 49 */
2967 "undefined", /* 50 */
2968 "undefined", /* 51 */
2969 "undefined", /* 52 */
2970 "undefined", /* 53 */
2971 "undefined", /* 54 */
2972 "undefined", /* 55 */
2973 "undefined", /* 56 */
2974 "undefined", /* 57 */
2975 "undefined", /* 58 */
2976 "undefined", /* 59 */
2977 "undefined", /* 60 */
2978 "undefined", /* 61 */
2979 "undefined", /* 62 */
2980 "undefined", /* 63 */
2981 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2987 /* Directory routines for systems that don't have them. */
2989 #ifdef SYSV_SYSTEM_DIR
2993 #if defined(BROKEN_CLOSEDIR) || !defined(HAVE_CLOSEDIR)
2997 register DIR *dirp
; /* stream from opendir */
3001 rtnval
= sys_close (dirp
->dd_fd
);
3003 /* Some systems (like Solaris) allocate the buffer and the DIR all
3004 in one block. Why in the world are we freeing this ourselves
3006 #if ! (defined (sun) && defined (USG5_4))
3007 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
3009 xfree ((char *) dirp
);
3013 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3014 #endif /* SYSV_SYSTEM_DIR */
3016 #ifdef NONSYSTEM_DIR_LIBRARY
3020 char *filename
; /* name of directory */
3022 register DIR *dirp
; /* -> malloc'ed storage */
3023 register int fd
; /* file descriptor for read */
3024 struct stat sbuf
; /* result of fstat */
3026 fd
= sys_open (filename
, 0);
3031 if (fstat (fd
, &sbuf
) < 0
3032 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
3033 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
3037 return 0; /* bad luck today */
3042 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
3049 register DIR *dirp
; /* stream from opendir */
3051 sys_close (dirp
->dd_fd
);
3052 xfree ((char *) dirp
);
3060 ino_t od_ino
; /* inode */
3061 char od_name
[DIRSIZ
]; /* filename */
3063 #endif /* not VMS */
3065 struct direct dir_static
; /* simulated directory contents */
3070 register DIR *dirp
; /* stream from opendir */
3073 register struct olddir
*dp
; /* -> directory data */
3075 register struct dir$_name
*dp
; /* -> directory data */
3076 register struct dir$_version
*dv
; /* -> version data */
3081 if (dirp
->dd_loc
>= dirp
->dd_size
)
3082 dirp
->dd_loc
= dirp
->dd_size
= 0;
3084 if (dirp
->dd_size
== 0 /* refill buffer */
3085 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3089 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3090 dirp
->dd_loc
+= sizeof (struct olddir
);
3092 if (dp
->od_ino
!= 0) /* not deleted entry */
3094 dir_static
.d_ino
= dp
->od_ino
;
3095 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3096 dir_static
.d_name
[DIRSIZ
] = '\0';
3097 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3098 dir_static
.d_reclen
= sizeof (struct direct
)
3100 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3101 return &dir_static
; /* -> simulated structure */
3104 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3105 if (dirp
->dd_loc
== 0)
3106 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3107 : dp
->dir$b_namecount
;
3108 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3109 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3110 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3111 dir_static
.d_reclen
= sizeof (struct direct
)
3113 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3114 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3115 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3116 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3123 /* readdirver is just like readdir except it returns all versions of a file
3124 as separate entries. */
3129 register DIR *dirp
; /* stream from opendir */
3131 register struct dir$_name
*dp
; /* -> directory data */
3132 register struct dir$_version
*dv
; /* -> version data */
3134 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3135 dirp
->dd_loc
= dirp
->dd_size
= 0;
3137 if (dirp
->dd_size
== 0 /* refill buffer */
3138 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3141 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3142 if (dirp
->dd_loc
== 0)
3143 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3144 : dp
->dir$b_namecount
;
3145 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3146 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3147 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3148 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3149 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3150 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3151 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3152 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3158 #endif /* NONSYSTEM_DIR_LIBRARY */
3161 /* mkdir and rmdir functions, for systems which don't have them. */
3165 * Written by Robert Rother, Mariah Corporation, August 1985.
3167 * If you want it, it's yours. All I ask in return is that if you
3168 * figure out how to do this in a Bourne Shell script you send me
3170 * sdcsvax!rmr or rmr@uscd
3172 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3173 * subroutine. 11Mar86; hoptoad!gnu
3175 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3176 * subroutine didn't return EEXIST. It does now.
3183 mkdir (dpath
, dmode
)
3187 int cpid
, status
, fd
;
3188 struct stat statbuf
;
3190 if (stat (dpath
, &statbuf
) == 0)
3192 errno
= EEXIST
; /* Stat worked, so it already exists */
3196 /* If stat fails for a reason other than non-existence, return error */
3197 if (errno
!= ENOENT
)
3200 synch_process_alive
= 1;
3201 switch (cpid
= fork ())
3204 case -1: /* Error in fork */
3205 return (-1); /* Errno is set already */
3207 case 0: /* Child process */
3209 * Cheap hack to set mode of new directory. Since this
3210 * child process is going away anyway, we zap its umask.
3211 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3212 * directory. Does anybody care?
3214 status
= umask (0); /* Get current umask */
3215 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3216 fd
= sys_open("/dev/null", 2);
3223 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3224 _exit (-1); /* Can't exec /bin/mkdir */
3226 default: /* Parent process */
3227 wait_for_termination (cpid
);
3230 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3232 errno
= EIO
; /* We don't know why, but */
3233 return -1; /* /bin/mkdir failed */
3238 #endif /* not HAVE_MKDIR */
3245 int cpid
, status
, fd
;
3246 struct stat statbuf
;
3248 if (stat (dpath
, &statbuf
) != 0)
3250 /* Stat just set errno. We don't have to */
3254 synch_process_alive
= 1;
3255 switch (cpid
= fork ())
3258 case -1: /* Error in fork */
3259 return (-1); /* Errno is set already */
3261 case 0: /* Child process */
3262 fd
= sys_open("/dev/null", 2);
3269 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
3270 _exit (-1); /* Can't exec /bin/mkdir */
3272 default: /* Parent process */
3273 wait_for_termination (cpid
);
3276 if (synch_process_death
!= 0 || synch_process_retcode
!= 0)
3278 errno
= EIO
; /* We don't know why, but */
3279 return -1; /* /bin/rmdir failed */
3284 #endif /* !HAVE_RMDIR */
3288 /* Functions for VMS */
3290 #include "vms-pwd.h"
3295 /* Return as a string the VMS error string pertaining to STATUS.
3296 Reuses the same static buffer each time it is called. */
3300 int status
; /* VMS status code */
3304 static char buf
[257];
3306 bufadr
[0] = sizeof buf
- 1;
3307 bufadr
[1] = (int) buf
;
3308 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3309 return "untranslatable VMS error status";
3317 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3318 * not work correctly. (It also doesn't work well in version 2.3.)
3323 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3324 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3328 unsigned short s_buflen
;
3329 unsigned short s_code
;
3331 unsigned short *s_retlenadr
;
3335 #define buflen s.s_buflen
3336 #define code s.s_code
3337 #define bufadr s.s_bufadr
3338 #define retlenadr s.s_retlenadr
3340 #define R_OK 4 /* test for read permission */
3341 #define W_OK 2 /* test for write permission */
3342 #define X_OK 1 /* test for execute (search) permission */
3343 #define F_OK 0 /* test for presence of file */
3346 sys_access (path
, mode
)
3350 static char *user
= NULL
;
3353 /* translate possible directory spec into .DIR file name, so brain-dead
3354 * access can treat the directory like a file. */
3355 if (directory_file_name (path
, dir_fn
))
3359 return access (path
, mode
);
3360 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3366 unsigned short int dummy
;
3368 static int constant
= ACL$C_FILE
;
3369 DESCRIPTOR (path_desc
, path
);
3370 DESCRIPTOR (user_desc
, user
);
3374 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3377 acces
|= CHP$M_READ
;
3379 acces
|= CHP$M_WRITE
;
3380 itemlst
[0].buflen
= sizeof (int);
3381 itemlst
[0].code
= CHP$_FLAGS
;
3382 itemlst
[0].bufadr
= (char *) &flags
;
3383 itemlst
[0].retlenadr
= &dummy
;
3384 itemlst
[1].buflen
= sizeof (int);
3385 itemlst
[1].code
= CHP$_ACCESS
;
3386 itemlst
[1].bufadr
= (char *) &acces
;
3387 itemlst
[1].retlenadr
= &dummy
;
3388 itemlst
[2].end
= CHP$_END
;
3389 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3390 return stat
== SS$_NORMAL
? 0 : -1;
3394 #else /* not VMS4_4 */
3397 #define ACE$M_WRITE 2
3398 #define ACE$C_KEYID 1
3400 static unsigned short memid
, grpid
;
3401 static unsigned int uic
;
3403 /* Called from init_sys_modes, so it happens not very often
3404 but at least each time Emacs is loaded. */
3405 sys_access_reinit ()
3411 sys_access (filename
, type
)
3417 int status
, size
, i
, typecode
, acl_controlled
;
3418 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3419 union prvdef prvmask
;
3421 /* Get UIC and GRP values for protection checking. */
3424 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3427 memid
= uic
& 0xFFFF;
3431 if (type
!= 2) /* not checking write access */
3432 return access (filename
, type
);
3434 /* Check write protection. */
3436 #define CHECKPRIV(bit) (prvmask.bit)
3437 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3439 /* Find privilege bits */
3440 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3442 error ("Unable to find privileges: %s", vmserrstr (status
));
3443 if (CHECKPRIV (PRV$V_BYPASS
))
3444 return 0; /* BYPASS enabled */
3446 fab
.fab$b_fac
= FAB$M_GET
;
3447 fab
.fab$l_fna
= filename
;
3448 fab
.fab$b_fns
= strlen (filename
);
3449 fab
.fab$l_xab
= &xab
;
3450 xab
= cc$rms_xabpro
;
3451 xab
.xab$l_aclbuf
= aclbuf
;
3452 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3453 status
= SYS$
OPEN (&fab
, 0, 0);
3456 SYS$
CLOSE (&fab
, 0, 0);
3457 /* Check system access */
3458 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
3460 /* Check ACL entries, if any */
3462 if (xab
.xab$w_acllen
> 0)
3465 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3466 while (*aclptr
&& aclptr
< aclend
)
3468 size
= (*aclptr
& 0xff) / 4;
3469 typecode
= (*aclptr
>> 8) & 0xff;
3470 if (typecode
== ACE$C_KEYID
)
3471 for (i
= size
- 1; i
> 1; i
--)
3472 if (aclptr
[i
] == uic
)
3475 if (aclptr
[1] & ACE$M_WRITE
)
3476 return 0; /* Write access through ACL */
3478 aclptr
= &aclptr
[size
];
3480 if (acl_controlled
) /* ACL specified, prohibits write access */
3483 /* No ACL entries specified, check normal protection */
3484 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3486 if (WRITEABLE (XAB$V_GRP
) &&
3487 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3488 return 0; /* Group writeable */
3489 if (WRITEABLE (XAB$V_OWN
) &&
3490 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3491 return 0; /* Owner writeable */
3493 return -1; /* Not writeable */
3495 #endif /* not VMS4_4 */
3498 static char vtbuf
[NAM$C_MAXRSS
+1];
3500 /* translate a vms file spec to a unix path */
3502 sys_translate_vms (vfile
)
3513 /* leading device or logical name is a root directory */
3514 if (p
= strchr (vfile
, ':'))
3523 if (*p
== '[' || *p
== '<')
3525 while (*++vfile
!= *p
+ 2)
3529 if (vfile
[-1] == *p
)
3552 static char utbuf
[NAM$C_MAXRSS
+1];
3554 /* translate a unix path to a VMS file spec */
3556 sys_translate_unix (ufile
)
3579 if (index (&ufile
[1], '/'))
3586 if (index (&ufile
[1], '/'))
3593 if (strncmp (ufile
, "./", 2) == 0)
3600 ufile
++; /* skip the dot */
3601 if (index (&ufile
[1], '/'))
3606 else if (strncmp (ufile
, "../", 3) == 0)
3614 ufile
+= 2; /* skip the dots */
3615 if (index (&ufile
[1], '/'))
3640 extern char *getcwd ();
3642 #define MAXPATHLEN 1024
3644 ptr
= xmalloc (MAXPATHLEN
);
3645 val
= getcwd (ptr
, MAXPATHLEN
);
3651 strcpy (pathname
, ptr
);
3659 long item_code
= JPI$_OWNER
;
3660 unsigned long parent_id
;
3663 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3666 vaxc$errno
= status
;
3676 return (getgid () << 16) | getuid ();
3680 sys_read (fildes
, buf
, nbyte
)
3685 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3690 sys_write (fildes
, buf
, nbyte
)
3695 register int nwrote
, rtnval
= 0;
3697 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3703 return rtnval
? rtnval
: -1;
3704 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3705 return rtnval
? rtnval
: -1;
3706 return (rtnval
+ nwrote
);
3711 * VAX/VMS VAX C RTL really loses. It insists that records
3712 * end with a newline (carriage return) character, and if they
3713 * don't it adds one (nice of it isn't it!)
3715 * Thus we do this stupidity below.
3719 sys_write (fildes
, buf
, nbytes
)
3722 unsigned int nbytes
;
3729 fstat (fildes
, &st
);
3735 /* Handle fixed-length files with carriage control. */
3736 if (st
.st_fab_rfm
== FAB$C_FIX
3737 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3739 len
= st
.st_fab_mrs
;
3740 retval
= write (fildes
, p
, min (len
, nbytes
));
3743 retval
++; /* This skips the implied carriage control */
3747 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3748 while (*e
!= '\n' && e
> p
) e
--;
3749 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3750 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3752 retval
= write (fildes
, p
, len
);
3763 /* Create file NEW copying its attributes from file OLD. If
3764 OLD is 0 or does not exist, create based on the value of
3767 /* Protection value the file should ultimately have.
3768 Set by create_copy_attrs, and use by rename_sansversions. */
3769 static unsigned short int fab_final_pro
;
3772 creat_copy_attrs (old
, new)
3775 struct FAB fab
= cc$rms_fab
;
3776 struct XABPRO xabpro
;
3777 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3778 extern int vms_stmlf_recfm
;
3782 fab
.fab$b_fac
= FAB$M_GET
;
3783 fab
.fab$l_fna
= old
;
3784 fab
.fab$b_fns
= strlen (old
);
3785 fab
.fab$l_xab
= (char *) &xabpro
;
3786 xabpro
= cc$rms_xabpro
;
3787 xabpro
.xab$l_aclbuf
= aclbuf
;
3788 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3789 /* Call $OPEN to fill in the fab & xabpro fields. */
3790 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3792 SYS$
CLOSE (&fab
, 0, 0);
3793 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3794 if (xabpro
.xab$w_acllen
> 0)
3796 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3797 /* If the acl buffer was too short, redo open with longer one.
3798 Wouldn't need to do this if there were some system imposed
3799 limit on the size of an ACL, but I can't find any such. */
3801 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3802 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3803 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3804 SYS$
CLOSE (&fab
, 0, 0);
3810 xabpro
.xab$l_aclbuf
= 0;
3815 fab
.fab$l_fna
= new;
3816 fab
.fab$b_fns
= strlen (new);
3820 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3821 fab
.fab$b_rat
= FAB$M_CR
;
3824 /* Set the file protections such that we will be able to manipulate
3825 this file. Once we are done writing and renaming it, we will set
3826 the protections back. */
3828 fab_final_pro
= xabpro
.xab$w_pro
;
3830 SYS$
SETDFPROT (0, &fab_final_pro
);
3831 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3833 /* Create the new file with either default attrs or attrs copied
3835 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3837 SYS$
CLOSE (&fab
, 0, 0);
3838 /* As this is a "replacement" for creat, return a file descriptor
3839 opened for writing. */
3840 return open (new, O_WRONLY
);
3845 #include <varargs.h>
3848 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3852 sys_creat (va_alist
)
3855 va_list list_incrementer
;
3858 int rfd
; /* related file descriptor */
3859 int fd
; /* Our new file descriptor */
3866 extern int vms_stmlf_recfm
;
3869 va_start (list_incrementer
);
3870 name
= va_arg (list_incrementer
, char *);
3871 mode
= va_arg (list_incrementer
, int);
3873 rfd
= va_arg (list_incrementer
, int);
3874 va_end (list_incrementer
);
3877 /* Use information from the related file descriptor to set record
3878 format of the newly created file. */
3879 fstat (rfd
, &st_buf
);
3880 switch (st_buf
.st_fab_rfm
)
3883 strcpy (rfm
, "rfm = fix");
3884 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3885 strcpy (rat
, "rat = ");
3886 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3888 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3889 strcat (rat
, "ftn");
3890 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3891 strcat (rat
, "prn");
3892 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3893 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3894 strcat (rat
, ", blk");
3896 strcat (rat
, "blk");
3897 return creat (name
, 0, rfm
, rat
, mrs
);
3900 strcpy (rfm
, "rfm = vfc");
3901 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3902 strcpy (rat
, "rat = ");
3903 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3905 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3906 strcat (rat
, "ftn");
3907 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3908 strcat (rat
, "prn");
3909 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3910 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3911 strcat (rat
, ", blk");
3913 strcat (rat
, "blk");
3914 return creat (name
, 0, rfm
, rat
, fsz
);
3917 strcpy (rfm
, "rfm = stm");
3921 strcpy (rfm
, "rfm = stmcr");
3925 strcpy (rfm
, "rfm = stmlf");
3929 strcpy (rfm
, "rfm = udf");
3933 strcpy (rfm
, "rfm = var");
3936 strcpy (rat
, "rat = ");
3937 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3939 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3940 strcat (rat
, "ftn");
3941 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3942 strcat (rat
, "prn");
3943 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3944 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3945 strcat (rat
, ", blk");
3947 strcat (rat
, "blk");
3951 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3952 strcpy (rat
, "rat=cr");
3954 /* Until the VAX C RTL fixes the many bugs with modes, always use
3955 mode 0 to get the user's default protection. */
3956 fd
= creat (name
, 0, rfm
, rat
);
3957 if (fd
< 0 && errno
== EEXIST
)
3959 if (unlink (name
) < 0)
3960 report_file_error ("delete", build_string (name
));
3961 fd
= creat (name
, 0, rfm
, rat
);
3967 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3968 sys_fwrite (ptr
, size
, num
, fp
)
3969 register char * ptr
;
3972 register int tot
= num
* size
;
3979 * The VMS C library routine creat actually creates a new version of an
3980 * existing file rather than truncating the old version. There are times
3981 * when this is not the desired behavior, for instance, when writing an
3982 * auto save file (you only want one version), or when you don't have
3983 * write permission in the directory containing the file (but the file
3984 * itself is writable). Hence this routine, which is equivalent to
3985 * "close (creat (fn, 0));" on Unix if fn already exists.
3991 struct FAB xfab
= cc$rms_fab
;
3992 struct RAB xrab
= cc$rms_rab
;
3995 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3996 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3997 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3998 xfab
.fab$l_fna
= fn
;
3999 xfab
.fab$b_fns
= strlen (fn
);
4000 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
4002 xrab
.rab$l_fab
= &xfab
;
4004 /* This gibberish opens the file, positions to the first record, and
4005 deletes all records from there until the end of file. */
4006 if ((SYS$
OPEN (&xfab
) & 01) == 01)
4008 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
4009 (SYS$
FIND (&xrab
) & 01) == 01 &&
4010 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
4021 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4022 SYSPRV or a readable SYSUAF.DAT. */
4028 * Routine to read the VMS User Authorization File and return
4029 * a specific user's record.
4032 static struct UAF retuaf
;
4035 get_uaf_name (uname
)
4042 uaf_fab
= cc$rms_fab
;
4043 uaf_rab
= cc$rms_rab
;
4044 /* initialize fab fields */
4045 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4046 uaf_fab
.fab$b_fns
= 21;
4047 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4048 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4049 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4050 /* initialize rab fields */
4051 uaf_rab
.rab$l_fab
= &uaf_fab
;
4052 /* open the User Authorization File */
4053 status
= SYS$
OPEN (&uaf_fab
);
4057 vaxc$errno
= status
;
4060 status
= SYS$
CONNECT (&uaf_rab
);
4064 vaxc$errno
= status
;
4067 /* read the requested record - index is in uname */
4068 uaf_rab
.rab$l_kbf
= uname
;
4069 uaf_rab
.rab$b_ksz
= strlen (uname
);
4070 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4071 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4072 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4073 status
= SYS$
GET (&uaf_rab
);
4077 vaxc$errno
= status
;
4080 /* close the User Authorization File */
4081 status
= SYS$
DISCONNECT (&uaf_rab
);
4085 vaxc$errno
= status
;
4088 status
= SYS$
CLOSE (&uaf_fab
);
4092 vaxc$errno
= status
;
4106 uaf_fab
= cc$rms_fab
;
4107 uaf_rab
= cc$rms_rab
;
4108 /* initialize fab fields */
4109 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4110 uaf_fab
.fab$b_fns
= 21;
4111 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4112 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4113 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4114 /* initialize rab fields */
4115 uaf_rab
.rab$l_fab
= &uaf_fab
;
4116 /* open the User Authorization File */
4117 status
= SYS$
OPEN (&uaf_fab
);
4121 vaxc$errno
= status
;
4124 status
= SYS$
CONNECT (&uaf_rab
);
4128 vaxc$errno
= status
;
4131 /* read the requested record - index is in uic */
4132 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4133 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4134 uaf_rab
.rab$b_ksz
= sizeof uic
;
4135 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4136 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4137 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4138 status
= SYS$
GET (&uaf_rab
);
4142 vaxc$errno
= status
;
4145 /* close the User Authorization File */
4146 status
= SYS$
DISCONNECT (&uaf_rab
);
4150 vaxc$errno
= status
;
4153 status
= SYS$
CLOSE (&uaf_fab
);
4157 vaxc$errno
= status
;
4163 static struct passwd retpw
;
4171 /* copy these out first because if the username is 32 chars, the next
4172 section will overwrite the first byte of the UIC */
4173 retpw
.pw_uid
= up
->uaf$w_mem
;
4174 retpw
.pw_gid
= up
->uaf$w_grp
;
4176 /* I suppose this is not the best sytle, to possibly overwrite one
4177 byte beyond the end of the field, but what the heck... */
4178 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4179 while (ptr
[-1] == ' ')
4182 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4184 /* the rest of these are counted ascii strings */
4185 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4186 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4187 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4188 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4189 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4190 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4191 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4192 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4196 #else /* not READ_SYSUAF */
4197 static struct passwd retpw
;
4198 #endif /* not READ_SYSUAF */
4209 unsigned char * full
;
4210 #endif /* READ_SYSUAF */
4215 if ('a' <= *ptr
&& *ptr
<= 'z')
4220 if (!(up
= get_uaf_name (name
)))
4222 return cnv_uaf_pw (up
);
4224 if (strcmp (name
, getenv ("USER")) == 0)
4226 retpw
.pw_uid
= getuid ();
4227 retpw
.pw_gid
= getgid ();
4228 strcpy (retpw
.pw_name
, name
);
4229 if (full
= egetenv ("FULLNAME"))
4230 strcpy (retpw
.pw_gecos
, full
);
4232 *retpw
.pw_gecos
= '\0';
4233 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4234 *retpw
.pw_shell
= '\0';
4239 #endif /* not READ_SYSUAF */
4249 if (!(up
= get_uaf_uic (uid
)))
4251 return cnv_uaf_pw (up
);
4253 if (uid
== sys_getuid ())
4254 return getpwnam (egetenv ("USER"));
4257 #endif /* not READ_SYSUAF */
4260 /* return total address space available to the current process. This is
4261 the sum of the current p0 size, p1 size and free page table entries
4266 unsigned long free_pages
;
4267 unsigned long frep0va
;
4268 unsigned long frep1va
;
4271 item_code
= JPI$_FREPTECNT
;
4272 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4275 vaxc$errno
= status
;
4280 item_code
= JPI$_FREP0VA
;
4281 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4284 vaxc$errno
= status
;
4287 item_code
= JPI$_FREP1VA
;
4288 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4291 vaxc$errno
= status
;
4295 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4298 define_logical_name (varname
, string
)
4302 struct dsc$descriptor_s strdsc
=
4303 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4304 struct dsc$descriptor_s envdsc
=
4305 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4306 struct dsc$descriptor_s lnmdsc
=
4307 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4309 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4312 delete_logical_name (varname
)
4315 struct dsc$descriptor_s envdsc
=
4316 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4317 struct dsc$descriptor_s lnmdsc
=
4318 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4320 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4331 error ("execvp system call not implemented");
4339 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4340 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4341 char from_esn
[NAM$C_MAXRSS
];
4342 char to_esn
[NAM$C_MAXRSS
];
4344 from_fab
.fab$l_fna
= from
;
4345 from_fab
.fab$b_fns
= strlen (from
);
4346 from_fab
.fab$l_nam
= &from_nam
;
4347 from_fab
.fab$l_fop
= FAB$M_NAM
;
4349 from_nam
.nam$l_esa
= from_esn
;
4350 from_nam
.nam$b_ess
= sizeof from_esn
;
4352 to_fab
.fab$l_fna
= to
;
4353 to_fab
.fab$b_fns
= strlen (to
);
4354 to_fab
.fab$l_nam
= &to_nam
;
4355 to_fab
.fab$l_fop
= FAB$M_NAM
;
4357 to_nam
.nam$l_esa
= to_esn
;
4358 to_nam
.nam$b_ess
= sizeof to_esn
;
4360 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4366 if (status
== RMS$_DEV
)
4370 vaxc$errno
= status
;
4375 /* This function renames a file like `rename', but it strips
4376 the version number from the "to" filename, such that the "to" file is
4377 will always be a new version. It also sets the file protection once it is
4378 finished. The protection that we will use is stored in fab_final_pro,
4379 and was set when we did a creat_copy_attrs to create the file that we
4382 We could use the chmod function, but Eunichs uses 3 bits per user category
4383 to describe the protection, and VMS uses 4 (write and delete are separate
4384 bits). To maintain portability, the VMS implementation of `chmod' wires
4385 the W and D bits together. */
4388 static struct fibdef fib
; /* We need this initialized to zero */
4389 char vms_file_written
[NAM$C_MAXRSS
];
4392 rename_sans_version (from
,to
)
4399 struct FAB to_fab
= cc$rms_fab
;
4400 struct NAM to_nam
= cc$rms_nam
;
4401 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4402 struct dsc$descriptor fib_attr
[2]
4403 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4404 char to_esn
[NAM$C_MAXRSS
];
4406 $
DESCRIPTOR (disk
,to_esn
);
4408 to_fab
.fab$l_fna
= to
;
4409 to_fab
.fab$b_fns
= strlen (to
);
4410 to_fab
.fab$l_nam
= &to_nam
;
4411 to_fab
.fab$l_fop
= FAB$M_NAM
;
4413 to_nam
.nam$l_esa
= to_esn
;
4414 to_nam
.nam$b_ess
= sizeof to_esn
;
4416 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4418 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4419 *(to_nam
.nam$l_ver
) = '\0';
4421 stat
= rename (from
, to_esn
);
4425 strcpy (vms_file_written
, to_esn
);
4427 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4428 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4430 /* Now set the file protection to the correct value */
4431 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4433 /* Copy these fields into the fib */
4434 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4435 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4436 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4438 SYS$
CLOSE (&to_fab
, 0, 0);
4440 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4443 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4444 0, 0, 0, &fib_attr
, 0);
4447 stat
= SYS$
DASSGN (chan
);
4450 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4460 unsigned short fid
[3];
4461 char esa
[NAM$C_MAXRSS
];
4464 fab
.fab$l_fop
= FAB$M_OFP
;
4465 fab
.fab$l_fna
= file
;
4466 fab
.fab$b_fns
= strlen (file
);
4467 fab
.fab$l_nam
= &nam
;
4470 nam
.nam$l_esa
= esa
;
4471 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4473 status
= SYS$
PARSE (&fab
);
4474 if ((status
& 1) == 0)
4477 vaxc$errno
= status
;
4480 status
= SYS$
SEARCH (&fab
);
4481 if ((status
& 1) == 0)
4484 vaxc$errno
= status
;
4488 fid
[0] = nam
.nam$w_fid
[0];
4489 fid
[1] = nam
.nam$w_fid
[1];
4490 fid
[2] = nam
.nam$w_fid
[2];
4492 fab
.fab$l_fna
= new;
4493 fab
.fab$b_fns
= strlen (new);
4495 status
= SYS$
PARSE (&fab
);
4496 if ((status
& 1) == 0)
4499 vaxc$errno
= status
;
4503 nam
.nam$w_fid
[0] = fid
[0];
4504 nam
.nam$w_fid
[1] = fid
[1];
4505 nam
.nam$w_fid
[2] = fid
[2];
4507 nam
.nam$l_esa
= nam
.nam$l_name
;
4508 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4510 status
= SYS$
ENTER (&fab
);
4511 if ((status
& 1) == 0)
4514 vaxc$errno
= status
;
4524 printf ("%s not yet implemented\r\n", badfunc
);
4532 /* Arrange to return a range centered on zero. */
4533 return rand () - (1 << 30);
4544 /* Called from init_sys_modes. */
4549 /* If we're not on an HFT we shouldn't do any of this. We determine
4550 if we are on an HFT by trying to get an HFT error code. If this
4551 call fails, we're not on an HFT. */
4553 if (ioctl (0, HFQERROR
, &junk
) < 0)
4555 #else /* not IBMR2AIX */
4556 if (ioctl (0, HFQEIO
, 0) < 0)
4558 #endif /* not IBMR2AIX */
4560 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4561 as the rubout key's ASCII code. Here this is changed. The bug is that
4562 there's no way to determine the old mapping, so in reset_sys_modes
4563 we need to assume that the normal map had been present. Of course, this
4564 code also doesn't help if on a terminal emulator which doesn't understand
4568 struct hfkeymap keymap
;
4570 buf
.hf_bufp
= (char *)&keymap
;
4571 buf
.hf_buflen
= sizeof (keymap
);
4572 keymap
.hf_nkeys
= 2;
4573 keymap
.hfkey
[0].hf_kpos
= 15;
4574 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4576 keymap
.hfkey
[0].hf_keyidh
= '<';
4577 #else /* not IBMR2AIX */
4578 keymap
.hfkey
[0].hf_page
= '<';
4579 #endif /* not IBMR2AIX */
4580 keymap
.hfkey
[0].hf_char
= 127;
4581 keymap
.hfkey
[1].hf_kpos
= 15;
4582 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4584 keymap
.hfkey
[1].hf_keyidh
= '<';
4585 #else /* not IBMR2AIX */
4586 keymap
.hfkey
[1].hf_page
= '<';
4587 #endif /* not IBMR2AIX */
4588 keymap
.hfkey
[1].hf_char
= 127;
4589 hftctl (0, HFSKBD
, &buf
);
4591 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4593 line_ins_del_ok
= char_ins_del_ok
= 0;
4596 /* Reset the rubout key to backspace. */
4601 struct hfkeymap keymap
;
4605 if (ioctl (0, HFQERROR
, &junk
) < 0)
4607 #else /* not IBMR2AIX */
4608 if (ioctl (0, HFQEIO
, 0) < 0)
4610 #endif /* not IBMR2AIX */
4612 buf
.hf_bufp
= (char *)&keymap
;
4613 buf
.hf_buflen
= sizeof (keymap
);
4614 keymap
.hf_nkeys
= 2;
4615 keymap
.hfkey
[0].hf_kpos
= 15;
4616 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4618 keymap
.hfkey
[0].hf_keyidh
= '<';
4619 #else /* not IBMR2AIX */
4620 keymap
.hfkey
[0].hf_page
= '<';
4621 #endif /* not IBMR2AIX */
4622 keymap
.hfkey
[0].hf_char
= 8;
4623 keymap
.hfkey
[1].hf_kpos
= 15;
4624 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4626 keymap
.hfkey
[1].hf_keyidh
= '<';
4627 #else /* not IBMR2AIX */
4628 keymap
.hfkey
[1].hf_page
= '<';
4629 #endif /* not IBMR2AIX */
4630 keymap
.hfkey
[1].hf_char
= 8;
4631 hftctl (0, HFSKBD
, &buf
);