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 static int baud_convert
[] =
163 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
164 1800, 2400, 4800, 9600, 19200, 38400
170 /* The file descriptor for Emacs's input terminal.
171 Under Unix, this is always left zero;
172 under VMS, we place the input channel number here.
173 This allows us to write more code that works for both VMS and Unix. */
178 struct emacs_tty buf
;
183 /* Discarding input is not safe when the input could contain
184 replies from the X server. So don't do it. */
185 if (read_socket_hook
)
190 SYS$
QIOW (0, input_fd
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
191 &buf
.main
, 0, 0, terminator_mask
, 0, 0);
197 ioctl (0, TIOCFLUSH
, &zero
);
199 #else /* not Apollo */
200 EMACS_GET_TTY (input_fd
, &buf
);
201 EMACS_SET_TTY (input_fd
, &buf
, 0);
202 #endif /* not Apollo */
211 /* Should perhaps error if in batch mode */
213 ioctl (0, TIOCSTI
, &c
);
214 #else /* no TIOCSTI */
215 error ("Cannot stuff terminal input characters in this version of Unix.");
216 #endif /* no TIOCSTI */
230 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &sg
, 0, 0,
231 &sg
.class, 12, 0, 0, 0, 0 );
232 ospeed
= sg
.xmit_baud
;
237 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
239 ospeed
= cfgetospeed (&sg
);
240 #else /* neither VMS nor TERMIOS */
244 sg
.c_cflag
= (sg
.c_cflag
& ~CBAUD
) | B9600
;
248 ioctl (input_fd
, TCGETA
, &sg
);
250 ospeed
= sg
.c_cflag
& CBAUD
;
251 #else /* neither VMS nor TERMIOS nor TERMIO */
254 sg
.sg_ospeed
= B9600
;
255 if (ioctl (0, TIOCGETP
, &sg
) < 0)
257 ospeed
= sg
.sg_ospeed
;
258 #endif /* not HAVE_TERMIO */
259 #endif /* not HAVE_TERMIOS */
263 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
264 ? baud_convert
[ospeed
] : 9600);
270 set_exclusive_use (fd
)
274 ioctl (fd
, FIOCLEX
, 0);
276 /* Ok to do nothing if this feature does not exist */
281 wait_without_blocking ()
284 wait3 (0, WNOHANG
| WUNTRACED
, 0);
286 croak ("wait_without_blocking");
288 synch_process_alive
= 0;
291 #endif /* not subprocesses */
293 int wait_debugging
; /* Set nonzero to make following function work under dbx
294 (at least for bsd). */
297 wait_for_termination_signal ()
300 /* Wait for subprocess with process id `pid' to terminate and
301 make sure it will get eliminated (not remain forever as a zombie) */
303 wait_for_termination (pid
)
312 status
= SYS$
FORCEX (&pid
, 0, 0);
315 #if defined (BSD) || (defined (HPUX) && !defined (HPUX_5))
316 /* Note that kill returns -1 even if the process is just a zombie now.
317 But inevitably a SIGCHLD interrupt should be generated
318 and child_sig will do wait3 and make the process go away. */
319 /* There is some indication that there is a bug involved with
320 termination of subprocesses, perhaps involving a kernel bug too,
321 but no idea what it is. Just as a hunch we signal SIGCHLD to see
322 if that causes the problem to go away or get worse. */
323 sigsetmask (sigmask (SIGCHLD
));
324 if (0 > kill (pid
, 0))
326 sigsetmask (SIGEMPTYMASK
);
327 kill (getpid (), SIGCHLD
);
333 sigpause (SIGEMPTYMASK
);
334 #else /* not BSD, and not HPUX version >= 6 */
335 #if defined (UNIPLUS)
336 if (0 > kill (pid
, 0))
339 #else /* neither BSD nor UNIPLUS: random sysV */
340 #ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
341 sigblock (sigmask (SIGCHLD
));
342 if (0 > kill (pid
, 0))
344 sigunblock (sigmask (SIGCHLD
));
347 sigpause (SIGEMPTYMASK
);
348 #else /* not POSIX_SIGNALS */
349 #ifdef HAVE_SYSV_SIGPAUSE
351 if (0 > kill (pid
, 0))
357 #else /* not HAVE_SYSV_SIGPAUSE */
358 if (0 > kill (pid
, 0))
360 /* Using sleep instead of pause avoids timing error.
361 If the inferior dies just before the sleep,
362 we lose just one second. */
364 #endif /* not HAVE_SYSV_SIGPAUSE */
365 #endif /* not POSIX_SIGNALS */
366 #endif /* not UNIPLUS */
367 #endif /* not BSD, and not HPUX version >= 6 */
369 #else /* not subprocesses */
371 if (kill (pid
, 0) < 0)
377 if (status
== pid
|| status
== -1)
380 #endif /* not subprocesses */
387 * flush any pending output
388 * (may flush input as well; it does not matter the way we use it)
391 flush_pending_output (channel
)
395 /* If we try this, we get hit with SIGTTIN, because
396 the child's tty belongs to the child's pgrp. */
399 ioctl (channel
, TCFLSH
, 1);
403 /* 3rd arg should be ignored
404 but some 4.2 kernels actually want the address of an int
405 and nonzero means something different. */
406 ioctl (channel
, TIOCFLUSH
, &zero
);
413 /* Set up the terminal at the other end of a pseudo-terminal that
414 we will be controlling an inferior through.
415 It should not echo or do line-editing, since that is done
416 in Emacs. No padding needed for insertion into an Emacs buffer. */
418 child_setup_tty (out
)
423 EMACS_GET_TTY (out
, &s
);
425 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
426 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
427 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
428 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
429 /* No output delays */
430 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
431 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
432 s
.main
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on
434 s
.main
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on
437 /* Said to be unnecessary: */
438 s
.main
.c_cc
[VMIN
] = 1; /* minimum number of characters to accept */
439 s
.main
.c_cc
[VTIME
] = 0; /* wait forever for at least 1 character */
442 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
443 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
444 s
.main
.c_cc
[VERASE
] = 0377; /* disable erase processing */
445 s
.main
.c_cc
[VKILL
] = 0377; /* disable kill processing */
448 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
452 /* AIX enhanced edit loses NULs, so disable it */
455 s
.main
.c_iflag
&= ~ASCEDIT
;
457 /* Also, PTY overloads NUL and BREAK.
458 don't ignore break, but don't signal either, so it looks like NUL. */
459 s
.main
.c_iflag
&= ~IGNBRK
;
460 s
.main
.c_iflag
&= ~BRKINT
;
461 /* QUIT and INTR work better as signals, so disable character forms */
462 s
.main
.c_cc
[VINTR
] = 0377;
463 #ifdef SIGNALS_VIA_CHARACTERS
464 /* the QUIT and INTR character are used in process_send_signal
465 so set them here to something useful. */
466 if (s
.main
.c_cc
[VQUIT
] == 0377)
467 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
468 if (s
.main
.c_cc
[VINTR
] == 0377)
469 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
470 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
471 /* QUIT and INTR work better as signals, so disable character forms */
472 s
.main
.c_cc
[VQUIT
] = 0377;
473 s
.main
.c_cc
[VINTR
] = 0377;
474 s
.main
.c_lflag
&= ~ISIG
;
475 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
476 s
.main
.c_cc
[VEOL
] = 0377;
477 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
480 #else /* not HAVE_TERMIO */
482 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
484 s
.main
.sg_erase
= 0377;
485 s
.main
.sg_kill
= 0377;
487 #endif /* not HAVE_TERMIO */
489 EMACS_SET_TTY (out
, &s
, 0);
498 ioctl (out
, FIOASYNC
, &zero
);
504 #endif /* subprocesses */
510 EMACS_SET_TTY_PGRP (input_fd
, &pid
);
513 /* Record a signal code and the handler for it. */
517 SIGTYPE (*handler
) ();
520 /* Suspend the Emacs process; give terminal to its superior. */
525 /* "Foster" parentage allows emacs to return to a subprocess that attached
526 to the current emacs as a cheaper than starting a whole new process. This
527 is set up by KEPTEDITOR.COM. */
528 unsigned long parent_id
, foster_parent_id
;
531 fpid_string
= getenv ("EMACS_PARENT_PID");
532 if (fpid_string
!= NULL
)
534 sscanf (fpid_string
, "%x", &foster_parent_id
);
535 if (foster_parent_id
!= 0)
536 parent_id
= foster_parent_id
;
538 parent_id
= getppid ();
541 parent_id
= getppid ();
543 xfree (fpid_string
); /* On VMS, this was malloc'd */
545 if (parent_id
&& parent_id
!= 0xffffffff)
547 SIGTYPE (*oldsig
)() = (int) signal (SIGINT
, SIG_IGN
);
548 int status
= LIB$
ATTACH (&parent_id
) & 1;
549 signal (SIGINT
, oldsig
);
558 d_prompt
.l
= sizeof ("Emacs: "); /* Our special prompt */
559 d_prompt
.a
= "Emacs: "; /* Just a reminder */
560 LIB$
SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt
, 0);
569 int pgrp
= getpgrp ();
571 int pgrp
= getpgrp (0);
573 EMACS_KILLPG (pgrp
, 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
964 #endif /* F_SETOWN */
965 #endif /* F_SETOWN_BUG */
967 /* This may also be defined in stdio,
968 but if so, this does no harm,
969 and using the same name avoids wasting the other one's space. */
971 #if defined (USG) || defined (DGUX)
972 unsigned char _sobuf
[BUFSIZ
+8];
978 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
981 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
986 struct emacs_tty tty
;
990 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
991 extern int (*interrupt_signal
) ();
1000 input_ef
= get_kbd_event_flag ();
1001 /* LIB$GET_EF (&input_ef); */
1002 SYS$
CLREF (input_ef
);
1003 waiting_for_ast
= 0;
1005 timer_ef
= get_timer_event_flag ();
1006 /* LIB$GET_EF (&timer_ef); */
1007 SYS$
CLREF (timer_ef
);
1011 LIB$
GET_EF (&process_ef
);
1012 SYS$
CLREF (process_ef
);
1014 if (input_ef
/ 32 != process_ef
/ 32)
1015 croak ("Input and process event flags in different clusters.");
1017 if (input_ef
/ 32 != timer_ef
/ 32)
1018 croak ("Input and timer event flags in different clusters.");
1020 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1021 ((unsigned) 1 << (process_ef
% 32));
1023 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
1024 ((unsigned) 1 << (timer_ef
% 32));
1026 sys_access_reinit ();
1028 #endif /* not VMS */
1031 if (! read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1032 narrow_foreground_group ();
1035 EMACS_GET_TTY (input_fd
, &old_tty
);
1037 if (!read_socket_hook
&& EQ (Vwindow_system
, Qnil
))
1041 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1042 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1043 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1045 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1047 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1048 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1050 tty
.main
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
1052 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1055 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1057 tty
.main
.c_iflag
&= ~IXANY
;
1061 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1062 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1064 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1068 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1069 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1072 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1073 /* Set up C-g for both SIGQUIT and SIGINT.
1074 We don't know which we will get, but we handle both alike
1075 so which one it really gives us does not matter. */
1076 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1077 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1078 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1080 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1083 #if defined (mips) || defined (HAVE_TCATTR)
1085 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1088 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1089 #endif /* V_DSUSP */
1090 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1091 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1094 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1097 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1098 #endif /* VREPRINT */
1100 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1101 #endif /* VWERASE */
1103 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1104 #endif /* VDISCARD */
1105 #endif /* mips or HAVE_TCATTR */
1108 /* AIX enhanced edit loses NULs, so disable it */
1109 tty
.main
.c_line
= 0;
1110 tty
.main
.c_iflag
&= ~ASCEDIT
;
1112 tty
.main
.c_cc
[VSTRT
] = 255;
1113 tty
.main
.c_cc
[VSTOP
] = 255;
1114 tty
.main
.c_cc
[VSUSP
] = 255;
1115 tty
.main
.c_cc
[VDSUSP
] = 255;
1116 #endif /* IBMR2AIX */
1117 /* Also, PTY overloads NUL and BREAK.
1118 don't ignore break, but don't signal either, so it looks like NUL.
1119 This really serves a purpose only if running in an XTERM window
1120 or via TELNET or the like, but does no harm elsewhere. */
1121 tty
.main
.c_iflag
&= ~IGNBRK
;
1122 tty
.main
.c_iflag
&= ~BRKINT
;
1124 #else /* if not HAVE_TERMIO */
1126 tty
.main
.tt_char
|= TT$M_NOECHO
;
1128 tty
.main
.tt_char
|= TT$M_EIGHTBIT
;
1130 tty
.main
.tt_char
|= TT$M_TTSYNC
;
1132 tty
.main
.tt_char
&= ~TT$M_TTSYNC
;
1133 tty
.main
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1134 #else /* not VMS (BSD, that is) */
1135 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1137 tty
.main
.sg_flags
|= ANYP
;
1138 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1139 #endif /* not VMS (BSD, that is) */
1140 #endif /* not HAVE_TERMIO */
1142 /* If going to use CBREAK mode, we must request C-g to interrupt
1143 and turn off start and stop chars, etc. If not going to use
1144 CBREAK mode, do this anyway so as to turn off local flow
1145 control for user coming over network on 4.2; in this case,
1146 only t_stopc and t_startc really matter. */
1149 /* Note: if not using CBREAK mode, it makes no difference how we
1151 tty
.tchars
= new_tchars
;
1152 tty
.tchars
.t_intrc
= quit_char
;
1155 tty
.tchars
.t_startc
= '\021';
1156 tty
.tchars
.t_stopc
= '\023';
1159 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
1165 #define LNOFLSH 0100000
1168 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_tty
.lmode
;
1170 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1171 anything, and leaving it in breaks the meta key. Go figure. */
1172 tty
.lmode
&= ~LLITOUT
;
1179 #endif /* HAVE_TCHARS */
1180 #endif /* not HAVE_TERMIO */
1183 tty
.ltchars
= new_ltchars
;
1184 #endif /* HAVE_LTCHARS */
1186 EMACS_SET_TTY (input_fd
, &tty
, 0);
1188 /* This code added to insure that, if flow-control is not to be used,
1189 we have an unlocked terminal at the start. */
1192 if (!flow_control
) ioctl (0, TCXONC
, 1);
1196 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
1204 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1205 to be only LF. This is the way that is done. */
1208 if (ioctl (1, HFTGETID
, &tty
) != -1)
1209 write (1, "\033[20l", 5);
1215 /* Appears to do nothing when in PASTHRU mode.
1216 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1217 interrupt_signal, oob_chars, 0, 0, 0, 0);
1219 queue_kbd_input (0);
1224 #ifndef F_SETOWN_BUG
1225 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1226 if (interrupt_input
)
1228 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
1229 fcntl (0, F_SETOWN
, getpid ());
1232 #endif /* F_GETOWN */
1233 #endif /* F_SETOWN_BUG */
1234 #endif /* F_SETFL */
1237 if (interrupt_input
)
1241 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1245 /* This symbol is defined on recent USG systems.
1246 Someone says without this call USG won't really buffer the file
1247 even with a call to setbuf. */
1248 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1250 setbuf (stdout
, _sobuf
);
1252 set_terminal_modes ();
1253 if (term_initted
&& no_redraw_on_reenter
)
1255 if (display_completed
)
1256 direct_output_forward_char (0);
1262 if (FRAMEP (Vterminal_frame
))
1263 FRAME_GARBAGED_P (XFRAME (Vterminal_frame
)) = 1;
1270 /* Return nonzero if safe to use tabs in output.
1271 At the time this is called, init_sys_modes has not been done yet. */
1275 struct emacs_tty tty
;
1277 EMACS_GET_TTY (input_fd
, &tty
);
1278 return EMACS_TTY_TABS_OK (&tty
);
1281 /* Get terminal size from system.
1282 Store number of lines into *heightp and width into *widthp.
1283 If zero or a negative number is stored, the value is not valid. */
1285 get_frame_size (widthp
, heightp
)
1286 int *widthp
, *heightp
;
1292 struct winsize size
;
1294 if (ioctl (input_fd
, TIOCGWINSZ
, &size
) == -1)
1295 *widthp
= *heightp
= 0;
1298 *widthp
= size
.ws_col
;
1299 *heightp
= size
.ws_row
;
1305 /* SunOS - style. */
1306 struct ttysize size
;
1308 if (ioctl (input_fd
, TIOCGSIZE
, &size
) == -1)
1309 *widthp
= *heightp
= 0;
1312 *widthp
= size
.ts_cols
;
1313 *heightp
= size
.ts_lines
;
1319 struct sensemode tty
;
1321 SYS$
QIOW (0, input_fd
, IO$_SENSEMODE
, &tty
, 0, 0,
1322 &tty
.class, 12, 0, 0, 0, 0);
1323 *widthp
= tty
.scr_wid
;
1324 *heightp
= tty
.scr_len
;
1326 #else /* system doesn't know size */
1331 #endif /* not VMS */
1332 #endif /* not SunOS-style */
1333 #endif /* not BSD-style */
1337 /* Prepare the terminal for exiting Emacs; move the cursor to the
1338 bottom of the frame, turn off interrupt-driven I/O, etc. */
1348 if (read_socket_hook
|| !EQ (Vwindow_system
, Qnil
))
1350 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1351 clear_end_of_line (FRAME_WIDTH (selected_frame
));
1352 /* clear_end_of_line may move the cursor */
1353 cursor_to (FRAME_HEIGHT (selected_frame
) - 1, 0);
1356 /* HFT devices normally use ^J as a LF/CR. We forced it to
1357 do the LF only. Now, we need to reset it. */
1360 if (ioctl (1, HFTGETID
, &tty
) != -1)
1361 write (1, "\033[20h", 5);
1365 reset_terminal_modes ();
1369 /* Avoid possible loss of output when changing terminal modes. */
1370 fsync (fileno (stdout
));
1375 #ifndef F_SETOWN_BUG
1376 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1377 if (interrupt_input
)
1380 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1382 #endif /* F_SETOWN */
1383 #endif /* F_SETOWN_BUG */
1384 #endif /* F_SETFL */
1386 if (interrupt_input
)
1390 while (EMACS_SET_TTY (input_fd
, &old_tty
, 0) < 0 && errno
== EINTR
)
1398 widen_foreground_group ();
1404 /* Set up the proper status flags for use of a pty. */
1409 /* I'm told that TOICREMOTE does not mean control chars
1410 "can't be sent" but rather that they don't have
1411 input-editing or signaling effects.
1412 That should be good, because we have other ways
1413 to do those things in Emacs.
1414 However, telnet mode seems not to work on 4.2.
1415 So TIOCREMOTE is turned off now. */
1417 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1418 will hang. In particular, the "timeout" feature (which
1419 causes a read to return if there is no data available)
1420 does this. Also it is known that telnet mode will hang
1421 in such a way that Emacs must be stopped (perhaps this
1422 is the same problem).
1424 If TIOCREMOTE is turned off, then there is a bug in
1425 hp-ux which sometimes loses data. Apparently the
1426 code which blocks the master process when the internal
1427 buffer fills up does not work. Other than this,
1428 though, everything else seems to work fine.
1430 Since the latter lossage is more benign, we may as well
1431 lose that way. -- cph */
1436 ioctl (fd
, FIONBIO
, &on
);
1441 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1442 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1443 /* cause EMACS not to die when it should, i.e., when its own controlling */
1444 /* tty goes away. I've complained to the AIX developers, and they may */
1445 /* change this behavior, but I'm not going to hold my breath. */
1446 signal (SIGHUP
, SIG_IGN
);
1449 #endif /* HAVE_PTYS */
1453 /* Assigning an input channel is done at the start of Emacs execution.
1454 This is called each time Emacs is resumed, also, but does nothing
1455 because input_chain is no longer zero. */
1463 status
= SYS$
ASSIGN (&input_dsc
, &input_fd
, 0, 0);
1469 /* Deassigning the input channel is done before exiting. */
1473 return SYS$
DASSGN (input_fd
);
1478 /* Request reading one character into the keyboard buffer.
1479 This is done as soon as the buffer becomes empty. */
1484 extern kbd_input_ast ();
1486 waiting_for_ast
= 0;
1488 status
= SYS$
QIO (0, input_fd
, IO$_READVBLK
,
1489 &input_iosb
, kbd_input_ast
, 1,
1490 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1495 /* Ast routine that is called when keyboard input comes in
1496 in accord with the SYS$QIO above. */
1500 register int c
= -1;
1501 int old_errno
= errno
;
1502 extern EMACS_TIME
*input_available_clear_time
;
1504 if (waiting_for_ast
)
1505 SYS$
SETEF (input_ef
);
1506 waiting_for_ast
= 0;
1509 if (input_count
== 25)
1511 printf ("Ast # %d,", input_count
);
1512 printf (" iosb = %x, %x, %x, %x",
1513 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1516 if (input_iosb
.offset
)
1520 printf (", char = 0%o", c
);
1532 struct input_event e
;
1533 e
.kind
= ascii_keystroke
;
1534 XSET (e
.code
, Lisp_Int
, c
);
1536 XSET(e
.frame_or_window
, Lisp_Frame
, selected_frame
);
1538 e
.frame_or_window
= Qnil
;
1540 kbd_buffer_store_event (&e
);
1542 if (input_available_clear_time
)
1543 EMACS_SET_SECS_USECS (*input_available_clear_time
, 0, 0);
1547 /* Wait until there is something in kbd_buffer. */
1549 wait_for_kbd_input ()
1551 extern int have_process_input
, process_exited
;
1553 /* If already something, avoid doing system calls. */
1554 if (detect_input_pending ())
1558 /* Clear a flag, and tell ast routine above to set it. */
1559 SYS$
CLREF (input_ef
);
1560 waiting_for_ast
= 1;
1561 /* Check for timing error: ast happened while we were doing that. */
1562 if (!detect_input_pending ())
1564 /* No timing error: wait for flag to be set. */
1565 set_waiting_for_input (0);
1566 SYS$
WFLOR (input_ef
, input_eflist
);
1567 clear_waiting_for_input (0);
1568 if (!detect_input_pending ())
1569 /* Check for subprocess input availability */
1571 int dsp
= have_process_input
|| process_exited
;
1573 SYS$
CLREF (process_ef
);
1574 if (have_process_input
)
1575 process_command_input ();
1580 update_mode_lines
++;
1581 redisplay_preserve_echo_area ();
1585 waiting_for_ast
= 0;
1588 /* Get rid of any pending QIO, when we are about to suspend
1589 or when we want to throw away pending input.
1590 We wait for a positive sign that the AST routine has run
1591 and therefore there is no I/O request queued when we return.
1592 SYS$SETAST is used to avoid a timing error. */
1597 printf ("At end_kbd_input.\n");
1601 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
1603 SYS$
CANCEL (input_fd
);
1608 /* Clear a flag, and tell ast routine above to set it. */
1609 SYS$
CLREF (input_ef
);
1610 waiting_for_ast
= 1;
1612 SYS$
CANCEL (input_fd
);
1614 SYS$
WAITFR (input_ef
);
1615 waiting_for_ast
= 0;
1618 /* Wait for either input available or time interval expiry. */
1620 input_wait_timeout (timeval
)
1621 int timeval
; /* Time to wait, in seconds */
1624 static int zero
= 0;
1625 static int large
= -10000000;
1627 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1629 /* If already something, avoid doing system calls. */
1630 if (detect_input_pending ())
1634 /* Clear a flag, and tell ast routine above to set it. */
1635 SYS$
CLREF (input_ef
);
1636 waiting_for_ast
= 1;
1637 /* Check for timing error: ast happened while we were doing that. */
1638 if (!detect_input_pending ())
1640 /* No timing error: wait for flag to be set. */
1642 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1643 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1645 waiting_for_ast
= 0;
1648 /* The standard `sleep' routine works some other way
1649 and it stops working if you have ever quit out of it.
1650 This one continues to work. */
1656 static int zero
= 0;
1657 static int large
= -10000000;
1659 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1662 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1663 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1678 croak ("request sigio");
1683 croak ("unrequest sigio");
1688 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1693 #ifndef SYSTEM_MALLOC
1700 /* Some systems that cannot dump also cannot implement these. */
1703 * Return the address of the start of the text segment prior to
1704 * doing an unexec. After unexec the return value is undefined.
1705 * See crt0.c for further explanation and _start.
1709 #ifndef CANNOT_UNEXEC
1714 return ((char *) TEXT_START
);
1718 return ((char *) csrt
);
1719 #else /* not GOULD */
1720 extern int _start ();
1721 return ((char *) _start
);
1723 #endif /* TEXT_START */
1725 #endif /* not CANNOT_UNEXEC */
1728 * Return the address of the start of the data segment prior to
1729 * doing an unexec. After unexec the return value is undefined.
1730 * See crt0.c for further information and definition of data_start.
1732 * Apparently, on BSD systems this is etext at startup. On
1733 * USG systems (swapping) this is highly mmu dependent and
1734 * is also dependent on whether or not the program is running
1735 * with shared text. Generally there is a (possibly large)
1736 * gap between end of text and start of data with shared text.
1738 * On Uniplus+ systems with shared text, data starts at a
1739 * fixed address. Each port (from a given oem) is generally
1740 * different, and the specific value of the start of data can
1741 * be obtained via the UniPlus+ specific "uvar" system call,
1742 * however the method outlined in crt0.c seems to be more portable.
1744 * Probably what will have to happen when a USG unexec is available,
1745 * at least on UniPlus, is temacs will have to be made unshared so
1746 * that text and data are contiguous. Then once loadup is complete,
1747 * unexec will produce a shared executable where the data can be
1748 * at the normal shared text boundry and the startofdata variable
1749 * will be patched by unexec to the correct value.
1757 return ((char *) DATA_START
);
1759 #ifdef ORDINARY_LINK
1761 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1762 * data_start isn't defined. We take the address of environ, which
1763 * is known to live at or near the start of the system crt0.c, and
1764 * we don't sweat the handful of bytes that might lose.
1766 extern char **environ
;
1768 return((char *) &environ
);
1770 extern int data_start
;
1771 return ((char *) &data_start
);
1772 #endif /* ORDINARY_LINK */
1773 #endif /* DATA_START */
1775 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1778 /* Some systems that cannot dump also cannot implement these. */
1781 * Return the address of the end of the text segment prior to
1782 * doing an unexec. After unexec the return value is undefined.
1789 return ((char *) TEXT_END
);
1792 return ((char *) &etext
);
1797 * Return the address of the end of the data segment prior to
1798 * doing an unexec. After unexec the return value is undefined.
1805 return ((char *) DATA_END
);
1808 return ((char *) &edata
);
1812 #endif /* not CANNOT_DUMP */
1814 /* Get_system_name returns as its value
1815 a string for the Lisp function system-name to return. */
1821 /* Can't have this within the function since `static' is #defined to
1822 nothing for some USG systems. */
1824 #ifdef HAVE_GETHOSTNAME
1825 static char get_system_name_name
[256];
1826 #else /* not HAVE_GETHOSTNAME */
1827 static struct utsname get_system_name_name
;
1828 #endif /* not HAVE_GETHOSTNAME */
1835 #include <sys/socket.h>
1837 #endif /* HAVE_SOCKETS */
1838 #endif /* not VMS */
1839 #endif /* not USG */
1840 #endif /* not BSD4_1 */
1846 #ifdef HAVE_GETHOSTNAME
1847 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1848 return get_system_name_name
;
1849 #else /* not HAVE_GETHOSTNAME */
1850 uname (&get_system_name_name
);
1851 return (get_system_name_name
.nodename
);
1852 #endif /* not HAVE_GETHOSTNAME */
1856 #else /* not USG, not 4.1 */
1857 static char system_name_saved
[32];
1860 if ((sp
= egetenv ("SYS$NODE")) == 0)
1866 if ((end
= index (sp
, ':')) != 0)
1869 strcpy (system_name_saved
, sp
);
1871 gethostname (system_name_saved
, sizeof (system_name_saved
));
1873 /* Turn the hostname into the official, fully-qualified hostname.
1874 Don't do this if we're going to dump; this can confuse system
1875 libraries on some machines and make the dumped emacs core dump. */
1878 #endif /* not CANNOT_DUMP */
1881 hp
= gethostbyname (system_name_saved
);
1882 if (hp
&& strlen (hp
->h_name
) < sizeof(system_name_saved
))
1883 strcpy (system_name_saved
, hp
->h_name
);
1885 #endif /* HAVE_SOCKETS */
1886 #endif /* not VMS */
1887 return system_name_saved
;
1888 #endif /* not USG, not 4.1 */
1889 #endif /* not USG */
1893 #ifndef HAVE_GETHOSTNAME
1894 void gethostname(buf
, len
)
1899 s
= getenv ("SYS$NODE");
1903 strncpy (buf
, s
, len
- 2);
1904 buf
[len
- 1] = '\0';
1906 } /* static void gethostname */
1907 #endif /* ! HAVE_GETHOSTNAME */
1914 #ifdef HAVE_X_WINDOWS
1915 /* Cause explanatory error message at compile time,
1916 since the select emulation is not good enough for X. */
1917 int *x
= &x_windows_lose_if_no_select_system_call
;
1920 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1921 * Only checks read descriptors.
1923 /* How long to wait between checking fds in select */
1924 #define SELECT_PAUSE 1
1927 /* For longjmp'ing back to read_input_waiting. */
1929 jmp_buf read_alarm_throw
;
1931 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1932 The read_socket_hook function sets this to 1 while it is waiting. */
1934 int read_alarm_should_throw
;
1942 #else /* not BSD4_1 */
1943 signal (SIGALRM
, SIG_IGN
);
1944 #endif /* not BSD4_1 */
1945 if (read_alarm_should_throw
)
1946 longjmp (read_alarm_throw
, 1);
1949 /* Only rfds are checked. */
1951 select (nfds
, rfds
, wfds
, efds
, timeout
)
1953 int *rfds
, *wfds
, *efds
, *timeout
;
1955 int ravail
= 0, orfds
= 0, old_alarm
;
1956 int timeoutval
= timeout
? *timeout
: 100000;
1957 int *local_timeout
= &timeoutval
;
1958 extern int proc_buffered_char
[];
1959 #ifndef subprocesses
1960 int process_tick
= 0, update_tick
= 0;
1962 extern int process_tick
, update_tick
;
1964 SIGTYPE (*old_trap
) ();
1977 /* If we are looking only for the terminal, with no timeout,
1978 just read it and wait -- that's more efficient. */
1979 if (orfds
== 1 && *local_timeout
== 100000 && process_tick
== update_tick
)
1981 if (! detect_input_pending ())
1982 read_input_waiting ();
1987 /* Once a second, till the timer expires, check all the flagged read
1988 * descriptors to see if any input is available. If there is some then
1989 * set the corresponding bit in the return copy of rfds.
1993 register int to_check
, bit
, fd
;
1997 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
2001 int avail
= 0, status
= 0;
2004 avail
= detect_input_pending (); /* Special keyboard handler */
2008 status
= ioctl (fd
, FIONREAD
, &avail
);
2009 #else /* no FIONREAD */
2010 /* Hoping it will return -1 if nothing available
2011 or 0 if all 0 chars requested are read. */
2012 if (proc_buffered_char
[fd
] >= 0)
2016 avail
= read (fd
, &buf
, 1);
2018 proc_buffered_char
[fd
] = buf
;
2020 #endif /* no FIONREAD */
2022 if (status
>= 0 && avail
> 0)
2030 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2032 old_alarm
= alarm (0);
2033 old_trap
= signal (SIGALRM
, select_alarm
);
2035 alarm (SELECT_PAUSE
);
2036 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2037 while (select_alarmed
== 0 && *local_timeout
!= 0
2038 && process_tick
== update_tick
)
2040 /* If we are interested in terminal input,
2041 wait by reading the terminal.
2042 That makes instant wakeup for terminal input at least. */
2045 read_input_waiting ();
2046 if (detect_input_pending ())
2052 (*local_timeout
) -= SELECT_PAUSE
;
2053 /* Reset the old alarm if there was one */
2055 signal (SIGALRM
, old_trap
);
2058 /* Reset or forge an interrupt for the original handler. */
2059 old_alarm
-= SELECT_PAUSE
;
2061 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
2065 if (*local_timeout
== 0) /* Stop on timer being cleared */
2071 /* Read keyboard input into the standard buffer,
2072 waiting for at least one character. */
2074 /* Make all keyboard buffers much bigger when using X windows. */
2075 #ifdef HAVE_X_WINDOWS
2076 #define BUFFER_SIZE_FACTOR 16
2078 #define BUFFER_SIZE_FACTOR 1
2081 read_input_waiting ()
2083 char buf
[256 * BUFFER_SIZE_FACTOR
];
2084 struct input_event e
;
2086 extern int quit_char
;
2088 if (read_socket_hook
)
2090 read_alarm_should_throw
= 0;
2091 if (! setjmp (read_alarm_throw
))
2092 nread
= (*read_socket_hook
) (0, buf
, 256 * BUFFER_SIZE_FACTOR
, 1, 0);
2097 nread
= read (fileno (stdin
), buf
, 1);
2099 /* Scan the chars for C-g and store them in kbd_buffer. */
2100 e
.kind
= ascii_keystroke
;
2101 e
.frame_or_window
= selected_frame
;
2103 for (i
= 0; i
< nread
; i
++)
2105 XSET (e
.code
, Lisp_Int
, buf
[i
]);
2106 kbd_buffer_store_event (&e
);
2107 /* Don't look at input that follows a C-g too closely.
2108 This reduces lossage due to autorepeat on C-g. */
2109 if (buf
[i
] == quit_char
)
2114 #endif /* not HAVE_SELECT */
2115 #endif /* not VMS */
2119 * Partially emulate 4.2 open call.
2120 * open is defined as this in 4.1.
2122 * - added by Michael Bloom @ Citicorp/TTI
2127 sys_open (path
, oflag
, mode
)
2131 if (oflag
& O_CREAT
)
2132 return creat (path
, mode
);
2134 return open (path
, oflag
);
2141 lmode
= LINTRUP
| lmode
;
2142 ioctl (0, TIOCLSET
, &lmode
);
2149 lmode
= ~LINTRUP
& lmode
;
2150 ioctl (0, TIOCLSET
, &lmode
);
2157 interrupts_deferred
= 0;
2164 interrupts_deferred
= 1;
2167 /* still inside #ifdef BSD4_1 */
2170 int sigheld
; /* Mask of held signals */
2175 sigheld
|= sigbit (signum
);
2182 sigheld
|= sigbit (signum
);
2188 sigheld
&= ~sigbit (signum
);
2192 sigfree () /* Free all held signals */
2195 for (i
= 0; i
< NSIG
; i
++)
2196 if (sigheld
& sigbit (i
))
2203 return 1 << (i
- 1);
2205 #endif /* subprocesses */
2208 /* POSIX signals support - DJB */
2209 /* Anyone with POSIX signals should have ANSI C declarations */
2211 #ifdef POSIX_SIGNALS
2213 sigset_t old_mask
, empty_mask
, full_mask
, temp_mask
;
2214 static struct sigaction new_action
, old_action
;
2218 sigemptyset (&empty_mask
);
2219 sigfillset (&full_mask
);
2223 sys_signal (int signal_number
, signal_handler_t action
)
2226 /* This gets us restartable system calls for efficiency.
2227 The "else" code will works as well. */
2228 return (berk_signal (signal_number
, action
));
2230 sigemptyset (&new_action
.sa_mask
);
2231 new_action
.sa_handler
= action
;
2232 new_action
.sa_flags
= 0;
2233 sigaction (signal_number
, &new_action
, &old_action
);
2234 return (old_action
.sa_handler
);
2239 /* If we're compiling with GCC, we don't need this function, since it
2240 can be written as a macro. */
2242 sys_sigmask (int sig
)
2245 sigemptyset (&mask
);
2246 sigaddset (&mask
, sig
);
2252 sys_sigpause (sigset_t new_mask
)
2254 /* pause emulating berk sigpause... */
2255 sigsuspend (&new_mask
);
2259 /* I'd like to have these guys return pointers to the mask storage in here,
2260 but there'd be trouble if the code was saving multiple masks. I'll be
2261 safe and pass the structure. It normally won't be more than 2 bytes
2265 sys_sigblock (sigset_t new_mask
)
2268 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2273 sys_sigunblock (sigset_t new_mask
)
2276 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2281 sys_sigsetmask (sigset_t new_mask
)
2284 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2288 #endif /* POSIX_SIGNALS */
2295 register int length
;
2299 long max_str
= 65535;
2301 while (length
> max_str
) {
2302 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2307 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2309 while (length
-- > 0)
2311 #endif /* not VMS */
2314 /* Saying `void' requires a declaration, above, where bcopy is used
2315 and that declaration causes pain for systems where bcopy is a macro. */
2316 bcopy (b1
, b2
, length
)
2319 register int length
;
2322 long max_str
= 65535;
2324 while (length
> max_str
) {
2325 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2331 (void) LIB$
MOVC3 (&length
, b1
, b2
);
2333 while (length
-- > 0)
2335 #endif /* not VMS */
2339 bcmp (b1
, b2
, length
) /* This could be a macro! */
2342 register int length
;
2345 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2346 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2348 return STR$
COMPARE (&src1
, &src2
);
2350 while (length
-- > 0)
2355 #endif /* not VMS */
2357 #endif /* not BSTRING */
2362 * The BSD random returns numbers in the range of
2363 * 0 to 2e31 - 1. The USG rand returns numbers in the
2364 * range of 0 to 2e15 - 1. This is probably not significant
2371 /* Arrange to return a range centered on zero. */
2372 return (rand () << 15) + rand () - (1 << 29);
2386 /* Arrange to return a range centered on zero. */
2387 return (rand () << 15) + rand () - (1 << 29);
2398 #ifdef WRONG_NAME_INSQUE
2411 /* If any place else asks for the TERM variable,
2412 allow it to be overridden with the EMACS_TERM variable
2413 before attempting to translate the logical name TERM. As a last
2414 resort, ask for VAX C's special idea of the TERM variable. */
2421 static char buf
[256];
2422 static struct dsc$descriptor_s equiv
2423 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2424 static struct dsc$descriptor_s d_name
2425 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2428 if (!strcmp (name
, "TERM"))
2430 val
= (char *) getenv ("EMACS_TERM");
2435 d_name
.dsc$w_length
= strlen (name
);
2436 d_name
.dsc$a_pointer
= name
;
2437 if (LIB$
SYS_TRNLOG (&d_name
, &eqlen
, &equiv
) == 1)
2439 char *str
= (char *) xmalloc (eqlen
+ 1);
2440 bcopy (buf
, str
, eqlen
);
2442 /* This is a storage leak, but a pain to fix. With luck,
2443 no one will ever notice. */
2446 return (char *) getenv (name
);
2451 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2452 to force a call on the debugger from within the image. */
2457 LIB$
SIGNAL (SS$_DEBUG
);
2463 #ifdef LINK_CRTL_SHARE
2464 #ifdef SHAREABLE_LIB_BUG
2465 /* Variables declared noshare and initialized in sharable libraries
2466 cannot be shared. The VMS linker incorrectly forces you to use a private
2467 version which is uninitialized... If not for this "feature", we
2468 could use the C library definition of sys_nerr and sys_errlist. */
2470 char *sys_errlist
[] =
2474 "no such file or directory",
2476 "interrupted system call",
2478 "no such device or address",
2479 "argument list too long",
2480 "exec format error",
2483 "no more processes",
2484 "not enough memory",
2485 "permission denied",
2487 "block device required",
2488 "mount devices busy",
2490 "cross-device link",
2495 "file table overflow",
2496 "too many open files",
2500 "no space left on device",
2502 "read-only file system",
2508 "vax/vms specific error code nontranslatable error"
2510 #endif /* SHAREABLE_LIB_BUG */
2511 #endif /* LINK_CRTL_SHARE */
2514 #ifdef INTERRUPTIBLE_OPEN
2518 sys_open (path
, oflag
, mode
)
2522 register int rtnval
;
2524 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2525 && (errno
== EINTR
));
2529 #endif /* INTERRUPTIBLE_OPEN */
2531 #ifdef INTERRUPTIBLE_CLOSE
2536 register int rtnval
;
2538 while ((rtnval
= close (fd
)) == -1
2539 && (errno
== EINTR
));
2543 #endif /* INTERRUPTIBLE_CLOSE */
2545 #ifdef INTERRUPTIBLE_IO
2548 sys_read (fildes
, buf
, nbyte
)
2553 register int rtnval
;
2555 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2556 && (errno
== EINTR
));
2561 sys_write (fildes
, buf
, nbyte
)
2566 register int rtnval
;
2568 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2569 && (errno
== EINTR
));
2573 #endif /* INTERRUPTIBLE_IO */
2578 * Substitute fork for vfork on USG flavors.
2586 #endif /* not HAVE_VFORK */
2590 * All of the following are for USG.
2592 * On USG systems the system calls are INTERRUPTIBLE by signals
2593 * that the user program has elected to catch. Thus the system call
2594 * must be retried in these cases. To handle this without massive
2595 * changes in the source code, we remap the standard system call names
2596 * to names for our own functions in sysdep.c that do the system call
2597 * with retries. Actually, for portability reasons, it is good
2598 * programming practice, as this example shows, to limit all actual
2599 * system calls to a single occurrence in the source. Sure, this
2600 * adds an extra level of function call overhead but it is almost
2601 * always negligible. Fred Fish, Unisoft Systems Inc.
2604 #ifndef HAVE_SYS_SIGLIST
2605 char *sys_siglist
[NSIG
+ 1] =
2608 /* AIX has changed the signals a bit */
2609 "bogus signal", /* 0 */
2610 "hangup", /* 1 SIGHUP */
2611 "interrupt", /* 2 SIGINT */
2612 "quit", /* 3 SIGQUIT */
2613 "illegal instruction", /* 4 SIGILL */
2614 "trace trap", /* 5 SIGTRAP */
2615 "IOT instruction", /* 6 SIGIOT */
2616 "crash likely", /* 7 SIGDANGER */
2617 "floating point exception", /* 8 SIGFPE */
2618 "kill", /* 9 SIGKILL */
2619 "bus error", /* 10 SIGBUS */
2620 "segmentation violation", /* 11 SIGSEGV */
2621 "bad argument to system call", /* 12 SIGSYS */
2622 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2623 "alarm clock", /* 14 SIGALRM */
2624 "software termination signum", /* 15 SIGTERM */
2625 "user defined signal 1", /* 16 SIGUSR1 */
2626 "user defined signal 2", /* 17 SIGUSR2 */
2627 "death of a child", /* 18 SIGCLD */
2628 "power-fail restart", /* 19 SIGPWR */
2629 "bogus signal", /* 20 */
2630 "bogus signal", /* 21 */
2631 "bogus signal", /* 22 */
2632 "bogus signal", /* 23 */
2633 "bogus signal", /* 24 */
2634 "LAN I/O interrupt", /* 25 SIGAIO */
2635 "PTY I/O interrupt", /* 26 SIGPTY */
2636 "I/O intervention required", /* 27 SIGIOINT */
2637 "HFT grant", /* 28 SIGGRANT */
2638 "HFT retract", /* 29 SIGRETRACT */
2639 "HFT sound done", /* 30 SIGSOUND */
2640 "HFT input ready", /* 31 SIGMSG */
2642 "bogus signal", /* 0 */
2643 "hangup", /* 1 SIGHUP */
2644 "interrupt", /* 2 SIGINT */
2645 "quit", /* 3 SIGQUIT */
2646 "illegal instruction", /* 4 SIGILL */
2647 "trace trap", /* 5 SIGTRAP */
2648 "IOT instruction", /* 6 SIGIOT */
2649 "EMT instruction", /* 7 SIGEMT */
2650 "floating point exception", /* 8 SIGFPE */
2651 "kill", /* 9 SIGKILL */
2652 "bus error", /* 10 SIGBUS */
2653 "segmentation violation", /* 11 SIGSEGV */
2654 "bad argument to system call", /* 12 SIGSYS */
2655 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2656 "alarm clock", /* 14 SIGALRM */
2657 "software termination signum", /* 15 SIGTERM */
2658 "user defined signal 1", /* 16 SIGUSR1 */
2659 "user defined signal 2", /* 17 SIGUSR2 */
2660 "death of a child", /* 18 SIGCLD */
2661 "power-fail restart", /* 19 SIGPWR */
2662 #endif /* not AIX */
2665 #endif /* HAVE_SYS_SIGLIST */
2668 * Warning, this function may not duplicate 4.2 action properly
2669 * under error conditions.
2673 /* In 4.1, param.h fails to define this. */
2674 #define MAXPATHLEN 1024
2683 char *npath
, *spath
;
2684 extern char *getcwd ();
2686 BLOCK_INPUT
; /* getcwd uses malloc */
2687 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2688 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2689 up to first slash. Should be harmless on other systems. */
2690 while (*npath
&& *npath
!= '/')
2692 strcpy (pathname
, npath
);
2693 free (spath
); /* getcwd uses malloc */
2698 #endif /* HAVE_GETWD */
2701 * Emulate rename using unlink/link. Note that this is
2702 * only partially correct. Also, doesn't enforce restriction
2703 * that files be of same type (regular->regular, dir->dir, etc).
2712 if (access (from
, 0) == 0)
2715 if (link (from
, to
) == 0)
2716 if (unlink (from
) == 0)
2724 #ifdef MISSING_UTIMES
2726 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2735 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2736 utimbuf structure defined anywhere but in the man page. */
2746 struct timeval tvp
[];
2749 utb
.actime
= tvp
[0].tv_sec
;
2750 utb
.modtime
= tvp
[1].tv_sec
;
2753 #endif /* IRIS_UTIME */
2759 /* HPUX curses library references perror, but as far as we know
2760 it won't be called. Anyway this definition will do for now. */
2766 #endif /* not HAVE_PERROR */
2772 * Emulate BSD dup2. First close newd if it already exists.
2773 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2774 * until we are, then close the unsuccessful ones.
2781 register int fd
, ret
;
2786 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2788 error ("can't dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2795 ret
= dup2 (old
,new);
2801 #endif /* not HAVE_DUP2 */
2804 * Gettimeofday. Simulate as much as possible. Only accurate
2805 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2806 * Only needed when subprocesses are defined.
2811 #ifndef HAVE_GETTIMEOFDAY
2815 gettimeofday (tp
, tzp
)
2817 struct timezone
*tzp
;
2819 extern long time ();
2821 tp
->tv_sec
= time ((long *)0);
2824 tzp
->tz_minuteswest
= -1;
2830 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
2833 * This function will go away as soon as all the stubs fixed. (fnf)
2839 printf ("%s not yet implemented\r\n", badfunc
);
2848 char *sys_siglist
[NSIG
+ 1] =
2850 "null signal", /* 0 SIGNULL */
2851 "hangup", /* 1 SIGHUP */
2852 "interrupt", /* 2 SIGINT */
2853 "quit", /* 3 SIGQUIT */
2854 "illegal instruction", /* 4 SIGILL */
2855 "trace trap", /* 5 SIGTRAP */
2856 "abort termination", /* 6 SIGABRT */
2857 "SIGEMT", /* 7 SIGEMT */
2858 "floating point exception", /* 8 SIGFPE */
2859 "kill", /* 9 SIGKILL */
2860 "bus error", /* 10 SIGBUS */
2861 "segmentation violation", /* 11 SIGSEGV */
2862 "bad argument to system call", /* 12 SIGSYS */
2863 "write on a pipe with no reader", /* 13 SIGPIPE */
2864 "alarm clock", /* 14 SIGALRM */
2865 "software termination signal", /* 15 SIGTERM */
2866 "user defined signal 1", /* 16 SIGUSR1 */
2867 "user defined signal 2", /* 17 SIGUSR2 */
2868 "child stopped or terminated", /* 18 SIGCLD */
2869 "power-fail restart", /* 19 SIGPWR */
2870 "window size changed", /* 20 SIGWINCH */
2871 "undefined", /* 21 */
2872 "pollable event occurred", /* 22 SIGPOLL */
2873 "sendable stop signal not from tty", /* 23 SIGSTOP */
2874 "stop signal from tty", /* 24 SIGSTP */
2875 "continue a stopped process", /* 25 SIGCONT */
2876 "attempted background tty read", /* 26 SIGTTIN */
2877 "attempted background tty write", /* 27 SIGTTOU */
2878 "undefined", /* 28 */
2879 "undefined", /* 29 */
2880 "undefined", /* 30 */
2881 "undefined", /* 31 */
2882 "undefined", /* 32 */
2883 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2884 "I/O is possible", /* 34 SIGIO */
2885 "exceeded cpu time limit", /* 35 SIGXCPU */
2886 "exceeded file size limit", /* 36 SIGXFSZ */
2887 "virtual time alarm", /* 37 SIGVTALRM */
2888 "profiling time alarm", /* 38 SIGPROF */
2889 "undefined", /* 39 */
2890 "file record locks revoked", /* 40 SIGLOST */
2891 "undefined", /* 41 */
2892 "undefined", /* 42 */
2893 "undefined", /* 43 */
2894 "undefined", /* 44 */
2895 "undefined", /* 45 */
2896 "undefined", /* 46 */
2897 "undefined", /* 47 */
2898 "undefined", /* 48 */
2899 "undefined", /* 49 */
2900 "undefined", /* 50 */
2901 "undefined", /* 51 */
2902 "undefined", /* 52 */
2903 "undefined", /* 53 */
2904 "undefined", /* 54 */
2905 "undefined", /* 55 */
2906 "undefined", /* 56 */
2907 "undefined", /* 57 */
2908 "undefined", /* 58 */
2909 "undefined", /* 59 */
2910 "undefined", /* 60 */
2911 "undefined", /* 61 */
2912 "undefined", /* 62 */
2913 "undefined", /* 63 */
2914 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2920 /* Directory routines for systems that don't have them. */
2922 #ifdef SYSV_SYSTEM_DIR
2926 #ifndef HAVE_CLOSEDIR
2929 register DIR *dirp
; /* stream from opendir */
2931 sys_close (dirp
->dd_fd
);
2933 /* Some systems (like Solaris) allocate the buffer and the DIR all
2934 in one block. Why in the world are we freeing this ourselves
2936 #if ! (defined (sun) && defined (USG5_4))
2937 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2939 xfree ((char *) dirp
);
2941 #endif /* not HAVE_CLOSEDIR */
2942 #endif /* SYSV_SYSTEM_DIR */
2944 #ifdef NONSYSTEM_DIR_LIBRARY
2948 char *filename
; /* name of directory */
2950 register DIR *dirp
; /* -> malloc'ed storage */
2951 register int fd
; /* file descriptor for read */
2952 struct stat sbuf
; /* result of fstat */
2954 fd
= sys_open (filename
, 0);
2959 if (fstat (fd
, &sbuf
) < 0
2960 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2961 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2965 return 0; /* bad luck today */
2970 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2977 register DIR *dirp
; /* stream from opendir */
2979 sys_close (dirp
->dd_fd
);
2980 xfree ((char *) dirp
);
2988 ino_t od_ino
; /* inode */
2989 char od_name
[DIRSIZ
]; /* filename */
2991 #endif /* not VMS */
2993 struct direct dir_static
; /* simulated directory contents */
2998 register DIR *dirp
; /* stream from opendir */
3001 register struct olddir
*dp
; /* -> directory data */
3003 register struct dir$_name
*dp
; /* -> directory data */
3004 register struct dir$_version
*dv
; /* -> version data */
3009 if (dirp
->dd_loc
>= dirp
->dd_size
)
3010 dirp
->dd_loc
= dirp
->dd_size
= 0;
3012 if (dirp
->dd_size
== 0 /* refill buffer */
3013 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3017 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
3018 dirp
->dd_loc
+= sizeof (struct olddir
);
3020 if (dp
->od_ino
!= 0) /* not deleted entry */
3022 dir_static
.d_ino
= dp
->od_ino
;
3023 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
3024 dir_static
.d_name
[DIRSIZ
] = '\0';
3025 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3026 dir_static
.d_reclen
= sizeof (struct direct
)
3028 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3029 return &dir_static
; /* -> simulated structure */
3032 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3033 if (dirp
->dd_loc
== 0)
3034 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
3035 : dp
->dir$b_namecount
;
3036 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
3037 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3038 dir_static
.d_namlen
= dp
->dir$b_namecount
;
3039 dir_static
.d_reclen
= sizeof (struct direct
)
3041 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3042 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3043 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
3044 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
3051 /* readdirver is just like readdir except it returns all versions of a file
3052 as separate entries. */
3057 register DIR *dirp
; /* stream from opendir */
3059 register struct dir$_name
*dp
; /* -> directory data */
3060 register struct dir$_version
*dv
; /* -> version data */
3062 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
3063 dirp
->dd_loc
= dirp
->dd_size
= 0;
3065 if (dirp
->dd_size
== 0 /* refill buffer */
3066 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
3069 dp
= (struct dir$_name
*) dirp
->dd_buf
;
3070 if (dirp
->dd_loc
== 0)
3071 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
3072 : dp
->dir$b_namecount
;
3073 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
3074 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
3075 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
3076 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
3077 dir_static
.d_ino
= dv
->dir$w_fid_num
;
3078 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
3079 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
3080 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
3086 #endif /* NONSYSTEM_DIR_LIBRARY */
3089 /* mkdir and rmdir functions, for systems which don't have them. */
3093 * Written by Robert Rother, Mariah Corporation, August 1985.
3095 * If you want it, it's yours. All I ask in return is that if you
3096 * figure out how to do this in a Bourne Shell script you send me
3098 * sdcsvax!rmr or rmr@uscd
3100 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3101 * subroutine. 11Mar86; hoptoad!gnu
3103 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3104 * subroutine didn't return EEXIST. It does now.
3111 mkdir (dpath
, dmode
)
3116 struct stat statbuf
;
3118 if (stat (dpath
, &statbuf
) == 0)
3120 errno
= EEXIST
; /* Stat worked, so it already exists */
3124 /* If stat fails for a reason other than non-existence, return error */
3125 if (errno
!= ENOENT
)
3128 switch (cpid
= fork ())
3131 case -1: /* Error in fork() */
3132 return (-1); /* Errno is set already */
3134 case 0: /* Child process */
3136 * Cheap hack to set mode of new directory. Since this
3137 * child process is going away anyway, we zap its umask.
3138 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3139 * directory. Does anybody care?
3141 status
= umask (0); /* Get current umask */
3142 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
3143 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
3144 _exit (-1); /* Can't exec /bin/mkdir */
3146 default: /* Parent process */
3147 while (cpid
!= wait (&status
)); /* Wait for kid to finish */
3150 if (WIFSIGNALED (status
) || WEXITSTATUS (status
) != 0)
3152 errno
= EIO
; /* We don't know why, but */
3153 return -1; /* /bin/mkdir failed */
3158 #endif /* not HAVE_MKDIR */
3166 struct stat statbuf
;
3168 if (stat (dpath
, &statbuf
) != 0)
3170 /* Stat just set errno. We don't have to */
3174 switch (cpid
= fork ())
3177 case -1: /* Error in fork() */
3178 return (-1); /* Errno is set already */
3180 case 0: /* Child process */
3181 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
3182 _exit (-1); /* Can't exec /bin/mkdir */
3184 default: /* Parent process */
3185 while (cpid
!= wait (&status
)); /* Wait for kid to finish */
3188 if (WIFSIGNALED (status
) || WEXITSTATUS (status
) != 0)
3190 errno
= EIO
; /* We don't know why, but */
3191 return -1; /* /bin/mkdir failed */
3196 #endif /* !HAVE_RMDIR */
3200 /* Functions for VMS */
3202 #include "vms-pwd.h"
3207 /* Return as a string the VMS error string pertaining to STATUS.
3208 Reuses the same static buffer each time it is called. */
3212 int status
; /* VMS status code */
3216 static char buf
[257];
3218 bufadr
[0] = sizeof buf
- 1;
3219 bufadr
[1] = (int) buf
;
3220 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
3221 return "untranslatable VMS error status";
3229 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3230 * not work correctly. (It also doesn't work well in version 2.3.)
3235 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3236 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3240 unsigned short s_buflen
;
3241 unsigned short s_code
;
3243 unsigned short *s_retlenadr
;
3247 #define buflen s.s_buflen
3248 #define code s.s_code
3249 #define bufadr s.s_bufadr
3250 #define retlenadr s.s_retlenadr
3252 #define R_OK 4 /* test for read permission */
3253 #define W_OK 2 /* test for write permission */
3254 #define X_OK 1 /* test for execute (search) permission */
3255 #define F_OK 0 /* test for presence of file */
3258 sys_access (path
, mode
)
3262 static char *user
= NULL
;
3265 /* translate possible directory spec into .DIR file name, so brain-dead
3266 * access can treat the directory like a file. */
3267 if (directory_file_name (path
, dir_fn
))
3271 return access (path
, mode
);
3272 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
3278 unsigned short int dummy
;
3280 static int constant
= ACL$C_FILE
;
3281 DESCRIPTOR (path_desc
, path
);
3282 DESCRIPTOR (user_desc
, user
);
3286 if ((mode
& X_OK
) && ((stat
= access (path
, mode
)) < 0 || mode
== X_OK
))
3289 acces
|= CHP$M_READ
;
3291 acces
|= CHP$M_WRITE
;
3292 itemlst
[0].buflen
= sizeof (int);
3293 itemlst
[0].code
= CHP$_FLAGS
;
3294 itemlst
[0].bufadr
= (char *) &flags
;
3295 itemlst
[0].retlenadr
= &dummy
;
3296 itemlst
[1].buflen
= sizeof (int);
3297 itemlst
[1].code
= CHP$_ACCESS
;
3298 itemlst
[1].bufadr
= (char *) &acces
;
3299 itemlst
[1].retlenadr
= &dummy
;
3300 itemlst
[2].end
= CHP$_END
;
3301 stat
= SYS$
CHECK_ACCESS (&constant
, &path_desc
, &user_desc
, itemlst
);
3302 return stat
== SS$_NORMAL
? 0 : -1;
3306 #else /* not VMS4_4 */
3309 #define ACE$M_WRITE 2
3310 #define ACE$C_KEYID 1
3312 static unsigned short memid
, grpid
;
3313 static unsigned int uic
;
3315 /* Called from init_sys_modes, so it happens not very often
3316 but at least each time Emacs is loaded. */
3317 sys_access_reinit ()
3323 sys_access (filename
, type
)
3329 int status
, size
, i
, typecode
, acl_controlled
;
3330 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3331 union prvdef prvmask
;
3333 /* Get UIC and GRP values for protection checking. */
3336 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3339 memid
= uic
& 0xFFFF;
3343 if (type
!= 2) /* not checking write access */
3344 return access (filename
, type
);
3346 /* Check write protection. */
3348 #define CHECKPRIV(bit) (prvmask.bit)
3349 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3351 /* Find privilege bits */
3352 status
= SYS$
SETPRV (0, 0, 0, prvmask
);
3354 error ("Unable to find privileges: %s", vmserrstr (status
));
3355 if (CHECKPRIV (PRV$V_BYPASS
))
3356 return 0; /* BYPASS enabled */
3358 fab
.fab$b_fac
= FAB$M_GET
;
3359 fab
.fab$l_fna
= filename
;
3360 fab
.fab$b_fns
= strlen (filename
);
3361 fab
.fab$l_xab
= &xab
;
3362 xab
= cc$rms_xabpro
;
3363 xab
.xab$l_aclbuf
= aclbuf
;
3364 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3365 status
= SYS$
OPEN (&fab
, 0, 0);
3368 SYS$
CLOSE (&fab
, 0, 0);
3369 /* Check system access */
3370 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
3372 /* Check ACL entries, if any */
3374 if (xab
.xab$w_acllen
> 0)
3377 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3378 while (*aclptr
&& aclptr
< aclend
)
3380 size
= (*aclptr
& 0xff) / 4;
3381 typecode
= (*aclptr
>> 8) & 0xff;
3382 if (typecode
== ACE$C_KEYID
)
3383 for (i
= size
- 1; i
> 1; i
--)
3384 if (aclptr
[i
] == uic
)
3387 if (aclptr
[1] & ACE$M_WRITE
)
3388 return 0; /* Write access through ACL */
3390 aclptr
= &aclptr
[size
];
3392 if (acl_controlled
) /* ACL specified, prohibits write access */
3395 /* No ACL entries specified, check normal protection */
3396 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3398 if (WRITEABLE (XAB$V_GRP
) &&
3399 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3400 return 0; /* Group writeable */
3401 if (WRITEABLE (XAB$V_OWN
) &&
3402 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3403 return 0; /* Owner writeable */
3405 return -1; /* Not writeable */
3407 #endif /* not VMS4_4 */
3410 static char vtbuf
[NAM$C_MAXRSS
+1];
3412 /* translate a vms file spec to a unix path */
3414 sys_translate_vms (vfile
)
3425 /* leading device or logical name is a root directory */
3426 if (p
= strchr (vfile
, ':'))
3435 if (*p
== '[' || *p
== '<')
3437 while (*++vfile
!= *p
+ 2)
3441 if (vfile
[-1] == *p
)
3464 static char utbuf
[NAM$C_MAXRSS
+1];
3466 /* translate a unix path to a VMS file spec */
3468 sys_translate_unix (ufile
)
3491 if (index (&ufile
[1], '/'))
3498 if (index (&ufile
[1], '/'))
3505 if (strncmp (ufile
, "./", 2) == 0)
3512 ufile
++; /* skip the dot */
3513 if (index (&ufile
[1], '/'))
3518 else if (strncmp (ufile
, "../", 3) == 0)
3526 ufile
+= 2; /* skip the dots */
3527 if (index (&ufile
[1], '/'))
3552 extern char *getcwd ();
3554 #define MAXPATHLEN 1024
3556 ptr
= xmalloc (MAXPATHLEN
);
3557 getcwd (ptr
, MAXPATHLEN
);
3558 strcpy (pathname
, ptr
);
3566 long item_code
= JPI$_OWNER
;
3567 unsigned long parent_id
;
3570 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3573 vaxc$errno
= status
;
3583 return (getgid () << 16) | getuid ();
3587 sys_read (fildes
, buf
, nbyte
)
3592 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3597 sys_write (fildes
, buf
, nbyte
)
3602 register int nwrote
, rtnval
= 0;
3604 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3610 return rtnval
? rtnval
: -1;
3611 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3612 return rtnval
? rtnval
: -1;
3613 return (rtnval
+ nwrote
);
3618 * VAX/VMS VAX C RTL really loses. It insists that records
3619 * end with a newline (carriage return) character, and if they
3620 * don't it adds one (nice of it isn't it!)
3622 * Thus we do this stupidity below.
3626 sys_write (fildes
, buf
, nbytes
)
3629 unsigned int nbytes
;
3636 fstat (fildes
, &st
);
3642 /* Handle fixed-length files with carriage control. */
3643 if (st
.st_fab_rfm
== FAB$C_FIX
3644 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3646 len
= st
.st_fab_mrs
;
3647 retval
= write (fildes
, p
, min (len
, nbytes
));
3650 retval
++; /* This skips the implied carriage control */
3654 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3655 while (*e
!= '\n' && e
> p
) e
--;
3656 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3657 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3659 retval
= write (fildes
, p
, len
);
3670 /* Create file NEW copying its attributes from file OLD. If
3671 OLD is 0 or does not exist, create based on the value of
3674 /* Protection value the file should ultimately have.
3675 Set by create_copy_attrs, and use by rename_sansversions. */
3676 static unsigned short int fab_final_pro
;
3679 creat_copy_attrs (old
, new)
3682 struct FAB fab
= cc$rms_fab
;
3683 struct XABPRO xabpro
;
3684 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3685 extern int vms_stmlf_recfm
;
3689 fab
.fab$b_fac
= FAB$M_GET
;
3690 fab
.fab$l_fna
= old
;
3691 fab
.fab$b_fns
= strlen (old
);
3692 fab
.fab$l_xab
= (char *) &xabpro
;
3693 xabpro
= cc$rms_xabpro
;
3694 xabpro
.xab$l_aclbuf
= aclbuf
;
3695 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3696 /* Call $OPEN to fill in the fab & xabpro fields. */
3697 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3699 SYS$
CLOSE (&fab
, 0, 0);
3700 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3701 if (xabpro
.xab$w_acllen
> 0)
3703 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3704 /* If the acl buffer was too short, redo open with longer one.
3705 Wouldn't need to do this if there were some system imposed
3706 limit on the size of an ACL, but I can't find any such. */
3708 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3709 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3710 if (SYS$
OPEN (&fab
, 0, 0) & 1)
3711 SYS$
CLOSE (&fab
, 0, 0);
3717 xabpro
.xab$l_aclbuf
= 0;
3722 fab
.fab$l_fna
= new;
3723 fab
.fab$b_fns
= strlen (new);
3727 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3728 fab
.fab$b_rat
= FAB$M_CR
;
3731 /* Set the file protections such that we will be able to manipulate
3732 this file. Once we are done writing and renaming it, we will set
3733 the protections back. */
3735 fab_final_pro
= xabpro
.xab$w_pro
;
3737 SYS$
SETDFPROT (0, &fab_final_pro
);
3738 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3740 /* Create the new file with either default attrs or attrs copied
3742 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3744 SYS$
CLOSE (&fab
, 0, 0);
3745 /* As this is a "replacement" for creat, return a file descriptor
3746 opened for writing. */
3747 return open (new, O_WRONLY
);
3752 #include <varargs.h>
3755 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3759 sys_creat (va_alist
)
3762 va_list list_incrementer
;
3765 int rfd
; /* related file descriptor */
3766 int fd
; /* Our new file descriptor */
3773 extern int vms_stmlf_recfm
;
3776 va_start (list_incrementer
);
3777 name
= va_arg (list_incrementer
, char *);
3778 mode
= va_arg (list_incrementer
, int);
3780 rfd
= va_arg (list_incrementer
, int);
3781 va_end (list_incrementer
);
3784 /* Use information from the related file descriptor to set record
3785 format of the newly created file. */
3786 fstat (rfd
, &st_buf
);
3787 switch (st_buf
.st_fab_rfm
)
3790 strcpy (rfm
, "rfm = fix");
3791 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3792 strcpy (rat
, "rat = ");
3793 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3795 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3796 strcat (rat
, "ftn");
3797 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3798 strcat (rat
, "prn");
3799 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3800 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3801 strcat (rat
, ", blk");
3803 strcat (rat
, "blk");
3804 return creat (name
, 0, rfm
, rat
, mrs
);
3807 strcpy (rfm
, "rfm = vfc");
3808 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3809 strcpy (rat
, "rat = ");
3810 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3812 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3813 strcat (rat
, "ftn");
3814 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3815 strcat (rat
, "prn");
3816 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3817 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3818 strcat (rat
, ", blk");
3820 strcat (rat
, "blk");
3821 return creat (name
, 0, rfm
, rat
, fsz
);
3824 strcpy (rfm
, "rfm = stm");
3828 strcpy (rfm
, "rfm = stmcr");
3832 strcpy (rfm
, "rfm = stmlf");
3836 strcpy (rfm
, "rfm = udf");
3840 strcpy (rfm
, "rfm = var");
3843 strcpy (rat
, "rat = ");
3844 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3846 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3847 strcat (rat
, "ftn");
3848 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3849 strcat (rat
, "prn");
3850 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3851 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3852 strcat (rat
, ", blk");
3854 strcat (rat
, "blk");
3858 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3859 strcpy (rat
, "rat=cr");
3861 /* Until the VAX C RTL fixes the many bugs with modes, always use
3862 mode 0 to get the user's default protection. */
3863 fd
= creat (name
, 0, rfm
, rat
);
3864 if (fd
< 0 && errno
== EEXIST
)
3866 if (unlink (name
) < 0)
3867 report_file_error ("delete", build_string (name
));
3868 fd
= creat (name
, 0, rfm
, rat
);
3874 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3875 sys_fwrite (ptr
, size
, num
, fp
)
3876 register char * ptr
;
3879 register int tot
= num
* size
;
3886 * The VMS C library routine creat actually creates a new version of an
3887 * existing file rather than truncating the old version. There are times
3888 * when this is not the desired behavior, for instance, when writing an
3889 * auto save file (you only want one version), or when you don't have
3890 * write permission in the directory containing the file (but the file
3891 * itself is writable). Hence this routine, which is equivalent to
3892 * "close (creat (fn, 0));" on Unix if fn already exists.
3898 struct FAB xfab
= cc$rms_fab
;
3899 struct RAB xrab
= cc$rms_rab
;
3902 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3903 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3904 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3905 xfab
.fab$l_fna
= fn
;
3906 xfab
.fab$b_fns
= strlen (fn
);
3907 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3909 xrab
.rab$l_fab
= &xfab
;
3911 /* This gibberish opens the file, positions to the first record, and
3912 deletes all records from there until the end of file. */
3913 if ((SYS$
OPEN (&xfab
) & 01) == 01)
3915 if ((SYS$
CONNECT (&xrab
) & 01) == 01 &&
3916 (SYS$
FIND (&xrab
) & 01) == 01 &&
3917 (SYS$
TRUNCATE (&xrab
) & 01) == 01)
3928 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3929 SYSPRV or a readable SYSUAF.DAT. */
3935 * Routine to read the VMS User Authorization File and return
3936 * a specific user's record.
3939 static struct UAF retuaf
;
3942 get_uaf_name (uname
)
3949 uaf_fab
= cc$rms_fab
;
3950 uaf_rab
= cc$rms_rab
;
3951 /* initialize fab fields */
3952 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3953 uaf_fab
.fab$b_fns
= 21;
3954 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3955 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3956 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3957 /* initialize rab fields */
3958 uaf_rab
.rab$l_fab
= &uaf_fab
;
3959 /* open the User Authorization File */
3960 status
= SYS$
OPEN (&uaf_fab
);
3964 vaxc$errno
= status
;
3967 status
= SYS$
CONNECT (&uaf_rab
);
3971 vaxc$errno
= status
;
3974 /* read the requested record - index is in uname */
3975 uaf_rab
.rab$l_kbf
= uname
;
3976 uaf_rab
.rab$b_ksz
= strlen (uname
);
3977 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3978 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3979 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3980 status
= SYS$
GET (&uaf_rab
);
3984 vaxc$errno
= status
;
3987 /* close the User Authorization File */
3988 status
= SYS$
DISCONNECT (&uaf_rab
);
3992 vaxc$errno
= status
;
3995 status
= SYS$
CLOSE (&uaf_fab
);
3999 vaxc$errno
= status
;
4013 uaf_fab
= cc$rms_fab
;
4014 uaf_rab
= cc$rms_rab
;
4015 /* initialize fab fields */
4016 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
4017 uaf_fab
.fab$b_fns
= 21;
4018 uaf_fab
.fab$b_fac
= FAB$M_GET
;
4019 uaf_fab
.fab$b_org
= FAB$C_IDX
;
4020 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
4021 /* initialize rab fields */
4022 uaf_rab
.rab$l_fab
= &uaf_fab
;
4023 /* open the User Authorization File */
4024 status
= SYS$
OPEN (&uaf_fab
);
4028 vaxc$errno
= status
;
4031 status
= SYS$
CONNECT (&uaf_rab
);
4035 vaxc$errno
= status
;
4038 /* read the requested record - index is in uic */
4039 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
4040 uaf_rab
.rab$l_kbf
= (char *) &uic
;
4041 uaf_rab
.rab$b_ksz
= sizeof uic
;
4042 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
4043 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
4044 uaf_rab
.rab$w_usz
= sizeof retuaf
;
4045 status
= SYS$
GET (&uaf_rab
);
4049 vaxc$errno
= status
;
4052 /* close the User Authorization File */
4053 status
= SYS$
DISCONNECT (&uaf_rab
);
4057 vaxc$errno
= status
;
4060 status
= SYS$
CLOSE (&uaf_fab
);
4064 vaxc$errno
= status
;
4070 static struct passwd retpw
;
4078 /* copy these out first because if the username is 32 chars, the next
4079 section will overwrite the first byte of the UIC */
4080 retpw
.pw_uid
= up
->uaf$w_mem
;
4081 retpw
.pw_gid
= up
->uaf$w_grp
;
4083 /* I suppose this is not the best sytle, to possibly overwrite one
4084 byte beyond the end of the field, but what the heck... */
4085 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
4086 while (ptr
[-1] == ' ')
4089 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
4091 /* the rest of these are counted ascii strings */
4092 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
4093 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
4094 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
4095 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
4096 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
4097 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
4098 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
4099 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
4103 #else /* not READ_SYSUAF */
4104 static struct passwd retpw
;
4105 #endif /* not READ_SYSUAF */
4116 unsigned char * full
;
4117 #endif /* READ_SYSUAF */
4122 if ('a' <= *ptr
&& *ptr
<= 'z')
4127 if (!(up
= get_uaf_name (name
)))
4129 return cnv_uaf_pw (up
);
4131 if (strcmp (name
, getenv ("USER")) == 0)
4133 retpw
.pw_uid
= getuid ();
4134 retpw
.pw_gid
= getgid ();
4135 strcpy (retpw
.pw_name
, name
);
4136 if (full
= egetenv ("FULLNAME"))
4137 strcpy (retpw
.pw_gecos
, full
);
4139 *retpw
.pw_gecos
= '\0';
4140 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
4141 *retpw
.pw_shell
= '\0';
4146 #endif /* not READ_SYSUAF */
4156 if (!(up
= get_uaf_uic (uid
)))
4158 return cnv_uaf_pw (up
);
4160 if (uid
== sys_getuid ())
4161 return getpwnam (egetenv ("USER"));
4164 #endif /* not READ_SYSUAF */
4167 /* return total address space available to the current process. This is
4168 the sum of the current p0 size, p1 size and free page table entries
4173 unsigned long free_pages
;
4174 unsigned long frep0va
;
4175 unsigned long frep1va
;
4178 item_code
= JPI$_FREPTECNT
;
4179 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
4182 vaxc$errno
= status
;
4187 item_code
= JPI$_FREP0VA
;
4188 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
4191 vaxc$errno
= status
;
4194 item_code
= JPI$_FREP1VA
;
4195 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
4198 vaxc$errno
= status
;
4202 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
4205 define_logical_name (varname
, string
)
4209 struct dsc$descriptor_s strdsc
=
4210 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
4211 struct dsc$descriptor_s envdsc
=
4212 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4213 struct dsc$descriptor_s lnmdsc
=
4214 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4216 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
4219 delete_logical_name (varname
)
4222 struct dsc$descriptor_s envdsc
=
4223 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
4224 struct dsc$descriptor_s lnmdsc
=
4225 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
4227 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
4238 error ("execvp system call not implemented");
4246 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
4247 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
4248 char from_esn
[NAM$C_MAXRSS
];
4249 char to_esn
[NAM$C_MAXRSS
];
4251 from_fab
.fab$l_fna
= from
;
4252 from_fab
.fab$b_fns
= strlen (from
);
4253 from_fab
.fab$l_nam
= &from_nam
;
4254 from_fab
.fab$l_fop
= FAB$M_NAM
;
4256 from_nam
.nam$l_esa
= from_esn
;
4257 from_nam
.nam$b_ess
= sizeof from_esn
;
4259 to_fab
.fab$l_fna
= to
;
4260 to_fab
.fab$b_fns
= strlen (to
);
4261 to_fab
.fab$l_nam
= &to_nam
;
4262 to_fab
.fab$l_fop
= FAB$M_NAM
;
4264 to_nam
.nam$l_esa
= to_esn
;
4265 to_nam
.nam$b_ess
= sizeof to_esn
;
4267 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4273 if (status
== RMS$_DEV
)
4277 vaxc$errno
= status
;
4282 /* This function renames a file like `rename', but it strips
4283 the version number from the "to" filename, such that the "to" file is
4284 will always be a new version. It also sets the file protection once it is
4285 finished. The protection that we will use is stored in fab_final_pro,
4286 and was set when we did a creat_copy_attrs to create the file that we
4289 We could use the chmod function, but Eunichs uses 3 bits per user category
4290 to describe the protection, and VMS uses 4 (write and delete are separate
4291 bits). To maintain portability, the VMS implementation of `chmod' wires
4292 the W and D bits together. */
4295 static struct fibdef fib
; /* We need this initialized to zero */
4296 char vms_file_written
[NAM$C_MAXRSS
];
4299 rename_sans_version (from
,to
)
4306 struct FAB to_fab
= cc$rms_fab
;
4307 struct NAM to_nam
= cc$rms_nam
;
4308 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4309 struct dsc$descriptor fib_attr
[2]
4310 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4311 char to_esn
[NAM$C_MAXRSS
];
4313 $
DESCRIPTOR (disk
,to_esn
);
4315 to_fab
.fab$l_fna
= to
;
4316 to_fab
.fab$b_fns
= strlen (to
);
4317 to_fab
.fab$l_nam
= &to_nam
;
4318 to_fab
.fab$l_fop
= FAB$M_NAM
;
4320 to_nam
.nam$l_esa
= to_esn
;
4321 to_nam
.nam$b_ess
= sizeof to_esn
;
4323 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4325 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4326 *(to_nam
.nam$l_ver
) = '\0';
4328 stat
= rename (from
, to_esn
);
4332 strcpy (vms_file_written
, to_esn
);
4334 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4335 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4337 /* Now set the file protection to the correct value */
4338 SYS$
OPEN (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4340 /* Copy these fields into the fib */
4341 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4342 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4343 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4345 SYS$
CLOSE (&to_fab
, 0, 0);
4347 stat
= SYS$
ASSIGN (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4350 stat
= SYS$
QIOW (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4351 0, 0, 0, &fib_attr
, 0);
4354 stat
= SYS$
DASSGN (chan
);
4357 strcpy (vms_file_written
, to_esn
); /* We will write this to the terminal*/
4367 unsigned short fid
[3];
4368 char esa
[NAM$C_MAXRSS
];
4371 fab
.fab$l_fop
= FAB$M_OFP
;
4372 fab
.fab$l_fna
= file
;
4373 fab
.fab$b_fns
= strlen (file
);
4374 fab
.fab$l_nam
= &nam
;
4377 nam
.nam$l_esa
= esa
;
4378 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4380 status
= SYS$
PARSE (&fab
);
4381 if ((status
& 1) == 0)
4384 vaxc$errno
= status
;
4387 status
= SYS$
SEARCH (&fab
);
4388 if ((status
& 1) == 0)
4391 vaxc$errno
= status
;
4395 fid
[0] = nam
.nam$w_fid
[0];
4396 fid
[1] = nam
.nam$w_fid
[1];
4397 fid
[2] = nam
.nam$w_fid
[2];
4399 fab
.fab$l_fna
= new;
4400 fab
.fab$b_fns
= strlen (new);
4402 status
= SYS$
PARSE (&fab
);
4403 if ((status
& 1) == 0)
4406 vaxc$errno
= status
;
4410 nam
.nam$w_fid
[0] = fid
[0];
4411 nam
.nam$w_fid
[1] = fid
[1];
4412 nam
.nam$w_fid
[2] = fid
[2];
4414 nam
.nam$l_esa
= nam
.nam$l_name
;
4415 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4417 status
= SYS$
ENTER (&fab
);
4418 if ((status
& 1) == 0)
4421 vaxc$errno
= status
;
4431 printf ("%s not yet implemented\r\n", badfunc
);
4439 /* Arrange to return a range centered on zero. */
4440 return rand () - (1 << 30);
4451 /* Called from init_sys_modes. */
4456 /* If we're not on an HFT we shouldn't do any of this. We determine
4457 if we are on an HFT by trying to get an HFT error code. If this
4458 call fails, we're not on an HFT. */
4460 if (ioctl (0, HFQERROR
, &junk
) < 0)
4462 #else /* not IBMR2AIX */
4463 if (ioctl (0, HFQEIO
, 0) < 0)
4465 #endif /* not IBMR2AIX */
4467 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4468 as the rubout key's ASCII code. Here this is changed. The bug is that
4469 there's no way to determine the old mapping, so in reset_sys_modes
4470 we need to assume that the normal map had been present. Of course, this
4471 code also doesn't help if on a terminal emulator which doesn't understand
4475 struct hfkeymap keymap
;
4477 buf
.hf_bufp
= (char *)&keymap
;
4478 buf
.hf_buflen
= sizeof (keymap
);
4479 keymap
.hf_nkeys
= 2;
4480 keymap
.hfkey
[0].hf_kpos
= 15;
4481 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4483 keymap
.hfkey
[0].hf_keyidh
= '<';
4484 #else /* not IBMR2AIX */
4485 keymap
.hfkey
[0].hf_page
= '<';
4486 #endif /* not IBMR2AIX */
4487 keymap
.hfkey
[0].hf_char
= 127;
4488 keymap
.hfkey
[1].hf_kpos
= 15;
4489 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4491 keymap
.hfkey
[1].hf_keyidh
= '<';
4492 #else /* not IBMR2AIX */
4493 keymap
.hfkey
[1].hf_page
= '<';
4494 #endif /* not IBMR2AIX */
4495 keymap
.hfkey
[1].hf_char
= 127;
4496 hftctl (0, HFSKBD
, &buf
);
4498 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4500 line_ins_del_ok
= char_ins_del_ok
= 0;
4503 /* Reset the rubout key to backspace. */
4508 struct hfkeymap keymap
;
4512 if (ioctl (0, HFQERROR
, &junk
) < 0)
4514 #else /* not IBMR2AIX */
4515 if (ioctl (0, HFQEIO
, 0) < 0)
4517 #endif /* not IBMR2AIX */
4519 buf
.hf_bufp
= (char *)&keymap
;
4520 buf
.hf_buflen
= sizeof (keymap
);
4521 keymap
.hf_nkeys
= 2;
4522 keymap
.hfkey
[0].hf_kpos
= 15;
4523 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4525 keymap
.hfkey
[0].hf_keyidh
= '<';
4526 #else /* not IBMR2AIX */
4527 keymap
.hfkey
[0].hf_page
= '<';
4528 #endif /* not IBMR2AIX */
4529 keymap
.hfkey
[0].hf_char
= 8;
4530 keymap
.hfkey
[1].hf_kpos
= 15;
4531 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4533 keymap
.hfkey
[1].hf_keyidh
= '<';
4534 #else /* not IBMR2AIX */
4535 keymap
.hfkey
[1].hf_page
= '<';
4536 #endif /* not IBMR2AIX */
4537 keymap
.hfkey
[1].hf_char
= 8;
4538 hftctl (0, HFSKBD
, &buf
);