1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include "blockinput.h"
29 #define min(x,y) ((x) > (y) ? (y) : (x))
31 /* In this file, open, read and write refer to the system calls,
32 not our sugared interfaces sys_open, sys_read and sys_write.
33 Contrariwise, for systems where we use the system calls directly,
34 define sys_read, etc. here as aliases for them. */
37 #define sys_write write
38 #endif /* `read' is not a macro */
44 #define sys_close close
51 #else /* `open' is a macro */
53 #endif /* `open' is a macro */
55 /* Does anyone other than VMS need this? */
57 #define sys_fwrite fwrite
63 #include <sys/types.h>
69 extern char *sys_errlist
[];
92 #define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */
96 #ifdef BSD /* this is done this way to avoid defined (BSD) || defined (USG)
97 because the vms compiler doesn't grok `defined' */
105 #endif /* not 4.1 bsd */
108 /* On some systems (DGUX comes to mind real fast) FASYNC causes
109 background writes to the terminal to stop all processes in the
110 process group when invoked under the csh (and probably any shell
111 with job control). This stops Emacs dead in its tracks when coming
116 #include <sys/ioctl.h>
123 #include <sys/wait.h>
127 #ifdef BROKEN_TIOCGWINSZ
132 #include <sys/utsname.h>
134 #ifndef MEMORY_IN_STRING_H
139 #include <sys/sioctl.h>
142 #include <sys/stream.h>
143 #include <sys/ptem.h>
145 #endif /* TIOCGWINSZ */
148 extern int quit_char
;
152 #include "termhooks.h"
153 #include "termchar.h"
154 #include "termopts.h"
155 #include "dispextern.h"
158 #ifdef NONSYSTEM_DIR_LIBRARY
160 #endif /* NONSYSTEM_DIR_LIBRARY */
162 #include "syssignal.h"
165 static int baud_convert
[] =
170 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
171 1800, 2400, 4800, 9600, 19200, 38400
177 /* The file descriptor for Emacs's input terminal.
178 Under Unix, this is always left zero;
179 under VMS, we place the input channel number here.
180 This allows us to write more code that works for both VMS and Unix. */
185 struct emacs_tty buf
;
190 /* Discarding input is not safe when the input could contain
191 replies from the X server. So don't do it. */
192 if (read_socket_hook
)
197 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
198 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
204 ioctl (0, TIOCFLUSH
, &zero
);
206 #else /* not Apollo */
207 EMACS_GET_TTY (input_fd
, &buf
);
208 EMACS_SET_TTY (input_fd
, &buf
, 0);
209 #endif /* not Apollo */
218 /* Should perhaps error if in batch mode */
220 ioctl (0, TIOCSTI
, &c
);
221 #else /* no TIOCSTI */
222 error ("Cannot stuff terminal input characters in this version of Unix.");
223 #endif /* no TIOCSTI */
237 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
238 &sg
.class, 12, 0, 0, 0, 0 );
239 ospeed
= sg
.xmit_baud
;
244 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
246 ospeed
= cfgetospeed (&sg
);
247 #else /* neither VMS nor TERMIOS */
251 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
255 ioctl (input_fd
, TCGETA
, &sg
);
257 ospeed
= sg
.c_cflag
& CBAUD
;
258 #else /* neither VMS nor TERMIOS nor TERMIO */
261 sg
.sg_ospeed
= B9600
;
262 if (ioctl (0, TIOCGETP
, &sg
) < 0)
264 ospeed
= sg
.sg_ospeed
;
265 #endif /* not HAVE_TERMIO */
266 #endif /* not HAVE_TERMIOS */
270 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
271 ? baud_convert
[ospeed
] : 9600);
277 set_exclusive_use (fd
)
281 ioctl (fd
, FIOCLEX
, 0);
283 /* Ok to do nothing if this feature does not exist */
288 wait_without_blocking ()
291 wait3 (0, WNOHANG
| WUNTRACED
, 0);
293 croak ("wait_without_blocking");
295 synch_process_alive
= 0;
298 #endif /* not subprocesses */
300 int wait_debugging
; /* Set nonzero to make following function work under dbx
301 (at least for bsd). */
304 wait_for_termination_signal ()
307 /* Wait for subprocess with process id `pid' to terminate and
308 make sure it will get eliminated (not remain forever as a zombie) */
310 wait_for_termination (pid
)
319 status
= SYS$
FORCEX (&pid
, 0, 0);
322 #if defined (BSD) || (defined (HPUX) && !defined (HPUX_5))
323 /* Note that kill returns -1 even if the process is just a zombie now.
324 But inevitably a SIGCHLD interrupt should be generated
325 and child_sig will do wait3 and make the process go away. */
326 /* There is some indication that there is a bug involved with
327 termination of subprocesses, perhaps involving a kernel bug too,
328 but no idea what it is. Just as a hunch we signal SIGCHLD to see
329 if that causes the problem to go away or get worse. */
330 sigsetmask (sigmask (SIGCHLD
));
331 if (0 > kill (pid
, 0))
333 sigsetmask (SIGEMPTYMASK
);
334 kill (getpid (), SIGCHLD
);
340 sigpause (SIGEMPTYMASK
);
341 #else /* not BSD, and not HPUX version >= 6 */
342 #if defined (UNIPLUS)
343 if (0 > kill (pid
, 0))
346 #else /* neither BSD nor UNIPLUS: random sysV */
347 #ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
348 sigblock (sigmask (SIGCHLD
));
349 if (0 > kill (pid
, 0))
351 sigunblock (sigmask (SIGCHLD
));
354 sigpause (SIGEMPTYMASK
);
355 #else /* not POSIX_SIGNALS */
356 #ifdef HAVE_SYSV_SIGPAUSE
358 if (0 > kill (pid
, 0))
364 #else /* not HAVE_SYSV_SIGPAUSE */
365 if (0 > kill (pid
, 0))
367 /* Using sleep instead of pause avoids timing error.
368 If the inferior dies just before the sleep,
369 we lose just one second. */
371 #endif /* not HAVE_SYSV_SIGPAUSE */
372 #endif /* not POSIX_SIGNALS */
373 #endif /* not UNIPLUS */
374 #endif /* not BSD, and not HPUX version >= 6 */
376 #else /* not subprocesses */
378 if (kill (pid
, 0) < 0)
384 if (status
== pid
|| status
== -1)
387 #endif /* not subprocesses */
394 * flush any pending output
395 * (may flush input as well; it does not matter the way we use it)
398 flush_pending_output (channel
)
402 /* If we try this, we get hit with SIGTTIN, because
403 the child's tty belongs to the child's pgrp. */
406 ioctl (channel
, TCFLSH
, 1);
410 /* 3rd arg should be ignored
411 but some 4.2 kernels actually want the address of an int
412 and nonzero means something different. */
413 ioctl (channel
, TIOCFLUSH
, &zero
);
420 /* Set up the terminal at the other end of a pseudo-terminal that
421 we will be controlling an inferior through.
422 It should not echo or do line-editing, since that is done
423 in Emacs. No padding needed for insertion into an Emacs buffer. */
425 child_setup_tty (out
)
430 EMACS_GET_TTY (out
, &s
);
432 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
433 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
434 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
435 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
436 /* No output delays */
437 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
438 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
439 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
441 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
444 /* Said to be unnecessary: */
445 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
446 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
449 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
450 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
451 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
452 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
455 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
459 /* AIX enhanced edit loses NULs, so disable it */
462 s
.main
.c_iflag
&= ~ASCEDIT
;
464 /* Also, PTY overloads NUL and BREAK.
465 don't ignore break, but don't signal either, so it looks like NUL. */
466 s
.main
.c_iflag
&= ~IGNBRK
;
467 s
.main
.c_iflag
&= ~BRKINT
;
468 /* QUIT and INTR work better as signals, so disable character forms */
469 s
.main
.c_cc
[VINTR
] = 0377;
470 #ifdef SIGNALS_VIA_CHARACTERS
471 /* the QUIT and INTR character are used in process_send_signal
472 so set them here to something useful. */
473 if (s
.main
.c_cc
[VQUIT
] == 0377)
474 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
475 if (s
.main
.c_cc
[VINTR
] == 0377)
476 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
477 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
478 /* QUIT and INTR work better as signals, so disable character forms */
479 s
.main
.c_cc
[VQUIT
] = 0377;
480 s
.main
.c_cc
[VINTR
] = 0377;
481 s
.main
.c_lflag
&= ~ISIG
;
482 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
483 s
.main
.c_cc
[VEOL
] = 0377;
484 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
487 #else /* not HAVE_TERMIO */
489 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
491 s
.main
.sg_erase
= 0377;
492 s
.main
.sg_kill
= 0377;
494 #endif /* not HAVE_TERMIO */
496 EMACS_SET_TTY (out
, &s
, 0);
505 ioctl (out
, FIOASYNC
, &zero
);
511 #endif /* subprocesses */
517 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
520 /* Record a signal code and the handler for it. */
524 SIGTYPE (*handler
) ();
527 /* Suspend the Emacs process; give terminal to its superior. */
532 /* "Foster" parentage allows emacs to return to a subprocess that attached
533 to the current emacs as a cheaper than starting a whole new process. This
534 is set up by KEPTEDITOR.COM. */
535 unsigned long parent_id
, foster_parent_id
;
538 fpid_string
= getenv ("EMACS_PARENT_PID");
539 if (fpid_string
!= NULL
)
541 sscanf (fpid_string
, "%x", &foster_parent_id
);
542 if (foster_parent_id
!= 0)
543 parent_id
= foster_parent_id
;
545 parent_id
= getppid ();
548 parent_id
= getppid ();
550 xfree (fpid_string
); /* On VMS, this was malloc'd */
552 if (parent_id
&& parent_id
!= 0xffffffff)
554 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
555 int status
= LIB$
ATTACH (&parent_id
) & 1;
556 signal (SIGINT
, oldsig
);
565 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
566 d_prompt
.a
= "Emacs: "; /* Just a reminder */
567 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
574 EMACS_KILLPG (getpgrp (0), SIGTSTP
);
576 #else /* No SIGTSTP */
577 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
578 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
579 kill (getpid (), SIGQUIT
);
581 #else /* No SIGTSTP or USG_JOBCTRL */
583 /* On a system where suspending is not implemented,
584 instead fork a subshell and let it talk directly to the terminal
587 struct save_signal saved_handlers
[5];
589 saved_handlers
[0].code
= SIGINT
;
590 saved_handlers
[1].code
= SIGQUIT
;
591 saved_handlers
[2].code
= SIGTERM
;
593 saved_handlers
[3].code
= SIGIO
;
594 saved_handlers
[4].code
= 0;
596 saved_handlers
[3].code
= 0;
600 error ("Can't spawn subshell");
605 sh
= (char *) egetenv ("SHELL");
608 /* Use our buffer's default directory for the subshell. */
614 /* mentioning current_buffer->buffer would mean including buffer.h,
615 which somehow wedges the hp compiler. So instead... */
617 dir
= intern ("default-directory");
619 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
621 dir
= Fsymbol_value (dir
);
622 if (XTYPE (dir
) != Lisp_String
)
625 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
626 len
= XSTRING (dir
)->size
;
627 bcopy (XSTRING (dir
)->data
, str
, len
);
628 if (str
[len
- 1] != '/') str
[len
++] = '/';
634 close_process_descs (); /* Close Emacs's pipes/ptys */
639 extern int emacs_priority
;
642 nice (-emacs_priority
);
647 write (1, "Can't execute subshell", 22);
651 save_signal_handlers (saved_handlers
);
652 synch_process_alive
= 1;
653 wait_for_termination (pid
);
654 restore_signal_handlers (saved_handlers
);
656 #endif /* no USG_JOBCTRL */
657 #endif /* no SIGTSTP */
661 save_signal_handlers (saved_handlers
)
662 struct save_signal
*saved_handlers
;
664 while (saved_handlers
->code
)
666 saved_handlers
->handler
667 = (SIGTYPE (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
672 restore_signal_handlers (saved_handlers
)
673 struct save_signal
*saved_handlers
;
675 while (saved_handlers
->code
)
677 signal (saved_handlers
->code
, saved_handlers
->handler
);
689 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
699 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
704 sigunblock (sigmask (SIGWINCH
));
706 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
708 interrupts_deferred
= 0;
714 sigblock (sigmask (SIGWINCH
));
716 fcntl (0, F_SETFL
, old_fcntl_flags
);
717 interrupts_deferred
= 1;
720 #else /* no FASYNC */
721 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
726 ioctl (0, FIOASYNC
, &on
);
727 interrupts_deferred
= 0;
734 ioctl (0, FIOASYNC
, &off
);
735 interrupts_deferred
= 1;
738 #else /* not FASYNC, not STRIDE */
742 croak ("request_sigio");
747 croak ("unrequest_sigio");
754 /* Saving and restoring the process group of Emacs's terminal. */
758 /* The process group of which Emacs was a member when it initially
761 If Emacs was in its own process group (i.e. inherited_pgroup ==
762 getpid ()), then we know we're running under a shell with job
763 control (Emacs would never be run as part of a pipeline).
766 If Emacs was not in its own process group, then we know we're
767 running under a shell (or a caller) that doesn't know how to
768 separate itself from Emacs (like sh). Emacs must be in its own
769 process group in order to receive SIGIO correctly. In this
770 situation, we put ourselves in our own pgroup, forcibly set the
771 tty's pgroup to our pgroup, and make sure to restore and reinstate
772 the tty's pgroup just like any other terminal setting. If
773 inherited_group was not the tty's pgroup, then we'll get a
774 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
775 it goes foreground in the future, which is what should happen. */
776 int inherited_pgroup
;
778 /* Split off the foreground process group to Emacs alone.
779 When we are in the foreground, but not started in our own process
780 group, redirect the TTY to point to our own process group. We need
781 to be in our own process group to receive SIGIO properly. */
782 narrow_foreground_group ()
786 setpgrp (0, inherited_pgroup
);
787 if (inherited_pgroup
!= me
)
788 EMACS_SET_TTY_PGRP (0, &me
);
792 /* Set the tty to our original foreground group. */
793 widen_foreground_group ()
795 if (inherited_pgroup
!= getpid ())
796 EMACS_SET_TTY_PGRP (0, &inherited_pgroup
);
797 setpgrp (0, inherited_pgroup
);
802 /* Getting and setting emacs_tty structures. */
804 /* Set *TC to the parameters associated with the terminal FD.
805 Return zero if all's well, or -1 if we ran into an error we
806 couldn't deal with. */
808 emacs_get_tty (fd
, settings
)
810 struct emacs_tty
*settings
;
812 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
814 /* We have those nifty POSIX tcmumbleattr functions. */
815 if (tcgetattr (fd
, &settings
->main
) < 0)
820 /* The SYSV-style interface? */
821 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
826 /* Vehemently Monstrous System? :-) */
827 if (! (SYS$
QIOW (0, fd
, IO$_SENSEMODE
, settings
, 0, 0,
828 &settings
->main
.class, 12, 0, 0, 0, 0)
833 /* I give up - I hope you have the BSD ioctls. */
834 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
841 /* Suivant - Do we have to get struct ltchars data? */
843 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
847 /* How about a struct tchars and a wordful of lmode bits? */
849 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
850 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
854 /* We have survived the tempest. */
859 /* Set the parameters of the tty on FD according to the contents of
860 *SETTINGS. If WAITP is non-zero, we wait for all queued output to
861 be written before making the change; otherwise, we forget any
862 queued input and make the change immediately.
863 Return 0 if all went well, and -1 if anything failed. */
865 emacs_set_tty (fd
, settings
, waitp
)
867 struct emacs_tty
*settings
;
870 /* Set the primary parameters - baud rate, character size, etcetera. */
873 /* We have those nifty POSIX tcmumbleattr functions.
874 William J. Smith <wjs@wiis.wang.com> writes:
875 "POSIX 1003.1 defines tcsetattr() to return success if it was
876 able to perform any of the requested actions, even if some
877 of the requested actions could not be performed.
878 We must read settings back to ensure tty setup properly.
879 AIX requires this to keep tty from hanging occasionally." */
880 /* This make sure that we don't loop indefinitely in here. */
881 for (i
= 0 ; i
< 10 ; i
++)
882 if (tcsetattr (fd
, waitp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
893 /* Get the current settings, and see if they're what we asked for. */
894 tcgetattr (fd
, &new);
895 /* We cannot use memcmp on the whole structure here because under
896 * aix386 the termios structure has some reserved field that may
899 if ( new.c_iflag
== settings
->main
.c_iflag
900 && new.c_oflag
== settings
->main
.c_oflag
901 && new.c_cflag
== settings
->main
.c_cflag
902 && new.c_lflag
== settings
->main
.c_lflag
903 && memcmp(new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
911 /* The SYSV-style interface? */
912 if (ioctl (fd
, waitp
? TCSETAW
: TCSETAF
, &settings
->main
) < 0)
917 /* Vehemently Monstrous System? :-) */
918 if (! (SYS$
QIOW (0, fd
, IO$_SETMODE
, &input_iosb
, 0, 0,
919 &settings
->main
.class, 12, 0, 0, 0, 0)
924 /* I give up - I hope you have the BSD ioctls. */
925 if (ioctl (fd
, (waitp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
932 /* Suivant - Do we have to get struct ltchars data? */
934 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
938 /* How about a struct tchars and a wordful of lmode bits? */
940 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
941 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
945 /* We have survived the tempest. */
950 /* The initial tty mode bits */
951 struct emacs_tty old_tty
;
953 int term_initted
; /* 1 if outer tty status has been recorded */
956 /* BSD 4.1 needs to keep track of the lmode bits in order to start
963 #endif /* F_SETOWN */
965 /* This may also be defined in stdio,
966 but if so, this does no harm,
967 and using the same name avoids wasting the other one's space. */
969 #if defined (USG) || defined (DGUX)
970 unsigned char _sobuf
[BUFSIZ
+8];
976 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
979 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
984 struct emacs_tty tty
;
988 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
989 extern int (*interrupt_signal
) ();
998 input_ef
= get_kbd_event_flag ();
999 /* LIB$GET_EF (&input_ef); */
1000 SYS$
CLREF (input_ef
);
1001 waiting_for_ast
= 0;
1003 timer_ef
= get_timer_event_flag ();
1004 /* LIB$GET_EF (&timer_ef); */
1005 SYS$
CLREF (timer_ef
);
1009 LIB$
GET_EF (&process_ef
);
1010 SYS$
CLREF (process_ef
);
1012 if (input_ef
/ 32 != process_ef
/ 32)
1013 croak ("Input and process event flags in different clusters.");
1015 if (input_ef
/ 32 != timer_ef
/ 32)
1016 croak ("Input and timer event flags in different clusters.");
1018 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1019 ((unsigned) 1 << (process_ef
% 32));
1021 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1022 ((unsigned) 1 << (timer_ef
% 32));
1024 sys_access_reinit ();
1026 #endif /* not VMS */
1029 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1030 narrow_foreground_group ();
1033 EMACS_GET_TTY (input_fd
, &old_tty
);
1035 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1039 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1040 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1041 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1043 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1045 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1046 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1048 tty
.main
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
1050 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1053 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1055 tty
.main
.c_iflag
&= ~IXANY
;
1059 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1060 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1062 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1066 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1067 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1070 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1071 /* Set up C-g for both SIGQUIT and SIGINT.
1072 We don't know which we will get, but we handle both alike
1073 so which one it really gives us does not matter. */
1074 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1075 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1076 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1078 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1081 #if defined (mips) || defined (HAVE_TCATTR)
1083 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1086 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1087 #endif /* V_DSUSP */
1088 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1089 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1092 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1095 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1096 #endif /* VREPRINT */
1098 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1099 #endif /* VWERASE */
1101 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1102 #endif /* VDISCARD */
1103 #endif /* mips or HAVE_TCATTR */
1106 /* AIX enhanced edit loses NULs, so disable it */
1107 tty
.main
.c_line
= 0;
1108 tty
.main
.c_iflag
&= ~ASCEDIT
;
1110 tty
.main
.c_cc
[VSTRT
] = 255;
1111 tty
.main
.c_cc
[VSTOP
] = 255;
1112 tty
.main
.c_cc
[VSUSP
] = 255;
1113 tty
.main
.c_cc
[VDSUSP
] = 255;
1114 #endif /* IBMR2AIX */
1115 /* Also, PTY overloads NUL and BREAK.
1116 don't ignore break, but don't signal either, so it looks like NUL.
1117 This really serves a purpose only if running in an XTERM window
1118 or via TELNET or the like, but does no harm elsewhere. */
1119 tty
.main
.c_iflag
&= ~IGNBRK
;
1120 tty
.main
.c_iflag
&= ~BRKINT
;
1122 #else /* if not HAVE_TERMIO */
1124 tty
.main
.tt_char
|= TT$M_NOECHO
;
1126 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1128 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1130 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1131 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1132 #else /* not VMS (BSD, that is) */
1133 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1135 tty
.main
.sg_flags
|= ANYP
;
1136 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1137 #endif /* not VMS (BSD, that is) */
1138 #endif /* not HAVE_TERMIO */
1140 /* If going to use CBREAK mode, we must request C-g to interrupt
1141 and turn off start and stop chars, etc. If not going to use
1142 CBREAK mode, do this anyway so as to turn off local flow
1143 control for user coming over network on 4.2; in this case,
1144 only t_stopc and t_startc really matter. */
1147 /* Note: if not using CBREAK mode, it makes no difference how we
1149 tty
.tchars
= new_tchars
;
1150 tty
.tchars
.t_intrc
= quit_char
;
1153 tty
.tchars
.t_startc
= '\021';
1154 tty
.tchars
.t_stopc
= '\023';
1157 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
1163 #define LNOFLSH 0100000
1166 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1168 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1169 anything, and leaving it in breaks the meta key. Go figure. */
1170 tty
.lmode
&= ~LLITOUT
;
1177 #endif /* HAVE_TCHARS */
1178 #endif /* not HAVE_TERMIO */
1181 tty
.ltchars
= new_ltchars
;
1182 #endif /* HAVE_LTCHARS */
1184 EMACS_SET_TTY (input_fd
, &tty
, 0);
1186 /* This code added to insure that, if flow-control is not to be used,
1187 we have an unlocked terminal at the start. */
1190 if (!flow_control
) ioctl (0, TCXONC
, 1);
1194 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
1202 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1203 to be only LF. This is the way that is done. */
1206 if (ioctl (1, HFTGETID
, &tty
) != -1)
1207 write (1, "\033[20l", 5);
1213 /* Appears to do nothing when in PASTHRU mode.
1214 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1215 interrupt_signal, oob_chars, 0, 0, 0, 0);
1217 queue_kbd_input (0);
1222 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1223 if (interrupt_input
)
1225 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
1226 fcntl (0, F_SETOWN
, getpid ());
1229 #endif /* F_GETOWN */
1230 #endif /* F_SETFL */
1233 if (interrupt_input
)
1237 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1241 /* This symbol is defined on recent USG systems.
1242 Someone says without this call USG won't really buffer the file
1243 even with a call to setbuf. */
1244 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1246 setbuf (stdout
, _sobuf
);
1248 set_terminal_modes ();
1249 if (term_initted
&& no_redraw_on_reenter
)
1251 if (display_completed
)
1252 direct_output_forward_char (0);
1258 if (FRAMEP (Vterminal_frame
))
1259 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1266 /* Return nonzero if safe to use tabs in output.
1267 At the time this is called, init_sys_modes has not been done yet. */
1271 struct emacs_tty tty
;
1273 EMACS_GET_TTY (input_fd
, &tty
);
1274 return EMACS_TTY_TABS_OK (&tty
);
1277 /* Get terminal size from system.
1278 Store number of lines into *heightp and width into *widthp.
1279 If zero or a negative number is stored, the value is not valid. */
1281 get_frame_size (widthp
, heightp
)
1282 int *widthp
, *heightp
;
1288 struct winsize size
;
1290 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1291 *widthp
= *heightp
= 0;
1294 *widthp
= size
.ws_col
;
1295 *heightp
= size
.ws_row
;
1301 /* SunOS - style. */
1302 struct ttysize size
;
1304 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1305 *widthp
= *heightp
= 0;
1308 *widthp
= size
.ts_cols
;
1309 *heightp
= size
.ts_lines
;
1315 struct sensemode tty
;
1317 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1318 &tty
.class, 12, 0, 0, 0, 0);
1319 *widthp
= tty
.scr_wid
;
1320 *heightp
= tty
.scr_len
;
1322 #else /* system doesn't know size */
1327 #endif /* not VMS */
1328 #endif /* not SunOS-style */
1329 #endif /* not BSD-style */
1333 /* Prepare the terminal for exiting Emacs; move the cursor to the
1334 bottom of the frame, turn off interrupt-driven I/O, etc. */
1344 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1346 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1347 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1348 /* clear_end_of_line may move the cursor */
1349 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1352 /* HFT devices normally use ^J as a LF/CR. We forced it to
1353 do the LF only. Now, we need to reset it. */
1356 if (ioctl (1, HFTGETID
, &tty
) != -1)
1357 write (1, "\033[20h", 5);
1361 reset_terminal_modes ();
1365 /* Avoid possible loss of output when changing terminal modes. */
1366 fsync (fileno (stdout
));
1371 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1372 if (interrupt_input
)
1375 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1377 #endif /* F_SETOWN */
1378 #endif /* F_SETFL */
1380 if (interrupt_input
)
1384 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1392 widen_foreground_group ();
1398 /* Set up the proper status flags for use of a pty. */
1403 /* I'm told that TOICREMOTE does not mean control chars
1404 "can't be sent" but rather that they don't have
1405 input-editing or signaling effects.
1406 That should be good, because we have other ways
1407 to do those things in Emacs.
1408 However, telnet mode seems not to work on 4.2.
1409 So TIOCREMOTE is turned off now. */
1411 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1412 will hang. In particular, the "timeout" feature (which
1413 causes a read to return if there is no data available)
1414 does this. Also it is known that telnet mode will hang
1415 in such a way that Emacs must be stopped (perhaps this
1416 is the same problem).
1418 If TIOCREMOTE is turned off, then there is a bug in
1419 hp-ux which sometimes loses data. Apparently the
1420 code which blocks the master process when the internal
1421 buffer fills up does not work. Other than this,
1422 though, everything else seems to work fine.
1424 Since the latter lossage is more benign, we may as well
1425 lose that way. -- cph */
1430 ioctl (fd
, FIONBIO
, &on
);
1435 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1436 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1437 /* cause EMACS not to die when it should, i.e., when its own controlling */
1438 /* tty goes away. I've complained to the AIX developers, and they may */
1439 /* change this behavior, but I'm not going to hold my breath. */
1440 signal (SIGHUP
, SIG_IGN
);
1443 #endif /* HAVE_PTYS */
1447 /* Assigning an input channel is done at the start of Emacs execution.
1448 This is called each time Emacs is resumed, also, but does nothing
1449 because input_chain is no longer zero. */
1457 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1463 /* Deassigning the input channel is done before exiting. */
1467 return SYS$
DASSGN (input_fd
);
1472 /* Request reading one character into the keyboard buffer.
1473 This is done as soon as the buffer becomes empty. */
1478 extern kbd_input_ast ();
1480 waiting_for_ast
= 0;
1482 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1483 &input_iosb
, kbd_input_ast
, 1,
1484 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1489 /* Ast routine that is called when keyboard input comes in
1490 in accord with the SYS$QIO above. */
1494 register int c
= -1;
1495 int old_errno
= errno
;
1496 extern EMACS_TIME
*input_available_clear_time
;
1498 if (waiting_for_ast
)
1499 SYS$
SETEF (input_ef
);
1500 waiting_for_ast
= 0;
1503 if (input_count
== 25)
1505 printf ("Ast # %d,", input_count
);
1506 printf (" iosb = %x, %x, %x, %x",
1507 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1510 if (input_iosb
.offset
)
1514 printf (", char = 0%o", c
);
1526 struct input_event e
;
1527 e
.kind
= ascii_keystroke
;
1528 XSET (e
.code
, Lisp_Int
, c
);
1530 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1532 e
.frame_or_window
= Qnil
;
1534 kbd_buffer_store_event (&e
);
1536 if (input_available_clear_time
)
1537 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1541 /* Wait until there is something in kbd_buffer. */
1543 wait_for_kbd_input ()
1545 extern int have_process_input
, process_exited
;
1547 /* If already something, avoid doing system calls. */
1548 if (detect_input_pending ())
1552 /* Clear a flag, and tell ast routine above to set it. */
1553 SYS$
CLREF (input_ef
);
1554 waiting_for_ast
= 1;
1555 /* Check for timing error: ast happened while we were doing that. */
1556 if (!detect_input_pending ())
1558 /* No timing error: wait for flag to be set. */
1559 set_waiting_for_input (0);
1560 SYS$
WFLOR (input_ef
, input_eflist
);
1561 clear_waiting_for_input (0);
1562 if (!detect_input_pending ())
1563 /* Check for subprocess input availability */
1565 int dsp
= have_process_input
|| process_exited
;
1567 SYS$
CLREF (process_ef
);
1568 if (have_process_input
)
1569 process_command_input ();
1574 update_mode_lines
++;
1575 redisplay_preserve_echo_area ();
1579 waiting_for_ast
= 0;
1582 /* Get rid of any pending QIO, when we are about to suspend
1583 or when we want to throw away pending input.
1584 We wait for a positive sign that the AST routine has run
1585 and therefore there is no I/O request queued when we return.
1586 SYS$SETAST is used to avoid a timing error. */
1591 printf ("At end_kbd_input.\n");
1595 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1597 SYS$
CANCEL (input_fd
);
1602 /* Clear a flag, and tell ast routine above to set it. */
1603 SYS$
CLREF (input_ef
);
1604 waiting_for_ast
= 1;
1606 SYS$
CANCEL (input_fd
);
1608 SYS$
WAITFR (input_ef
);
1609 waiting_for_ast
= 0;
1612 /* Wait for either input available or time interval expiry. */
1614 input_wait_timeout (timeval
)
1615 int timeval
; /* Time to wait, in seconds */
1618 static int zero
= 0;
1619 static int large
= -10000000;
1621 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1623 /* If already something, avoid doing system calls. */
1624 if (detect_input_pending ())
1628 /* Clear a flag, and tell ast routine above to set it. */
1629 SYS$
CLREF (input_ef
);
1630 waiting_for_ast
= 1;
1631 /* Check for timing error: ast happened while we were doing that. */
1632 if (!detect_input_pending ())
1634 /* No timing error: wait for flag to be set. */
1636 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1637 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1639 waiting_for_ast
= 0;
1642 /* The standard `sleep' routine works some other way
1643 and it stops working if you have ever quit out of it.
1644 This one continues to work. */
1650 static int zero
= 0;
1651 static int large
= -10000000;
1653 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1656 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1657 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1672 croak ("request sigio");
1677 croak ("unrequest sigio");
1682 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1687 #ifndef SYSTEM_MALLOC
1694 /* Some systems that cannot dump also cannot implement these. */
1697 * Return the address of the start of the text segment prior to
1698 * doing an unexec. After unexec the return value is undefined.
1699 * See crt0.c for further explanation and _start.
1703 #ifndef CANNOT_UNEXEC
1708 return ((char *) TEXT_START
);
1712 return ((char *) csrt
);
1713 #else /* not GOULD */
1714 extern int _start ();
1715 return ((char *) _start
);
1717 #endif /* TEXT_START */
1719 #endif /* not CANNOT_UNEXEC */
1722 * Return the address of the start of the data segment prior to
1723 * doing an unexec. After unexec the return value is undefined.
1724 * See crt0.c for further information and definition of data_start.
1726 * Apparently, on BSD systems this is etext at startup. On
1727 * USG systems (swapping) this is highly mmu dependent and
1728 * is also dependent on whether or not the program is running
1729 * with shared text. Generally there is a (possibly large)
1730 * gap between end of text and start of data with shared text.
1732 * On Uniplus+ systems with shared text, data starts at a
1733 * fixed address. Each port (from a given oem) is generally
1734 * different, and the specific value of the start of data can
1735 * be obtained via the UniPlus+ specific "uvar" system call,
1736 * however the method outlined in crt0.c seems to be more portable.
1738 * Probably what will have to happen when a USG unexec is available,
1739 * at least on UniPlus, is temacs will have to be made unshared so
1740 * that text and data are contiguous. Then once loadup is complete,
1741 * unexec will produce a shared executable where the data can be
1742 * at the normal shared text boundry and the startofdata variable
1743 * will be patched by unexec to the correct value.
1751 return ((char *) DATA_START
);
1753 #ifdef ORDINARY_LINK
1755 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1756 * data_start isn't defined. We take the address of environ, which
1757 * is known to live at or near the start of the system crt0.c, and
1758 * we don't sweat the handful of bytes that might lose.
1760 extern char **environ
;
1762 return((char *) &environ
);
1764 extern int data_start
;
1765 return ((char *) &data_start
);
1766 #endif /* ORDINARY_LINK */
1767 #endif /* DATA_START */
1769 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1772 /* Some systems that cannot dump also cannot implement these. */
1775 * Return the address of the end of the text segment prior to
1776 * doing an unexec. After unexec the return value is undefined.
1783 return ((char *) TEXT_END
);
1786 return ((char *) &etext
);
1791 * Return the address of the end of the data segment prior to
1792 * doing an unexec. After unexec the return value is undefined.
1799 return ((char *) DATA_END
);
1802 return ((char *) &edata
);
1806 #endif /* not CANNOT_DUMP */
1808 /* Get_system_name returns as its value
1809 a string for the Lisp function system-name to return. */
1815 /* Can't have this within the function since `static' is #defined to
1816 nothing for some USG systems. */
1818 #ifdef HAVE_GETHOSTNAME
1819 static char get_system_name_name
[256];
1820 #else /* not HAVE_GETHOSTNAME */
1821 static struct utsname get_system_name_name
;
1822 #endif /* not HAVE_GETHOSTNAME */
1829 #include <sys/socket.h>
1831 #endif /* HAVE_SOCKETS */
1832 #endif /* not VMS */
1833 #endif /* not USG */
1834 #endif /* not BSD4_1 */
1840 #ifdef HAVE_GETHOSTNAME
1841 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1842 return get_system_name_name
;
1843 #else /* not HAVE_GETHOSTNAME */
1844 uname (&get_system_name_name
);
1845 return (get_system_name_name
.nodename
);
1846 #endif /* not HAVE_GETHOSTNAME */
1850 #else /* not USG, not 4.1 */
1851 static char system_name_saved
[32];
1854 if ((sp
= egetenv ("SYS$NODE")) == 0)
1860 if ((end
= index (sp
, ':')) != 0)
1863 strcpy (system_name_saved
, sp
);
1865 gethostname (system_name_saved
, sizeof (system_name_saved
));
1867 /* Turn the hostname into the official, fully-qualified hostname.
1868 Don't do this if we're going to dump; this can confuse system
1869 libraries on some machines and make the dumped emacs core dump. */
1872 #endif /* not CANNOT_DUMP */
1875 hp
= gethostbyname (system_name_saved
);
1876 if (hp
&& strlen (hp
->h_name
) < sizeof(system_name_saved
))
1877 strcpy (system_name_saved
, hp
->h_name
);
1879 #endif /* HAVE_SOCKETS */
1880 #endif /* not VMS */
1881 return system_name_saved
;
1882 #endif /* not USG, not 4.1 */
1883 #endif /* not USG */
1887 #ifndef HAVE_GETHOSTNAME
1888 void gethostname(buf
, len
)
1893 s
= getenv ("SYS$NODE");
1897 strncpy (buf
, s
, len
- 2);
1898 buf
[len
- 1] = '\0';
1900 } /* static void gethostname */
1901 #endif /* ! HAVE_GETHOSTNAME */
1908 #ifdef HAVE_X_WINDOWS
1909 /* Cause explanatory error message at compile time,
1910 since the select emulation is not good enough for X. */
1911 int *x
= &x_windows_lose_if_no_select_system_call
;
1914 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1915 * Only checks read descriptors.
1917 /* How long to wait between checking fds in select */
1918 #define SELECT_PAUSE 1
1921 /* For longjmp'ing back to read_input_waiting. */
1923 jmp_buf read_alarm_throw
;
1925 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1926 The read_socket_hook function sets this to 1 while it is waiting. */
1928 int read_alarm_should_throw
;
1936 #else /* not BSD4_1 */
1937 signal (SIGALRM
, SIG_IGN
);
1938 #endif /* not BSD4_1 */
1939 if (read_alarm_should_throw
)
1940 longjmp (read_alarm_throw
, 1);
1943 /* Only rfds are checked. */
1945 select (nfds
, rfds
, wfds
, efds
, timeout
)
1947 int *rfds
, *wfds
, *efds
, *timeout
;
1949 int ravail
= 0, orfds
= 0, old_alarm
;
1950 int timeoutval
= timeout
? *timeout
: 100000;
1951 int *local_timeout
= &timeoutval
;
1952 extern int proc_buffered_char
[];
1953 #ifndef subprocesses
1954 int process_tick
= 0, update_tick
= 0;
1956 extern int process_tick
, update_tick
;
1958 SIGTYPE (*old_trap
) ();
1971 /* If we are looking only for the terminal, with no timeout,
1972 just read it and wait -- that's more efficient. */
1973 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1975 if (! detect_input_pending ())
1976 read_input_waiting ();
1981 /* Once a second, till the timer expires, check all the flagged read
1982 * descriptors to see if any input is available. If there is some then
1983 * set the corresponding bit in the return copy of rfds.
1987 register int to_check
, bit
, fd
;
1991 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1995 int avail
= 0, status
= 0;
1998 avail
= detect_input_pending (); /* Special keyboard handler */
2002 status
= ioctl (fd
, FIONREAD
, &avail
);
2003 #else /* no FIONREAD */
2004 /* Hoping it will return -1 if nothing available
2005 or 0 if all 0 chars requested are read. */
2006 if (proc_buffered_char
[fd
] >= 0)
2010 avail
= read (fd
, &buf
, 1);
2012 proc_buffered_char
[fd
] = buf
;
2014 #endif /* no FIONREAD */
2016 if (status
>= 0 && avail
> 0)
2024 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2026 old_alarm
= alarm (0);
2027 old_trap
= signal (SIGALRM
, select_alarm
);
2029 alarm (SELECT_PAUSE
);
2030 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2031 while (select_alarmed
== 0 && *local_timeout
!= 0
2032 && process_tick
== update_tick
)
2034 /* If we are interested in terminal input,
2035 wait by reading the terminal.
2036 That makes instant wakeup for terminal input at least. */
2039 read_input_waiting ();
2040 if (detect_input_pending ())
2046 (*local_timeout
) -= SELECT_PAUSE
;
2047 /* Reset the old alarm if there was one */
2049 signal (SIGALRM
, old_trap
);
2052 /* Reset or forge an interrupt for the original handler. */
2053 old_alarm
-= SELECT_PAUSE
;
2055 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
2059 if (*local_timeout
== 0) /* Stop on timer being cleared */
2065 /* Read keyboard input into the standard buffer,
2066 waiting for at least one character. */
2068 /* Make all keyboard buffers much bigger when using X windows. */
2069 #ifdef HAVE_X_WINDOWS
2070 #define BUFFER_SIZE_FACTOR 16
2072 #define BUFFER_SIZE_FACTOR 1
2075 read_input_waiting ()
2077 char buf
[256 * BUFFER_SIZE_FACTOR
];
2078 struct input_event e
;
2080 extern int quit_char
;
2082 if (read_socket_hook
)
2084 read_alarm_should_throw
= 0;
2085 if (! setjmp (read_alarm_throw
))
2086 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
2091 nread
= read (fileno (stdin
), buf
, 1);
2093 /* Scan the chars for C-g and store them in kbd_buffer. */
2094 e
.kind
= ascii_keystroke
;
2095 e
.frame_or_window
= selected_frame
;
2097 for (i
= 0; i
< nread
; i
++)
2099 XSET (e
.code
, Lisp_Int
, buf
[i
]);
2100 kbd_buffer_store_event (&e
);
2101 /* Don't look at input that follows a C-g too closely.
2102 This reduces lossage due to autorepeat on C-g. */
2103 if (buf
[i
] == quit_char
)
2108 #endif /* not HAVE_SELECT */
2109 #endif /* not VMS */
2113 * Partially emulate 4.2 open call.
2114 * open is defined as this in 4.1.
2116 * - added by Michael Bloom @ Citicorp/TTI
2121 sys_open (path
, oflag
, mode
)
2125 if (oflag
& O_CREAT
)
2126 return creat (path
, mode
);
2128 return open (path
, oflag
);
2135 lmode
= LINTRUP
| lmode
;
2136 ioctl (0, TIOCLSET
, &lmode
);
2143 lmode
= ~LINTRUP
& lmode
;
2144 ioctl (0, TIOCLSET
, &lmode
);
2151 interrupts_deferred
= 0;
2158 interrupts_deferred
= 1;
2161 /* still inside #ifdef BSD4_1 */
2164 int sigheld
; /* Mask of held signals */
2169 sigheld
|= sigbit (signum
);
2176 sigheld
|= sigbit (signum
);
2182 sigheld
&= ~sigbit (signum
);
2186 sigfree () /* Free all held signals */
2189 for (i
= 0; i
< NSIG
; i
++)
2190 if (sigheld
& sigbit (i
))
2197 return 1 << (i
- 1);
2199 #endif /* subprocesses */
2202 /* POSIX signals support - DJB */
2203 /* Anyone with POSIX signals should have ANSI C declarations */
2205 #ifdef POSIX_SIGNALS
2207 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
2208 static struct sigaction new_action
, old_action
;
2212 sigemptyset (&empty_mask
);
2213 sigfillset (&full_mask
);
2217 sys_signal (int signal_number
, signal_handler_t action
)
2220 /* This gets us restartable system calls for efficiency.
2221 The "else" code will works as well. */
2222 return (berk_signal (signal_number
, action
));
2224 sigemptyset (&new_action
.sa_mask
);
2225 new_action
.sa_handler
= action
;
2226 new_action
.sa_flags
= 0;
2227 sigaction (signal_number
, &new_action
, &old_action
);
2228 return (old_action
.sa_handler
);
2233 /* If we're compiling with GCC, we don't need this function, since it
2234 can be written as a macro. */
2236 sys_sigmask (int sig
)
2239 sigemptyset (&mask
);
2240 sigaddset (&mask
, sig
);
2246 sys_sigpause (sigset_t new_mask
)
2248 /* pause emulating berk sigpause... */
2249 sigsuspend (&new_mask
);
2253 /* I'd like to have these guys return pointers to the mask storage in here,
2254 but there'd be trouble if the code was saving multiple masks. I'll be
2255 safe and pass the structure. It normally won't be more than 2 bytes
2259 sys_sigblock (sigset_t new_mask
)
2262 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2267 sys_sigunblock (sigset_t new_mask
)
2270 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2275 sys_sigsetmask (sigset_t new_mask
)
2278 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2282 #endif /* POSIX_SIGNALS */
2289 register int length
;
2293 long max_str
= 65535;
2295 while (length
> max_str
) {
2296 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2301 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2303 while (length
-- > 0)
2305 #endif /* not VMS */
2308 /* Saying `void' requires a declaration, above, where bcopy is used
2309 and that declaration causes pain for systems where bcopy is a macro. */
2310 bcopy (b1
, b2
, length
)
2313 register int length
;
2316 long max_str
= 65535;
2318 while (length
> max_str
) {
2319 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2325 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2327 while (length
-- > 0)
2329 #endif /* not VMS */
2333 bcmp (b1
, b2
, length
) /* This could be a macro! */
2336 register int length
;
2339 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2340 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2342 return STR$
COMPARE (&src1
, &src2
);
2344 while (length
-- > 0)
2349 #endif /* not VMS */
2351 #endif /* not BSTRING */
2356 * The BSD random returns numbers in the range of
2357 * 0 to 2e31 - 1. The USG rand returns numbers in the
2358 * range of 0 to 2e15 - 1. This is probably not significant
2365 /* Arrange to return a range centered on zero. */
2366 return (rand () << 15) + rand () - (1 << 29);
2380 /* Arrange to return a range centered on zero. */
2381 return (rand () << 15) + rand () - (1 << 29);
2392 #ifdef WRONG_NAME_INSQUE
2405 /* If any place else asks for the TERM variable,
2406 allow it to be overridden with the EMACS_TERM variable
2407 before attempting to translate the logical name TERM. As a last
2408 resort, ask for VAX C's special idea of the TERM variable. */
2415 static char buf
[256];
2416 static struct dsc$descriptor_s equiv
2417 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2418 static struct dsc$descriptor_s d_name
2419 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2422 if (!strcmp (name
, "TERM"))
2424 val
= (char *) getenv ("EMACS_TERM");
2429 d_name
.dsc$w_length
= strlen (name
);
2430 d_name
.dsc$a_pointer
= name
;
2431 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2433 char *str
= (char *) xmalloc (eqlen
+ 1);
2434 bcopy (buf
, str
, eqlen
);
2436 /* This is a storage leak, but a pain to fix. With luck,
2437 no one will ever notice. */
2440 return (char *) getenv (name
);
2445 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2446 to force a call on the debugger from within the image. */
2451 LIB$
SIGNAL (SS$_DEBUG
);
2457 #ifdef LINK_CRTL_SHARE
2458 #ifdef SHAREABLE_LIB_BUG
2459 /* Variables declared noshare and initialized in sharable libraries
2460 cannot be shared. The VMS linker incorrectly forces you to use a private
2461 version which is uninitialized... If not for this "feature", we
2462 could use the C library definition of sys_nerr and sys_errlist. */
2464 char *sys_errlist
[] =
2468 "no such file or directory",
2470 "interrupted system call",
2472 "no such device or address",
2473 "argument list too long",
2474 "exec format error",
2477 "no more processes",
2478 "not enough memory",
2479 "permission denied",
2481 "block device required",
2482 "mount devices busy",
2484 "cross-device link",
2489 "file table overflow",
2490 "too many open files",
2494 "no space left on device",
2496 "read-only file system",
2502 "vax/vms specific error code nontranslatable error"
2504 #endif /* SHAREABLE_LIB_BUG */
2505 #endif /* LINK_CRTL_SHARE */
2508 #ifdef INTERRUPTIBLE_OPEN
2512 sys_open (path
, oflag
, mode
)
2516 register int rtnval
;
2518 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2519 && (errno
== EINTR
));
2523 #endif /* INTERRUPTIBLE_OPEN */
2525 #ifdef INTERRUPTIBLE_CLOSE
2530 register int rtnval
;
2532 while ((rtnval
= close (fd
)) == -1
2533 && (errno
== EINTR
));
2537 #endif /* INTERRUPTIBLE_CLOSE */
2539 #ifdef INTERRUPTIBLE_IO
2542 sys_read (fildes
, buf
, nbyte
)
2547 register int rtnval
;
2549 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2550 && (errno
== EINTR
));
2555 sys_write (fildes
, buf
, nbyte
)
2560 register int rtnval
;
2562 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2563 && (errno
== EINTR
));
2567 #endif /* INTERRUPTIBLE_IO */
2571 * All of the following are for USG.
2573 * On USG systems the system calls are INTERRUPTIBLE by signals
2574 * that the user program has elected to catch. Thus the system call
2575 * must be retried in these cases. To handle this without massive
2576 * changes in the source code, we remap the standard system call names
2577 * to names for our own functions in sysdep.c that do the system call
2578 * with retries. Actually, for portability reasons, it is good
2579 * programming practice, as this example shows, to limit all actual
2580 * system calls to a single occurrence in the source. Sure, this
2581 * adds an extra level of function call overhead but it is almost
2582 * always negligible. Fred Fish, Unisoft Systems Inc.
2585 #ifndef HAVE_SYS_SIGLIST
2586 char *sys_siglist
[NSIG
+ 1] =
2589 /* AIX has changed the signals a bit */
2590 "bogus signal", /* 0 */
2591 "hangup", /* 1 SIGHUP */
2592 "interrupt", /* 2 SIGINT */
2593 "quit", /* 3 SIGQUIT */
2594 "illegal instruction", /* 4 SIGILL */
2595 "trace trap", /* 5 SIGTRAP */
2596 "IOT instruction", /* 6 SIGIOT */
2597 "crash likely", /* 7 SIGDANGER */
2598 "floating point exception", /* 8 SIGFPE */
2599 "kill", /* 9 SIGKILL */
2600 "bus error", /* 10 SIGBUS */
2601 "segmentation violation", /* 11 SIGSEGV */
2602 "bad argument to system call", /* 12 SIGSYS */
2603 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2604 "alarm clock", /* 14 SIGALRM */
2605 "software termination signum", /* 15 SIGTERM */
2606 "user defined signal 1", /* 16 SIGUSR1 */
2607 "user defined signal 2", /* 17 SIGUSR2 */
2608 "death of a child", /* 18 SIGCLD */
2609 "power-fail restart", /* 19 SIGPWR */
2610 "bogus signal", /* 20 */
2611 "bogus signal", /* 21 */
2612 "bogus signal", /* 22 */
2613 "bogus signal", /* 23 */
2614 "bogus signal", /* 24 */
2615 "LAN I/O interrupt", /* 25 SIGAIO */
2616 "PTY I/O interrupt", /* 26 SIGPTY */
2617 "I/O intervention required", /* 27 SIGIOINT */
2618 "HFT grant", /* 28 SIGGRANT */
2619 "HFT retract", /* 29 SIGRETRACT */
2620 "HFT sound done", /* 30 SIGSOUND */
2621 "HFT input ready", /* 31 SIGMSG */
2623 "bogus signal", /* 0 */
2624 "hangup", /* 1 SIGHUP */
2625 "interrupt", /* 2 SIGINT */
2626 "quit", /* 3 SIGQUIT */
2627 "illegal instruction", /* 4 SIGILL */
2628 "trace trap", /* 5 SIGTRAP */
2629 "IOT instruction", /* 6 SIGIOT */
2630 "EMT instruction", /* 7 SIGEMT */
2631 "floating point exception", /* 8 SIGFPE */
2632 "kill", /* 9 SIGKILL */
2633 "bus error", /* 10 SIGBUS */
2634 "segmentation violation", /* 11 SIGSEGV */
2635 "bad argument to system call", /* 12 SIGSYS */
2636 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2637 "alarm clock", /* 14 SIGALRM */
2638 "software termination signum", /* 15 SIGTERM */
2639 "user defined signal 1", /* 16 SIGUSR1 */
2640 "user defined signal 2", /* 17 SIGUSR2 */
2641 "death of a child", /* 18 SIGCLD */
2642 "power-fail restart", /* 19 SIGPWR */
2643 #endif /* not AIX */
2646 #endif /* HAVE_SYS_SIGLIST */
2649 * Warning, this function may not duplicate 4.2 action properly
2650 * under error conditions.
2654 /* In 4.1, param.h fails to define this. */
2655 #define MAXPATHLEN 1024
2664 char *npath
, *spath
;
2665 extern char *getcwd ();
2667 BLOCK_INPUT
; /* getcwd uses malloc */
2668 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2669 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2670 up to first slash. Should be harmless on other systems. */
2671 while (*npath
&& *npath
!= '/')
2673 strcpy (pathname
, npath
);
2674 free (spath
); /* getcwd uses malloc */
2679 #endif /* HAVE_GETWD */
2682 * Emulate rename using unlink/link. Note that this is
2683 * only partially correct. Also, doesn't enforce restriction
2684 * that files be of same type (regular->regular, dir->dir, etc).
2693 if (access (from
, 0) == 0)
2696 if (link (from
, to
) == 0)
2697 if (unlink (from
) == 0)
2708 * Substitute fork for vfork on USG flavors.
2716 #endif /* not HAVE_VFORK */
2718 #ifdef MISSING_UTIMES
2720 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2729 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2730 utimbuf structure defined anywhere but in the man page. */
2740 struct timeval tvp
[];
2743 utb
.actime
= tvp
[0].tv_sec
;
2744 utb
.modtime
= tvp
[1].tv_sec
;
2747 #endif /* IRIS_UTIME */
2753 /* HPUX curses library references perror, but as far as we know
2754 it won't be called. Anyway this definition will do for now. */
2760 #endif /* not HAVE_PERROR */
2766 * Emulate BSD dup2. First close newd if it already exists.
2767 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2768 * until we are, then close the unsuccessful ones.
2775 register int fd
, ret
;
2780 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2782 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2789 ret
= dup2 (old
,new);
2795 #endif /* not HAVE_DUP2 */
2798 * Gettimeofday. Simulate as much as possible. Only accurate
2799 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2800 * Only needed when subprocesses are defined.
2805 #ifndef HAVE_GETTIMEOFDAY
2809 gettimeofday (tp
, tzp
)
2811 struct timezone
*tzp
;
2813 extern long time ();
2815 tp
->tv_sec
= time ((long *)0);
2818 tzp
->tz_minuteswest
= -1;
2824 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2827 * This function will go away as soon as all the stubs fixed. (fnf)
2833 printf ("%s not yet implemented\r\n", badfunc
);
2842 char *sys_siglist
[NSIG
+ 1] =
2844 "null signal", /* 0 SIGNULL */
2845 "hangup", /* 1 SIGHUP */
2846 "interrupt", /* 2 SIGINT */
2847 "quit", /* 3 SIGQUIT */
2848 "illegal instruction", /* 4 SIGILL */
2849 "trace trap", /* 5 SIGTRAP */
2850 "abort termination", /* 6 SIGABRT */
2851 "SIGEMT", /* 7 SIGEMT */
2852 "floating point exception", /* 8 SIGFPE */
2853 "kill", /* 9 SIGKILL */
2854 "bus error", /* 10 SIGBUS */
2855 "segmentation violation", /* 11 SIGSEGV */
2856 "bad argument to system call", /* 12 SIGSYS */
2857 "write on a pipe with no reader", /* 13 SIGPIPE */
2858 "alarm clock", /* 14 SIGALRM */
2859 "software termination signal", /* 15 SIGTERM */
2860 "user defined signal 1", /* 16 SIGUSR1 */
2861 "user defined signal 2", /* 17 SIGUSR2 */
2862 "child stopped or terminated", /* 18 SIGCLD */
2863 "power-fail restart", /* 19 SIGPWR */
2864 "window size changed", /* 20 SIGWINCH */
2865 "undefined", /* 21 */
2866 "pollable event occurred", /* 22 SIGPOLL */
2867 "sendable stop signal not from tty", /* 23 SIGSTOP */
2868 "stop signal from tty", /* 24 SIGSTP */
2869 "continue a stopped process", /* 25 SIGCONT */
2870 "attempted background tty read", /* 26 SIGTTIN */
2871 "attempted background tty write", /* 27 SIGTTOU */
2872 "undefined", /* 28 */
2873 "undefined", /* 29 */
2874 "undefined", /* 30 */
2875 "undefined", /* 31 */
2876 "undefined", /* 32 */
2877 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2878 "I/O is possible", /* 34 SIGIO */
2879 "exceeded cpu time limit", /* 35 SIGXCPU */
2880 "exceeded file size limit", /* 36 SIGXFSZ */
2881 "virtual time alarm", /* 37 SIGVTALRM */
2882 "profiling time alarm", /* 38 SIGPROF */
2883 "undefined", /* 39 */
2884 "file record locks revoked", /* 40 SIGLOST */
2885 "undefined", /* 41 */
2886 "undefined", /* 42 */
2887 "undefined", /* 43 */
2888 "undefined", /* 44 */
2889 "undefined", /* 45 */
2890 "undefined", /* 46 */
2891 "undefined", /* 47 */
2892 "undefined", /* 48 */
2893 "undefined", /* 49 */
2894 "undefined", /* 50 */
2895 "undefined", /* 51 */
2896 "undefined", /* 52 */
2897 "undefined", /* 53 */
2898 "undefined", /* 54 */
2899 "undefined", /* 55 */
2900 "undefined", /* 56 */
2901 "undefined", /* 57 */
2902 "undefined", /* 58 */
2903 "undefined", /* 59 */
2904 "undefined", /* 60 */
2905 "undefined", /* 61 */
2906 "undefined", /* 62 */
2907 "undefined", /* 63 */
2908 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2914 /* Directory routines for systems that don't have them. */
2916 #ifdef SYSV_SYSTEM_DIR
2920 #ifndef HAVE_CLOSEDIR
2923 register DIR *dirp
; /* stream from opendir */
2925 sys_close (dirp
->dd_fd
);
2927 /* Some systems (like Solaris) allocate the buffer and the DIR all
2928 in one block. Why in the world are we freeing this ourselves
2930 #if ! (defined (sun) && defined (USG5_4))
2931 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2933 xfree ((char *) dirp
);
2935 #endif /* not HAVE_CLOSEDIR */
2936 #endif /* SYSV_SYSTEM_DIR */
2938 #ifdef NONSYSTEM_DIR_LIBRARY
2942 char *filename
; /* name of directory */
2944 register DIR *dirp
; /* -> malloc'ed storage */
2945 register int fd
; /* file descriptor for read */
2946 struct stat sbuf
; /* result of fstat */
2948 fd
= sys_open (filename
, 0);
2953 if (fstat (fd
, &sbuf
) < 0
2954 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2955 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2959 return 0; /* bad luck today */
2964 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2971 register DIR *dirp
; /* stream from opendir */
2973 sys_close (dirp
->dd_fd
);
2974 xfree ((char *) dirp
);
2982 ino_t od_ino
; /* inode */
2983 char od_name
[DIRSIZ
]; /* filename */
2985 #endif /* not VMS */
2987 struct direct dir_static
; /* simulated directory contents */
2992 register DIR *dirp
; /* stream from opendir */
2995 register struct olddir
*dp
; /* -> directory data */
2997 register struct dir$_name
*dp
; /* -> directory data */
2998 register struct dir$_version
*dv
; /* -> version data */
3003 if (dirp
->dd_loc
>= dirp
->dd_size
)
3004 dirp
->dd_loc
= dirp
->dd_size
= 0;
3006 if (dirp
->dd_size
== 0 /* refill buffer */
3007 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3011 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3012 dirp
->dd_loc
+= sizeof (struct olddir
);
3014 if (dp
->od_ino
!= 0) /* not deleted entry */
3016 dir_static
.d_ino
= dp
->od_ino
;
3017 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3018 dir_static
.d_name
[DIRSIZ
] = '\0';
3019 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3020 dir_static
.d_reclen
= sizeof (struct direct
)
3022 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3023 return &dir_static
; /* -> simulated structure */
3026 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3027 if (dirp
->dd_loc
== 0)
3028 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3029 : dp
->dir$b_namecount
;
3030 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3031 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3032 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3033 dir_static
.d_reclen
= sizeof (struct direct
)
3035 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3036 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3037 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3038 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3045 /* readdirver is just like readdir except it returns all versions of a file
3046 as separate entries. */
3051 register DIR *dirp
; /* stream from opendir */
3053 register struct dir$_name
*dp
; /* -> directory data */
3054 register struct dir$_version
*dv
; /* -> version data */
3056 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3057 dirp
->dd_loc
= dirp
->dd_size
= 0;
3059 if (dirp
->dd_size
== 0 /* refill buffer */
3060 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3063 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3064 if (dirp
->dd_loc
== 0)
3065 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3066 : dp
->dir$b_namecount
;
3067 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3068 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3069 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3070 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3071 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3072 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3073 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3074 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3080 #endif /* NONSYSTEM_DIR_LIBRARY */
3082 /* Functions for VMS */
3084 #include "vms-pwd.h"
3089 /* Return as a string the VMS error string pertaining to STATUS.
3090 Reuses the same static buffer each time it is called. */
3094 int status
; /* VMS status code */
3098 static char buf
[257];
3100 bufadr
[0] = sizeof buf
- 1;
3101 bufadr
[1] = (int) buf
;
3102 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3103 return "untranslatable VMS error status";
3111 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3112 * not work correctly. (It also doesn't work well in version 2.3.)
3117 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3118 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3122 unsigned short s_buflen
;
3123 unsigned short s_code
;
3125 unsigned short *s_retlenadr
;
3129 #define buflen s.s_buflen
3130 #define code s.s_code
3131 #define bufadr s.s_bufadr
3132 #define retlenadr s.s_retlenadr
3134 #define R_OK 4 /* test for read permission */
3135 #define W_OK 2 /* test for write permission */
3136 #define X_OK 1 /* test for execute (search) permission */
3137 #define F_OK 0 /* test for presence of file */
3140 sys_access (path
, mode
)
3144 static char *user
= NULL
;
3147 /* translate possible directory spec into .DIR file name, so brain-dead
3148 * access can treat the directory like a file. */
3149 if (directory_file_name (path
, dir_fn
))
3153 return access (path
, mode
);
3154 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3160 unsigned short int dummy
;
3162 static int constant
= ACL$C_FILE
;
3163 DESCRIPTOR (path_desc
, path
);
3164 DESCRIPTOR (user_desc
, user
);
3168 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3171 acces
|= CHP$M_READ
;
3173 acces
|= CHP$M_WRITE
;
3174 itemlst
[0].buflen
= sizeof (int);
3175 itemlst
[0].code
= CHP$_FLAGS
;
3176 itemlst
[0].bufadr
= (char *) &flags
;
3177 itemlst
[0].retlenadr
= &dummy
;
3178 itemlst
[1].buflen
= sizeof (int);
3179 itemlst
[1].code
= CHP$_ACCESS
;
3180 itemlst
[1].bufadr
= (char *) &acces
;
3181 itemlst
[1].retlenadr
= &dummy
;
3182 itemlst
[2].end
= CHP$_END
;
3183 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3184 return stat
== SS$_NORMAL
? 0 : -1;
3188 #else /* not VMS4_4 */
3191 #define ACE$M_WRITE 2
3192 #define ACE$C_KEYID 1
3194 static unsigned short memid
, grpid
;
3195 static unsigned int uic
;
3197 /* Called from init_sys_modes, so it happens not very often
3198 but at least each time Emacs is loaded. */
3199 sys_access_reinit ()
3205 sys_access (filename
, type
)
3211 int status
, size
, i
, typecode
, acl_controlled
;
3212 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3213 union prvdef prvmask
;
3215 /* Get UIC and GRP values for protection checking. */
3218 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3221 memid
= uic
& 0xFFFF;
3225 if (type
!= 2) /* not checking write access */
3226 return access (filename
, type
);
3228 /* Check write protection. */
3230 #define CHECKPRIV(bit) (prvmask.bit)
3231 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3233 /* Find privilege bits */
3234 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3236 error ("Unable to find privileges: %s", vmserrstr (status
));
3237 if (CHECKPRIV (PRV$V_BYPASS
))
3238 return 0; /* BYPASS enabled */
3240 fab
.fab$b_fac
= FAB$M_GET
;
3241 fab
.fab$l_fna
= filename
;
3242 fab
.fab$b_fns
= strlen (filename
);
3243 fab
.fab$l_xab
= &xab
;
3244 xab
= cc$rms_xabpro
;
3245 xab
.xab$l_aclbuf
= aclbuf
;
3246 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3247 status
= SYS$
OPEN (&fab
, 0, 0);
3250 SYS$
CLOSE (&fab
, 0, 0);
3251 /* Check system access */
3252 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
3254 /* Check ACL entries, if any */
3256 if (xab
.xab$w_acllen
> 0)
3259 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3260 while (*aclptr
&& aclptr
< aclend
)
3262 size
= (*aclptr
& 0xff) / 4;
3263 typecode
= (*aclptr
>> 8) & 0xff;
3264 if (typecode
== ACE$C_KEYID
)
3265 for (i
= size
- 1; i
> 1; i
--)
3266 if (aclptr
[i
] == uic
)
3269 if (aclptr
[1] & ACE$M_WRITE
)
3270 return 0; /* Write access through ACL */
3272 aclptr
= &aclptr
[size
];
3274 if (acl_controlled
) /* ACL specified, prohibits write access */
3277 /* No ACL entries specified, check normal protection */
3278 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3280 if (WRITEABLE (XAB$V_GRP
) &&
3281 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3282 return 0; /* Group writeable */
3283 if (WRITEABLE (XAB$V_OWN
) &&
3284 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3285 return 0; /* Owner writeable */
3287 return -1; /* Not writeable */
3289 #endif /* not VMS4_4 */
3292 static char vtbuf
[NAM$C_MAXRSS
+1];
3294 /* translate a vms file spec to a unix path */
3296 sys_translate_vms (vfile
)
3307 /* leading device or logical name is a root directory */
3308 if (p
= strchr (vfile
, ':'))
3317 if (*p
== '[' || *p
== '<')
3319 while (*++vfile
!= *p
+ 2)
3323 if (vfile
[-1] == *p
)
3346 static char utbuf
[NAM$C_MAXRSS
+1];
3348 /* translate a unix path to a VMS file spec */
3350 sys_translate_unix (ufile
)
3373 if (index (&ufile
[1], '/'))
3380 if (index (&ufile
[1], '/'))
3387 if (strncmp (ufile
, "./", 2) == 0)
3394 ufile
++; /* skip the dot */
3395 if (index (&ufile
[1], '/'))
3400 else if (strncmp (ufile
, "../", 3) == 0)
3408 ufile
+= 2; /* skip the dots */
3409 if (index (&ufile
[1], '/'))
3434 extern char *getcwd ();
3436 #define MAXPATHLEN 1024
3438 ptr
= xmalloc (MAXPATHLEN
);
3439 getcwd (ptr
, MAXPATHLEN
);
3440 strcpy (pathname
, ptr
);
3448 long item_code
= JPI$_OWNER
;
3449 unsigned long parent_id
;
3452 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3455 vaxc$errno
= status
;
3465 return (getgid () << 16) | getuid ();
3469 sys_read (fildes
, buf
, nbyte
)
3474 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3479 sys_write (fildes
, buf
, nbyte
)
3484 register int nwrote
, rtnval
= 0;
3486 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3492 return rtnval
? rtnval
: -1;
3493 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3494 return rtnval
? rtnval
: -1;
3495 return (rtnval
+ nwrote
);
3500 * VAX/VMS VAX C RTL really loses. It insists that records
3501 * end with a newline (carriage return) character, and if they
3502 * don't it adds one (nice of it isn't it!)
3504 * Thus we do this stupidity below.
3508 sys_write (fildes
, buf
, nbytes
)
3511 unsigned int nbytes
;
3518 fstat (fildes
, &st
);
3524 /* Handle fixed-length files with carriage control. */
3525 if (st
.st_fab_rfm
== FAB$C_FIX
3526 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3528 len
= st
.st_fab_mrs
;
3529 retval
= write (fildes
, p
, min (len
, nbytes
));
3532 retval
++; /* This skips the implied carriage control */
3536 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3537 while (*e
!= '\n' && e
> p
) e
--;
3538 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3539 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3541 retval
= write (fildes
, p
, len
);
3552 /* Create file NEW copying its attributes from file OLD. If
3553 OLD is 0 or does not exist, create based on the value of
3556 /* Protection value the file should ultimately have.
3557 Set by create_copy_attrs, and use by rename_sansversions. */
3558 static unsigned short int fab_final_pro
;
3561 creat_copy_attrs (old
, new)
3564 struct FAB fab
= cc$rms_fab
;
3565 struct XABPRO xabpro
;
3566 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3567 extern int vms_stmlf_recfm
;
3571 fab
.fab$b_fac
= FAB$M_GET
;
3572 fab
.fab$l_fna
= old
;
3573 fab
.fab$b_fns
= strlen (old
);
3574 fab
.fab$l_xab
= (char *) &xabpro
;
3575 xabpro
= cc$rms_xabpro
;
3576 xabpro
.xab$l_aclbuf
= aclbuf
;
3577 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3578 /* Call $OPEN to fill in the fab & xabpro fields. */
3579 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3581 SYS$
CLOSE (&fab
, 0, 0);
3582 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3583 if (xabpro
.xab$w_acllen
> 0)
3585 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3586 /* If the acl buffer was too short, redo open with longer one.
3587 Wouldn't need to do this if there were some system imposed
3588 limit on the size of an ACL, but I can't find any such. */
3590 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3591 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3592 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3593 SYS$
CLOSE (&fab
, 0, 0);
3599 xabpro
.xab$l_aclbuf
= 0;
3604 fab
.fab$l_fna
= new;
3605 fab
.fab$b_fns
= strlen (new);
3609 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3610 fab
.fab$b_rat
= FAB$M_CR
;
3613 /* Set the file protections such that we will be able to manipulate
3614 this file. Once we are done writing and renaming it, we will set
3615 the protections back. */
3617 fab_final_pro
= xabpro
.xab$w_pro
;
3619 SYS$
SETDFPROT (0, &fab_final_pro
);
3620 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3622 /* Create the new file with either default attrs or attrs copied
3624 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3626 SYS$
CLOSE (&fab
, 0, 0);
3627 /* As this is a "replacement" for creat, return a file descriptor
3628 opened for writing. */
3629 return open (new, O_WRONLY
);
3634 #include <varargs.h>
3637 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3641 sys_creat (va_alist
)
3644 va_list list_incrementer
;
3647 int rfd
; /* related file descriptor */
3648 int fd
; /* Our new file descriptor */
3655 extern int vms_stmlf_recfm
;
3658 va_start (list_incrementer
);
3659 name
= va_arg (list_incrementer
, char *);
3660 mode
= va_arg (list_incrementer
, int);
3662 rfd
= va_arg (list_incrementer
, int);
3663 va_end (list_incrementer
);
3666 /* Use information from the related file descriptor to set record
3667 format of the newly created file. */
3668 fstat (rfd
, &st_buf
);
3669 switch (st_buf
.st_fab_rfm
)
3672 strcpy (rfm
, "rfm = fix");
3673 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3674 strcpy (rat
, "rat = ");
3675 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3677 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3678 strcat (rat
, "ftn");
3679 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3680 strcat (rat
, "prn");
3681 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3682 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3683 strcat (rat
, ", blk");
3685 strcat (rat
, "blk");
3686 return creat (name
, 0, rfm
, rat
, mrs
);
3689 strcpy (rfm
, "rfm = vfc");
3690 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3691 strcpy (rat
, "rat = ");
3692 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3694 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3695 strcat (rat
, "ftn");
3696 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3697 strcat (rat
, "prn");
3698 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3699 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3700 strcat (rat
, ", blk");
3702 strcat (rat
, "blk");
3703 return creat (name
, 0, rfm
, rat
, fsz
);
3706 strcpy (rfm
, "rfm = stm");
3710 strcpy (rfm
, "rfm = stmcr");
3714 strcpy (rfm
, "rfm = stmlf");
3718 strcpy (rfm
, "rfm = udf");
3722 strcpy (rfm
, "rfm = var");
3725 strcpy (rat
, "rat = ");
3726 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3728 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3729 strcat (rat
, "ftn");
3730 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3731 strcat (rat
, "prn");
3732 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3733 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3734 strcat (rat
, ", blk");
3736 strcat (rat
, "blk");
3740 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3741 strcpy (rat
, "rat=cr");
3743 /* Until the VAX C RTL fixes the many bugs with modes, always use
3744 mode 0 to get the user's default protection. */
3745 fd
= creat (name
, 0, rfm
, rat
);
3746 if (fd
< 0 && errno
== EEXIST
)
3748 if (unlink (name
) < 0)
3749 report_file_error ("delete", build_string (name
));
3750 fd
= creat (name
, 0, rfm
, rat
);
3756 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3757 sys_fwrite (ptr
, size
, num
, fp
)
3758 register char * ptr
;
3761 register int tot
= num
* size
;
3768 * The VMS C library routine creat actually creates a new version of an
3769 * existing file rather than truncating the old version. There are times
3770 * when this is not the desired behavior, for instance, when writing an
3771 * auto save file (you only want one version), or when you don't have
3772 * write permission in the directory containing the file (but the file
3773 * itself is writable). Hence this routine, which is equivalent to
3774 * "close (creat (fn, 0));" on Unix if fn already exists.
3780 struct FAB xfab
= cc$rms_fab
;
3781 struct RAB xrab
= cc$rms_rab
;
3784 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3785 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3786 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3787 xfab
.fab$l_fna
= fn
;
3788 xfab
.fab$b_fns
= strlen (fn
);
3789 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3791 xrab
.rab$l_fab
= &xfab
;
3793 /* This gibberish opens the file, positions to the first record, and
3794 deletes all records from there until the end of file. */
3795 if ((SYS$
OPEN (&xfab
) & 01) == 01)
3797 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
3798 (SYS$
FIND (&xrab
) & 01) == 01 &&
3799 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
3810 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3811 SYSPRV or a readable SYSUAF.DAT. */
3817 * Routine to read the VMS User Authorization File and return
3818 * a specific user's record.
3821 static struct UAF retuaf
;
3824 get_uaf_name (uname
)
3831 uaf_fab
= cc$rms_fab
;
3832 uaf_rab
= cc$rms_rab
;
3833 /* initialize fab fields */
3834 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3835 uaf_fab
.fab$b_fns
= 21;
3836 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3837 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3838 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3839 /* initialize rab fields */
3840 uaf_rab
.rab$l_fab
= &uaf_fab
;
3841 /* open the User Authorization File */
3842 status
= SYS$
OPEN (&uaf_fab
);
3846 vaxc$errno
= status
;
3849 status
= SYS$
CONNECT (&uaf_rab
);
3853 vaxc$errno
= status
;
3856 /* read the requested record - index is in uname */
3857 uaf_rab
.rab$l_kbf
= uname
;
3858 uaf_rab
.rab$b_ksz
= strlen (uname
);
3859 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3860 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3861 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3862 status
= SYS$
GET (&uaf_rab
);
3866 vaxc$errno
= status
;
3869 /* close the User Authorization File */
3870 status
= SYS$
DISCONNECT (&uaf_rab
);
3874 vaxc$errno
= status
;
3877 status
= SYS$
CLOSE (&uaf_fab
);
3881 vaxc$errno
= status
;
3895 uaf_fab
= cc$rms_fab
;
3896 uaf_rab
= cc$rms_rab
;
3897 /* initialize fab fields */
3898 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3899 uaf_fab
.fab$b_fns
= 21;
3900 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3901 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3902 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3903 /* initialize rab fields */
3904 uaf_rab
.rab$l_fab
= &uaf_fab
;
3905 /* open the User Authorization File */
3906 status
= SYS$
OPEN (&uaf_fab
);
3910 vaxc$errno
= status
;
3913 status
= SYS$
CONNECT (&uaf_rab
);
3917 vaxc$errno
= status
;
3920 /* read the requested record - index is in uic */
3921 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3922 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3923 uaf_rab
.rab$b_ksz
= sizeof uic
;
3924 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3925 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3926 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3927 status
= SYS$
GET (&uaf_rab
);
3931 vaxc$errno
= status
;
3934 /* close the User Authorization File */
3935 status
= SYS$
DISCONNECT (&uaf_rab
);
3939 vaxc$errno
= status
;
3942 status
= SYS$
CLOSE (&uaf_fab
);
3946 vaxc$errno
= status
;
3952 static struct passwd retpw
;
3960 /* copy these out first because if the username is 32 chars, the next
3961 section will overwrite the first byte of the UIC */
3962 retpw
.pw_uid
= up
->uaf$w_mem
;
3963 retpw
.pw_gid
= up
->uaf$w_grp
;
3965 /* I suppose this is not the best sytle, to possibly overwrite one
3966 byte beyond the end of the field, but what the heck... */
3967 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3968 while (ptr
[-1] == ' ')
3971 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3973 /* the rest of these are counted ascii strings */
3974 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3975 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3976 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3977 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3978 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3979 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3980 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3981 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3985 #else /* not READ_SYSUAF */
3986 static struct passwd retpw
;
3987 #endif /* not READ_SYSUAF */
3998 unsigned char * full
;
3999 #endif /* READ_SYSUAF */
4004 if ('a' <= *ptr
&& *ptr
<= 'z')
4009 if (!(up
= get_uaf_name (name
)))
4011 return cnv_uaf_pw (up
);
4013 if (strcmp (name
, getenv ("USER")) == 0)
4015 retpw
.pw_uid
= getuid ();
4016 retpw
.pw_gid
= getgid ();
4017 strcpy (retpw
.pw_name
, name
);
4018 if (full
= egetenv ("FULLNAME"))
4019 strcpy (retpw
.pw_gecos
, full
);
4021 *retpw
.pw_gecos
= '\0';
4022 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4023 *retpw
.pw_shell
= '\0';
4028 #endif /* not READ_SYSUAF */
4038 if (!(up
= get_uaf_uic (uid
)))
4040 return cnv_uaf_pw (up
);
4042 if (uid
== sys_getuid ())
4043 return getpwnam (egetenv ("USER"));
4046 #endif /* not READ_SYSUAF */
4049 /* return total address space available to the current process. This is
4050 the sum of the current p0 size, p1 size and free page table entries
4055 unsigned long free_pages
;
4056 unsigned long frep0va
;
4057 unsigned long frep1va
;
4060 item_code
= JPI$_FREPTECNT
;
4061 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4064 vaxc$errno
= status
;
4069 item_code
= JPI$_FREP0VA
;
4070 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4073 vaxc$errno
= status
;
4076 item_code
= JPI$_FREP1VA
;
4077 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4080 vaxc$errno
= status
;
4084 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4087 define_logical_name (varname
, string
)
4091 struct dsc$descriptor_s strdsc
=
4092 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4093 struct dsc$descriptor_s envdsc
=
4094 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4095 struct dsc$descriptor_s lnmdsc
=
4096 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4098 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4101 delete_logical_name (varname
)
4104 struct dsc$descriptor_s envdsc
=
4105 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4106 struct dsc$descriptor_s lnmdsc
=
4107 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4109 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4120 error ("execvp system call not implemented");
4128 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4129 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4130 char from_esn
[NAM$C_MAXRSS
];
4131 char to_esn
[NAM$C_MAXRSS
];
4133 from_fab
.fab$l_fna
= from
;
4134 from_fab
.fab$b_fns
= strlen (from
);
4135 from_fab
.fab$l_nam
= &from_nam
;
4136 from_fab
.fab$l_fop
= FAB$M_NAM
;
4138 from_nam
.nam$l_esa
= from_esn
;
4139 from_nam
.nam$b_ess
= sizeof from_esn
;
4141 to_fab
.fab$l_fna
= to
;
4142 to_fab
.fab$b_fns
= strlen (to
);
4143 to_fab
.fab$l_nam
= &to_nam
;
4144 to_fab
.fab$l_fop
= FAB$M_NAM
;
4146 to_nam
.nam$l_esa
= to_esn
;
4147 to_nam
.nam$b_ess
= sizeof to_esn
;
4149 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4155 if (status
== RMS$_DEV
)
4159 vaxc$errno
= status
;
4164 /* This function renames a file like `rename', but it strips
4165 the version number from the "to" filename, such that the "to" file is
4166 will always be a new version. It also sets the file protection once it is
4167 finished. The protection that we will use is stored in fab_final_pro,
4168 and was set when we did a creat_copy_attrs to create the file that we
4171 We could use the chmod function, but Eunichs uses 3 bits per user category
4172 to describe the protection, and VMS uses 4 (write and delete are separate
4173 bits). To maintain portability, the VMS implementation of `chmod' wires
4174 the W and D bits together. */
4177 static struct fibdef fib
; /* We need this initialized to zero */
4178 char vms_file_written
[NAM$C_MAXRSS
];
4181 rename_sans_version (from
,to
)
4188 struct FAB to_fab
= cc$rms_fab
;
4189 struct NAM to_nam
= cc$rms_nam
;
4190 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4191 struct dsc$descriptor fib_attr
[2]
4192 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4193 char to_esn
[NAM$C_MAXRSS
];
4195 $
DESCRIPTOR (disk
,to_esn
);
4197 to_fab
.fab$l_fna
= to
;
4198 to_fab
.fab$b_fns
= strlen (to
);
4199 to_fab
.fab$l_nam
= &to_nam
;
4200 to_fab
.fab$l_fop
= FAB$M_NAM
;
4202 to_nam
.nam$l_esa
= to_esn
;
4203 to_nam
.nam$b_ess
= sizeof to_esn
;
4205 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4207 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4208 *(to_nam
.nam$l_ver
) = '\0';
4210 stat
= rename (from
, to_esn
);
4214 strcpy (vms_file_written
, to_esn
);
4216 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4217 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4219 /* Now set the file protection to the correct value */
4220 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4222 /* Copy these fields into the fib */
4223 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4224 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4225 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4227 SYS$
CLOSE (&to_fab
, 0, 0);
4229 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4232 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4233 0, 0, 0, &fib_attr
, 0);
4236 stat
= SYS$
DASSGN (chan
);
4239 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4249 unsigned short fid
[3];
4250 char esa
[NAM$C_MAXRSS
];
4253 fab
.fab$l_fop
= FAB$M_OFP
;
4254 fab
.fab$l_fna
= file
;
4255 fab
.fab$b_fns
= strlen (file
);
4256 fab
.fab$l_nam
= &nam
;
4259 nam
.nam$l_esa
= esa
;
4260 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4262 status
= SYS$
PARSE (&fab
);
4263 if ((status
& 1) == 0)
4266 vaxc$errno
= status
;
4269 status
= SYS$
SEARCH (&fab
);
4270 if ((status
& 1) == 0)
4273 vaxc$errno
= status
;
4277 fid
[0] = nam
.nam$w_fid
[0];
4278 fid
[1] = nam
.nam$w_fid
[1];
4279 fid
[2] = nam
.nam$w_fid
[2];
4281 fab
.fab$l_fna
= new;
4282 fab
.fab$b_fns
= strlen (new);
4284 status
= SYS$
PARSE (&fab
);
4285 if ((status
& 1) == 0)
4288 vaxc$errno
= status
;
4292 nam
.nam$w_fid
[0] = fid
[0];
4293 nam
.nam$w_fid
[1] = fid
[1];
4294 nam
.nam$w_fid
[2] = fid
[2];
4296 nam
.nam$l_esa
= nam
.nam$l_name
;
4297 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4299 status
= SYS$
ENTER (&fab
);
4300 if ((status
& 1) == 0)
4303 vaxc$errno
= status
;
4313 printf ("%s not yet implemented\r\n", badfunc
);
4321 /* Arrange to return a range centered on zero. */
4322 return rand () - (1 << 30);
4333 /* Called from init_sys_modes. */
4338 /* If we're not on an HFT we shouldn't do any of this. We determine
4339 if we are on an HFT by trying to get an HFT error code. If this
4340 call fails, we're not on an HFT. */
4342 if (ioctl (0, HFQERROR
, &junk
) < 0)
4344 #else /* not IBMR2AIX */
4345 if (ioctl (0, HFQEIO
, 0) < 0)
4347 #endif /* not IBMR2AIX */
4349 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4350 as the rubout key's ASCII code. Here this is changed. The bug is that
4351 there's no way to determine the old mapping, so in reset_sys_modes
4352 we need to assume that the normal map had been present. Of course, this
4353 code also doesn't help if on a terminal emulator which doesn't understand
4357 struct hfkeymap keymap
;
4359 buf
.hf_bufp
= (char *)&keymap
;
4360 buf
.hf_buflen
= sizeof (keymap
);
4361 keymap
.hf_nkeys
= 2;
4362 keymap
.hfkey
[0].hf_kpos
= 15;
4363 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4365 keymap
.hfkey
[0].hf_keyidh
= '<';
4366 #else /* not IBMR2AIX */
4367 keymap
.hfkey
[0].hf_page
= '<';
4368 #endif /* not IBMR2AIX */
4369 keymap
.hfkey
[0].hf_char
= 127;
4370 keymap
.hfkey
[1].hf_kpos
= 15;
4371 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4373 keymap
.hfkey
[1].hf_keyidh
= '<';
4374 #else /* not IBMR2AIX */
4375 keymap
.hfkey
[1].hf_page
= '<';
4376 #endif /* not IBMR2AIX */
4377 keymap
.hfkey
[1].hf_char
= 127;
4378 hftctl (0, HFSKBD
, &buf
);
4380 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4382 line_ins_del_ok
= char_ins_del_ok
= 0;
4385 /* Reset the rubout key to backspace. */
4390 struct hfkeymap keymap
;
4394 if (ioctl (0, HFQERROR
, &junk
) < 0)
4396 #else /* not IBMR2AIX */
4397 if (ioctl (0, HFQEIO
, 0) < 0)
4399 #endif /* not IBMR2AIX */
4401 buf
.hf_bufp
= (char *)&keymap
;
4402 buf
.hf_buflen
= sizeof (keymap
);
4403 keymap
.hf_nkeys
= 2;
4404 keymap
.hfkey
[0].hf_kpos
= 15;
4405 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4407 keymap
.hfkey
[0].hf_keyidh
= '<';
4408 #else /* not IBMR2AIX */
4409 keymap
.hfkey
[0].hf_page
= '<';
4410 #endif /* not IBMR2AIX */
4411 keymap
.hfkey
[0].hf_char
= 8;
4412 keymap
.hfkey
[1].hf_kpos
= 15;
4413 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4415 keymap
.hfkey
[1].hf_keyidh
= '<';
4416 #else /* not IBMR2AIX */
4417 keymap
.hfkey
[1].hf_page
= '<';
4418 #endif /* not IBMR2AIX */
4419 keymap
.hfkey
[1].hf_char
= 8;
4420 hftctl (0, HFSKBD
, &buf
);