1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 1986, 1987, 1988, 1990 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. */
21 /* This must precede sys/signal.h on certain machines. */
22 #include <sys/types.h>
30 #define min(x,y) ((x) > (y) ? (y) : (x))
32 /* In this file, open, read and write refer to the system calls,
33 not our sugared interfaces sys_open, sys_read and sys_write.
34 Contrariwise, for systems where we use the system calls directly,
35 define sys_read, etc. here as aliases for them. */
38 #define sys_write write
39 #endif /* `read' is not a macro */
45 #define sys_close close
52 #else /* `open' is a macro */
54 #endif /* `open' is a macro */
62 extern char *sys_errlist
[];
85 #define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */
89 #ifdef BSD /* this is done this way to avoid defined (BSD) || defined (USG)
90 because the vms compiler doesn't grok `defined' */
96 #endif /* not 4.1 bsd */
98 /* Get DGUX definition for FASYNC - DJB */
100 #include <sys/file.h>
104 #include <sys/ioctl.h>
108 #include <sys/wait.h>
113 #include <sys/ioctl.h>
117 #include <sys/termios.h>
121 #include <sys/ioctl.h>
125 #include <sys/stropts.h>
126 #endif /* _SEQUENT_ */
129 /* Get files for keyboard remapping */
132 #include <sys/devinfo.h>
135 /* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs. */
142 #if defined(AIX) && defined(i386)
143 #include <termios.h> /* needs to be before termio.h for aix ps/2 */
149 #define TERMINAL struct termios
150 #else /* not HAVE_TCATTR */
151 #define TERMINAL struct termio
152 #endif /* not HAVE_TCATTR */
158 #endif /* no TIOCGETP */
159 #define TIOCGETP TCGETS
161 #define TIOCSETN TCSETSW
163 #define TIOCSETP TCSETSF
165 #define TCSETAW TCSETS
166 #else /* not IBMR2AIX */
169 #endif /* HAVE_TCATTR */
171 #define TIOCGETP TCGETA
173 #define TIOCSETN TCSETAW
175 #define TIOCSETP TCSETAF
176 #endif /* not IBMR2AIX */
178 /* Try to establish the correct character to disable terminal functions
179 in a system-independent manner. Note that USG (at least) define
180 _POSIX_VDISABLE as 0! */
181 #ifdef _POSIX_VDISABLE
182 #define CDISABLE _POSIX_VDISABLE
183 #else /* not _POSIX_VDISABLE */
185 #define CDISABLE CDEL
188 #endif /* not CDEL */
189 #endif /* not _POSIX_VDISABLE */
192 #define OSPEED(str) (str.c_cflag & CBAUD)
195 #define SETOSPEED(str,new) (str.c_cflag = (str.c_cflag & ~CBAUD) | (new))
197 #define TABS_OK(str) ((str.c_oflag & TABDLY) != TAB3)
198 #endif /* HAVE_TERMIO */
200 #ifndef HAVE_TCATTR /* If HAVE_TCATTR, this is a primitive. */
201 #define tcgetattr(fd, addr) ioctl (fd, TIOCGETP, addr)
205 #undef TIOCGETC /* Avoid confusing some conditionals that test this. */
208 #ifdef BROKEN_TIOCGETC
212 #ifdef BROKEN_TIOCGWINSZ
218 #if defined(DGUX) && defined(_BSD_TTY_FLAVOR)
219 #undef _BSD_TTY_FLAVOR
220 /* DGUX 4.3 has it's own definition in sgtty.h, and it's different
221 than the one in s-dgux.h */
224 #define TERMINAL struct sgttyb
226 #define OSPEED(str) str.sg_ospeed
229 #define SETOSPEED(str,new) (str.sg_ospeed = (new))
231 #define TABS_OK(str) ((str.sg_flags & XTABS) != XTABS)
233 #define TCSETAW TIOCSETN
235 #endif /* not HAVE_TERMIO */
238 #include <sys/utsname.h>
240 #ifndef MEMORY_IN_STRING_H
248 /* Some USG systems with TIOCGWINSZ need this file; some don't have it.
249 We don't know how to distinguish them.
250 If this #include gets an error, just delete it. */
251 #include <sys/sioctl.h>
254 #include <sys/stream.h>
255 #include <sys/ptem.h>
257 #endif /* not aix386 */
258 #endif /* not mips */
259 #endif /* not IRIS_4D */
260 #endif /* TIOCGWINSZ */
265 #include <sys/time.h>
267 #endif /* HAVE_TIMEVAL */
275 #include <sys/bsdtty.h>
278 #if defined (HPUX) && defined (HAVE_PTYS)
279 #include <sys/ptyio.h>
292 #include "filetypes.h"
294 /* FASYNC defined in this file. But, FASYNC don't working.
295 so no problem, because unrequest_sigio only need. */
297 #include <sys/file.h>
300 #ifdef BROKEN_FIONREAD
305 extern int quit_char
;
307 #include "termhooks.h"
308 #include "termchar.h"
309 #include "termopts.h"
310 #include "dispextern.h"
312 #ifdef NONSYSTEM_DIR_LIBRARY
314 #endif /* NONSYSTEM_DIR_LIBRARY */
316 #include "emacssignal.h"
318 /* Define SIGCHLD as an alias for SIGCLD. There are many conditionals
324 #define SIGCHLD SIGCLD
325 #endif /* not SIGCHLD */
329 static int baud_convert
[] =
334 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
335 1800, 2400, 4800, 9600, 19200, 38400
350 int kbd_input_ast ();
360 static int input_chan
;
361 static $
DESCRIPTOR (input_dsc
, "TT");
362 static int terminator_mask
[2] = { 0, 0 };
364 static struct sensemode
{
366 unsigned char xmit_baud
;
367 unsigned char rcv_baud
;
368 unsigned char crfill
;
369 unsigned char lffill
;
370 unsigned char parity
;
371 unsigned char unused
;
375 unsigned long tt_char
: 24, scr_len
: 8;
376 unsigned long tt2_char
;
378 #define TERMINAL struct sensemode
379 #define OSPEED(str) (str.xmit_baud)
380 #define TABS_OK(str) ((str.tt_char & TT$M_MECHTAB) != 0)
390 /* Discarding input is not safe when the input could contain
391 replies from the X server. So don't do it. */
392 if (read_socket_hook
)
397 SYS$
QIOW (0, input_chan
, IO$_READVBLK
|IO$M_PURGE
, input_iosb
, 0, 0,
398 &buf
, 0, 0, terminator_mask
, 0, 0);
404 ioctl (0, TIOCFLUSH
, &zero
);
406 #else /* not Apollo */
409 ioctl (0, TIOCSETP
, &buf
);
411 tcsetattr (0, TCSAFLUSH
, &buf
);
413 #endif /* not Apollo */
422 /* Should perhaps error if in batch mode */
424 ioctl (0, TIOCSTI
, &c
);
425 #else /* no TIOCSTI */
426 error ("Cannot stuff terminal input characters in this version of Unix.");
427 #endif /* no TIOCSTI */
441 SYS$
QIOW (0, input_chan
, IO$_SENSEMODE
, &sg
, 0, 0,
442 &sg
.class, 12, 0, 0, 0, 0 );
444 SETOSPEED (sg
, B9600
);
447 ospeed
= OSPEED (sg
);
450 baud_rate
= (ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
451 ? baud_convert
[ospeed
] : 9600);
457 set_exclusive_use (fd
)
461 ioctl (fd
, FIOCLEX
, 0);
463 /* Ok to do nothing if this feature does not exist */
468 wait_without_blocking ()
471 wait3 (0, WNOHANG
| WUNTRACED
, 0);
473 croak ("wait_without_blocking");
477 #endif /* not subprocesses */
479 int wait_debugging
; /* Set nonzero to make following function work under dbx
480 (at least for bsd). */
482 /* Wait for subprocess with process id `pid' to terminate and
483 make sure it will get eliminated (not remain forever as a zombie) */
485 wait_for_termination (pid
)
491 #if defined (BSD) || (defined (HPUX) && !defined (HPUX_5))
492 /* Note that kill returns -1 even if the process is just a zombie now.
493 But inevitably a SIGCHLD interrupt should be generated
494 and child_sig will do wait3 and make the process go away. */
495 /* There is some indication that there is a bug involved with
496 termination of subprocesses, perhaps involving a kernel bug too,
497 but no idea what it is. Just as a hunch we signal SIGCHLD to see
498 if that causes the problem to go away or get worse. */
500 extern int synch_process_pid
;
502 if (synch_process_pid
== 0)
511 #else /* not BSD4_1 */
512 sigsetmask (sigmask (SIGCHLD
));
513 if (0 > kill (pid
, 0))
515 sigsetmask (SIGEMPTYMASK
);
516 kill (getpid (), SIGCHLD
);
522 sigpause (SIGEMPTYMASK
);
523 #endif /* not BSD4_1 */
524 #else /* not BSD, and not HPUX version >= 6 */
526 if (0 > kill (pid
, 0))
529 #else /* neither BSD nor UNIPLUS: random sysV */
530 #ifdef HAVE_SYSV_SIGPAUSE
532 if (0 > kill (pid
, 0))
538 #else /* not HAVE_SYSV_SIGPAUSE */
539 if (0 > kill (pid
, 0))
541 /* Using sleep instead of pause avoids timing error.
542 If the inferior dies just before the sleep,
543 we lose just one second. */
545 #endif /* not HAVE_SYSV_SIGPAUSE */
546 #endif /* not UNIPLUS */
547 #endif /* not BSD, and not HPUX version >= 6 */
548 #else /* not subprocesses */
550 if (0 > kill (pid
, 0))
556 if (status
== pid
|| status
== -1)
559 #endif /* not subprocesses */
566 * flush any pending output
567 * (may flush input as well; it does not matter the way we use it)
570 flush_pending_output (channel
)
574 ioctl (channel
, TCFLSH
, 1);
578 /* 3rd arg should be ignored
579 but some 4.2 kernels actually want the address of an int
580 and nonzero means something different. */
581 ioctl (channel
, TIOCFLUSH
, &zero
);
586 /* Set up the terminal at the other end of a pseudo-terminal that
587 we will be controlling an inferior through.
588 It should not echo or do line-editing, since that is done
589 in Emacs. No padding needed for insertion into an Emacs buffer. */
591 child_setup_tty (out
)
598 s
.c_oflag
|= OPOST
; /* Enable output postprocessing */
599 s
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
600 s
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
); /* No output delays */
601 s
.c_lflag
&= ~ECHO
; /* Disable echo */
602 s
.c_lflag
|= ISIG
; /* Enable signals */
603 s
.c_iflag
&= ~IUCLC
; /* Disable map of upper case to lower on input */
604 s
.c_oflag
&= ~OLCUC
; /* Disable map of lower case to upper on output */
605 /* said to be unnecesary
606 s.c_cc[VMIN] = 1; /* minimum number of characters to accept
607 s.c_cc[VTIME] = 0; /* wait forever for at least 1 character
609 s
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
610 s
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
611 s
.c_cc
[VERASE
] = 0377; /* disable erase processing */
612 s
.c_cc
[VKILL
] = 0377; /* disable kill processing */
613 #ifdef IRIS_4D /* This is needed for the sake of process_send_signal.
614 Probably a wide class of systems need something like this,
615 but in 18.58, let's be cautious. */
616 s
.c_cc
[VSWTCH
] = 032;
619 s
.c_cflag
= (s
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
623 /* AIX enhanced edit loses NULs, so disable it */
626 s
.c_iflag
&= ~ASCEDIT
;
628 /* Also, PTY overloads NUL and BREAK.
629 don't ignore break, but don't signal either, so it looks like NUL. */
630 s
.c_iflag
&= ~IGNBRK
;
631 s
.c_iflag
&= ~BRKINT
;
632 #if defined(TIOCGPGRP) && defined(TIOCGLTC) && defined(TIOCGETC)
633 /* the QUIT and INTR character are used in process_send_signal
634 so set them here to something useful. */
635 if (s
.c_cc
[VQUIT
] == 0377)
636 s
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
637 if (s
.c_cc
[VINTR
] == 0377)
638 s
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
639 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
640 /* QUIT and INTR are sent using system calls, so disable character forms. */
641 s
.c_cc
[VQUIT
] = 0377;
642 s
.c_cc
[VINTR
] = 0377;
644 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
646 s
.c_cflag
= (s
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
649 #else /* not HAVE_TERMIO */
650 s
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
| CBREAK
| TANDEM
);
653 #endif /* not HAVE_TERMIO */
656 ioctl (out
, TIOCSETN
, &s
);
658 tcsetattr (out
, TCSADRAIN
, &s
);
668 ioctl (out
, FIOASYNC
, &zero
);
673 #endif /* subprocesses */
683 ioctl (0, TIOCSPGRP
, &pid
);
685 /* Just ignore this for now and hope for the best */
690 /* Record a signal code and the handler for it. */
697 /* Suspend the Emacs process; give terminal to its superior. */
702 unsigned long parent_id
;
704 parent_id
= getppid ();
705 if (parent_id
&& parent_id
!= 0xffffffff)
707 int oldsig
= (int) signal (SIGINT
, SIG_IGN
);
708 int status
= LIB$
ATTACH (&parent_id
) & 1;
709 signal (SIGINT
, oldsig
);
716 killpg (getpgrp (0), SIGTSTP
);
718 kill (-getpgrp (0), SIGTSTP
);
722 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
723 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
724 kill (getpid (), SIGQUIT
);
728 /* On a system where suspending is not implemented,
729 instead fork a subshell and let it talk directly to the terminal
732 struct save_signal saved_handlers
[5];
734 saved_handlers
[0].code
= SIGINT
;
735 saved_handlers
[1].code
= SIGQUIT
;
736 saved_handlers
[2].code
= SIGTERM
;
738 saved_handlers
[3].code
= SIGIO
;
739 saved_handlers
[4].code
= 0;
741 saved_handlers
[3].code
= 0;
745 error ("Can't spawn subshell");
750 sh
= (char *) egetenv ("SHELL");
753 /* Use our buffer's default directory for the subshell. */
759 /* mentioning current_buffer->buffer would mean including buffer.h,
760 which somehow wedges the hp compiler. So instead... */
762 dir
= intern ("default-directory");
764 if (XFASTINT (Fboundp (dir
)) == XFASTINT (Qnil
))
766 dir
= Fsymbol_value (dir
);
767 if (XTYPE (dir
) != Lisp_String
)
770 str
= (unsigned char *) alloca (XSTRING (dir
)->size
+ 2);
771 len
= XSTRING (dir
)->size
;
772 bcopy (XSTRING (dir
)->data
, str
, len
);
773 if (str
[len
- 1] != '/') str
[len
++] = '/';
779 close_process_descs (); /* Close Emacs's pipes/ptys */
782 write (1, "Can't execute subshell", 22);
785 save_signal_handlers (saved_handlers
);
786 wait_for_termination (pid
);
787 restore_signal_handlers (saved_handlers
);
788 #endif /* no USG_JOBCTRL */
789 #endif /* no SIGTSTP */
793 save_signal_handlers (saved_handlers
)
794 struct save_signal
*saved_handlers
;
796 while (saved_handlers
->code
)
798 saved_handlers
->handler
799 = (int (*) ()) signal (saved_handlers
->code
, SIG_IGN
);
804 restore_signal_handlers (saved_handlers
)
805 struct save_signal
*saved_handlers
;
807 while (saved_handlers
->code
)
809 signal (saved_handlers
->code
, saved_handlers
->handler
);
821 old_fcntl_flags
= fcntl (0, F_GETFL
, 0) & ~FASYNC
;
831 #ifdef FASYNC /* F_SETFL does not imply existance of FASYNC */
836 sigunblock (sigmask (SIGWINCH
));
838 fcntl (0, F_SETFL
, old_fcntl_flags
| FASYNC
);
840 interrupts_deferred
= 0;
846 sigblock (sigmask (SIGWINCH
));
848 fcntl (0, F_SETFL
, old_fcntl_flags
);
849 interrupts_deferred
= 1;
852 #else /* no FASYNC */
853 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
858 ioctl (0, FIOASYNC
, &on
);
859 interrupts_deferred
= 0;
866 ioctl (0, FIOASYNC
, &off
);
867 interrupts_deferred
= 1;
870 #else /* not FASYNC, not STRIDE */
874 croak ("request_sigio");
879 croak ("unrequest_sigio");
886 TERMINAL old_gtty
; /* The initial tty mode bits */
888 int term_initted
; /* 1 if outer tty status has been recorded */
892 #endif /* F_SETOWN */
895 struct ltchars old_ltchars
;
896 #endif /* TIOCGLTC */
899 struct tchars old_tchars
;
902 int lmode
; /* Current lmode value. */
903 /* Needed as global for 4.1 */
904 #endif /* TIOCGETC */
906 /* This may also be defined in stdio,
907 but if so, this does no harm,
908 and using the same name avoids wasting the other one's space. */
910 #if defined (USG) || defined (DGUX)
911 unsigned char _sobuf
[BUFSIZ
+8];
917 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
920 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
927 struct tchars tchars
;
931 static int oob_chars
[2] = {0, 1 << 7}; /* catch C-g's */
932 extern int (*interrupt_signal
) ();
941 LIB$
GET_EF (&input_ef
);
942 SYS$
CLREF (input_ef
);
945 LIB$
GET_EF (&timer_ef
);
946 SYS$
CLREF (timer_ef
);
949 LIB$
GET_EF (&process_ef
);
950 SYS$
CLREF (process_ef
);
952 if (input_ef
/ 32 != process_ef
/ 32)
953 croak ("Input and process event flags in different clusters.");
954 if (input_ef
/ 32 != timer_ef
/ 32)
955 croak ("Input and process event flags in different clusters.");
956 input_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
957 ((unsigned) 1 << (process_ef
% 32));
958 timer_eflist
= ((unsigned) 1 << (input_ef
% 32)) |
959 ((unsigned) 1 << (timer_ef
% 32));
960 SYS$
QIOW (0, input_chan
, IO$_SENSEMODE
, &old_gtty
, 0, 0,
961 &old_gtty
.class, 12, 0, 0, 0, 0);
963 sys_access_reinit ();
966 tcgetattr (0, &old_gtty
);
968 if (!read_socket_hook
)
973 tty
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
974 tty
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
976 tty
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
978 tty
.c_lflag
&= ~ECHO
; /* Disable echo */
979 tty
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
981 tty
.c_iflag
&= ~IEXTEN
; /* Disable other editing characters. */
983 tty
.c_lflag
|= ISIG
; /* Enable signals */
986 tty
.c_iflag
|= IXON
; /* Enable start/stop output control */
988 tty
.c_iflag
&= ~IXANY
;
992 tty
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
993 tty
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
994 tty
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
996 tty
.c_cflag
|= CS8
; /* allow 8th bit on input */
997 tty
.c_cflag
&= ~PARENB
; /* Don't check parity */
999 tty
.c_cc
[VINTR
] = quit_char
; /* ^G gives SIGINT */
1000 /* Set up C-g (usually) for both SIGQUIT and SIGINT.
1001 We don't know which we will get, but we handle both alike
1002 so which one it really gives us does not matter. */
1003 tty
.c_cc
[VQUIT
] = quit_char
;
1004 tty
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1005 tty
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1007 tty
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use of C-z */
1009 #if defined (mips) || defined (HAVE_TCATTR)
1011 tty
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1014 tty
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1015 #endif /* V_DSUSP */
1016 #ifdef VDSUSP /* Some systems use VDSUSP instead of VD_SUSP. */
1017 tty
.c_cc
[VDSUSP
] = CDISABLE
;
1019 #endif /* mips or HAVE_TCATTR */
1023 /* AIX enhanced edit loses NULs, so disable it */
1025 tty
.c_iflag
&= ~ASCEDIT
;
1027 tty
.c_cc
[VSTRT
] = 255;
1028 tty
.c_cc
[VSTOP
] = 255;
1029 tty
.c_cc
[VSUSP
] = 255;
1030 tty
.c_cc
[VDSUSP
] = 255;
1031 #endif /* IBMR2AIX */
1032 /* Also, PTY overloads NUL and BREAK.
1033 don't ignore break, but don't signal either, so it looks like NUL.
1034 This really serves a purpose only if running in an XTERM window
1035 or via TELNET or the like, but does no harm elsewhere. */
1036 tty
.c_iflag
&= ~IGNBRK
;
1037 tty
.c_iflag
&= ~BRKINT
;
1040 #else /* if not HAVE_TERMIO */
1042 tty
.tt_char
|= TT$M_NOECHO
| TT$M_EIGHTBIT
;
1044 tty
.tt_char
|= TT$M_TTSYNC
;
1046 tty
.tt_char
&= ~TT$M_TTSYNC
;
1047 tty
.tt2_char
|= TT2$M_PASTHRU
| TT2$M_XON
;
1048 #else /* not VMS (BSD, that is) */
1049 tty
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1050 tty
.sg_flags
|= ANYP
;
1051 tty
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1052 #endif /* not VMS (BSD, that is) */
1053 #endif /* not HAVE_TERMIO */
1056 SYS$
QIOW (0, input_chan
, IO$_SETMODE
, &input_iosb
, 0, 0,
1057 &tty
.class, 12, 0, 0, 0, 0);
1060 ioctl (0, TIOCSETN
, &tty
);
1062 tcsetattr (0, TCSADRAIN
, &tty
);
1064 #endif /* not VMS */
1066 /* This code added to insure that, if flow-control is not to be used,
1067 we have an unlocked screen at the start. */
1069 if (!flow_control
) ioctl (0, TCXONC
, 1);
1073 if (!flow_control
) ioctl (0, TIOCSTART
, 0);
1081 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1082 to be only LF. This is the way that is done. */
1085 if (ioctl (1, HFTGETID
, &tty
) != -1)
1086 write (1, "\033[20l", 5);
1092 #ifdef F_GETOWN /* F_SETFL does not imply existance of F_GETOWN */
1093 if (interrupt_input
)
1095 old_fcntl_owner
= fcntl (0, F_GETOWN
, 0);
1096 fcntl (0, F_SETOWN
, getpid ());
1099 #endif /* F_GETOWN */
1100 #endif /* F_SETFL */
1102 /* If going to use CBREAK mode, we must request C-g to interrupt
1103 and turn off start and stop chars, etc.
1104 If not going to use CBREAK mode, do this anyway
1105 so as to turn off local flow control for user coming over
1106 network on 4.2; in this case, only t_stopc and t_startc really matter. */
1108 ioctl (0, TIOCGLTC
, &old_ltchars
);
1109 #endif /* TIOCGLTC */
1112 ioctl (0, TIOCGETC
, &old_tchars
);
1113 ioctl (0, TIOCLGET
, &old_lmode
);
1115 /* Note: if not using CBREAK mode, it makes no difference how we set this */
1116 tchars
= new_tchars
;
1117 tchars
.t_intrc
= quit_char
;
1120 tchars
.t_startc
= '\021';
1121 tchars
.t_stopc
= '\023';
1123 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
1129 #define LNOFLSH 0100000
1132 lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| old_lmode
;
1134 ioctl (0, TIOCSETC
, &tchars
);
1135 ioctl (0, TIOCLSET
, &lmode
);
1136 #endif /* TIOCGETC */
1137 #endif /* not HAVE_TERMIO */
1139 ioctl (0, TIOCSLTC
, &new_ltchars
);
1140 #endif /* TIOCGLTC */
1143 if (interrupt_input
)
1147 /* Appears to do nothing when in PASTHRU mode.
1148 SYS$QIOW (0, input_chan, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1149 interrupt_signal, oob_chars, 0, 0, 0, 0);
1151 queue_kbd_input (0);
1154 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1158 /* This symbol is defined on recent USG systems.
1159 Someone says without this call USG won't really buffer the file
1160 even with a call to setbuf. */
1161 setvbuf (stdout
, _sobuf
, _IOFBF
, sizeof _sobuf
);
1163 setbuf (stdout
, _sobuf
);
1165 set_terminal_modes ();
1166 if (term_initted
&& no_redraw_on_reenter
)
1168 if (display_completed
)
1169 direct_output_forward_char (0);
1172 screen_garbaged
= 1;
1176 /* Return nonzero if safe to use tabs in output.
1177 At the time this is called, init_sys_modes has not been done yet. */
1185 SYS$
QIOW (0, input_chan
, IO$_SENSEMODE
, &tty
, 0, 0,
1186 &tty
.class, 12, 0, 0, 0, 0);
1188 tcgetattr (0, &tty
);
1189 #endif /* not VMS */
1190 return (TABS_OK (tty
));
1193 /* Get terminal size from system.
1194 Store number of lines into *heightp and width into *widthp.
1195 If zero or a negative number is stored, the value is not valid. */
1197 get_screen_size (widthp
, heightp
)
1198 int *widthp
, *heightp
;
1200 /* Define the 4.3 names in terms of the Sun names
1201 if the latter exist and the former do not. */
1204 #define TIOCGWINSZ TIOCGSIZE
1205 #define winsize ttysize
1206 #define ws_row ts_lines
1207 #define ws_col ts_cols
1211 /* Do it using the 4.3 names if possible. */
1213 struct winsize size
;
1216 if (ioctl (0, TIOCGWINSZ
, &size
) < 0)
1218 *widthp
= size
.ws_col
;
1219 *heightp
= size
.ws_row
;
1220 #else /* not TIOCGWNSIZ */
1223 SYS$
QIOW (0, input_chan
, IO$_SENSEMODE
, &tty
, 0, 0,
1224 &tty
.class, 12, 0, 0, 0, 0);
1225 *widthp
= tty
.scr_wid
;
1226 *heightp
= tty
.scr_len
;
1227 #else /* system doesn't know size */
1230 #endif /* system does not know size */
1231 #endif /* not TIOCGWINSZ */
1243 if (read_socket_hook
)
1245 move_cursor (screen_height
- 1, 0);
1246 clear_end_of_line (screen_width
);
1247 /* clear_end_of_line may move the cursor */
1248 move_cursor (screen_height
- 1, 0);
1249 /* Output raw CR so kernel can track the cursor hpos. */
1253 /* HFT devices normally use ^J as a LF/CR. We forced it to
1254 do the LF only. Now, we need to reset it. */
1257 if (ioctl (1, HFTGETID
, &tty
) != -1)
1258 write (1, "\033[20h", 5);
1262 reset_terminal_modes ();
1266 /* Avoid possible loss of output when changing terminal modes. */
1267 fsync (fileno (stdout
));
1271 ioctl (0, TIOCSLTC
, &old_ltchars
);
1272 #endif /* TIOCGLTC */
1275 ioctl (0, TIOCSETC
, &old_tchars
);
1276 ioctl (0, TIOCLSET
, &old_lmode
);
1277 #endif /* TIOCGETC */
1278 #endif /* not HAVE_TERMIO */
1280 #ifdef F_SETOWN /* F_SETFL does not imply existance of F_SETOWN */
1281 if (interrupt_input
)
1284 fcntl (0, F_SETOWN
, old_fcntl_owner
);
1286 #endif /* F_SETOWN */
1287 #endif /* F_SETFL */
1289 if (interrupt_input
)
1294 SYS$
QIOW (0, input_chan
, IO$_SETMODE
, &input_iosb
, 0, 0,
1295 &old_gtty
.class, 12, 0, 0, 0, 0);
1298 while (ioctl (0, TCSETAW
, &old_gtty
) < 0 && errno
== EINTR
);
1300 while (tcsetattr (0, TCSADRAIN
, &old_gtty
) < 0 && errno
== EINTR
);
1302 #endif /* not VMS */
1311 /* Set up the proper status flags for use of a pty. */
1316 /* I'm told that TOICREMOTE does not mean control chars
1317 "can't be sent" but rather that they don't have
1318 input-editing or signaling effects.
1319 That should be good, because we have other ways
1320 to do those things in Emacs.
1321 However, telnet mode seems not to work on 4.2.
1322 So TIOCREMOTE is turned off now. */
1324 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1325 will hang. In particular, the "timeout" feature (which
1326 causes a read to return if there is no data available)
1327 does this. Also it is known that telnet mode will hang
1328 in such a way that Emacs must be stopped (perhaps this
1329 is the same problem).
1331 If TIOCREMOTE is turned off, then there is a bug in
1332 hp-ux which sometimes loses data. Apparently the
1333 code which blocks the master process when the internal
1334 buffer fills up does not work. Other than this,
1335 though, everything else seems to work fine.
1337 Since the latter lossage is more benign, we may as well
1338 lose that way. -- cph */
1343 ioctl (fd
, FIONBIO
, &on
);
1348 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1349 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1350 /* cause EMACS not to die when it should, i.e., when its own controlling */
1351 /* tty goes away. I've complained to the AIX developers, and they may */
1352 /* change this behavior, but I'm not going to hold my breath. */
1353 signal (SIGHUP
, SIG_IGN
);
1356 #endif /* HAVE_PTYS */
1360 /* Assigning an input channel is done at the start of Emacs execution.
1361 This is called each time Emacs is resumed, also, but does nothing
1362 because input_chain is no longer zero. */
1368 if (input_chan
== 0)
1370 status
= SYS$
ASSIGN (&input_dsc
, &input_chan
, 0, 0);
1376 /* Deassigning the input channel is done before exiting. */
1380 return SYS$
DASSGN (input_chan
);
1385 /* Request reading one character into the keyboard buffer.
1386 This is done as soon as the buffer becomes empty. */
1391 waiting_for_ast
= 0;
1393 status
= SYS$
QIO (0, input_chan
, IO$_READVBLK
,
1394 &input_iosb
, kbd_input_ast
, 1,
1395 &input_buffer
, 1, 0, terminator_mask
, 0, 0);
1400 /* Ast routine that is called when keyboard input comes in
1401 in accord with the SYS$QIO above. */
1405 register int c
= -1;
1406 int old_errno
= errno
;
1408 if (waiting_for_ast
)
1409 SYS$
SETEF (input_ef
);
1410 waiting_for_ast
= 0;
1413 if (input_count
== 25)
1415 printf ("Ast # %d,", input_count
);
1416 printf (" iosb = %x, %x, %x, %x",
1417 input_iosb
.offset
, input_iosb
.status
, input_iosb
.termlen
,
1420 if (input_iosb
.offset
)
1424 printf (", char = 0%o", c
);
1435 kbd_buffer_store_char (c
);
1440 /* Wait until there is something in kbd_buffer. */
1442 wait_for_kbd_input ()
1444 extern int have_process_input
, process_exited
;
1446 /* If already something, avoid doing system calls. */
1447 if (detect_input_pending ())
1451 /* Clear a flag, and tell ast routine above to set it. */
1452 SYS$
CLREF (input_ef
);
1453 waiting_for_ast
= 1;
1454 /* Check for timing error: ast happened while we were doing that. */
1455 if (!detect_input_pending ())
1457 /* No timing error: wait for flag to be set. */
1458 set_waiting_for_input (0);
1459 SYS$
WFLOR (input_ef
, input_eflist
);
1460 clear_waiting_for_input (0);
1461 if (!detect_input_pending ())
1462 /* Check for subprocess input availability */
1464 int dsp
= have_process_input
|| process_exited
;
1466 sys$
clref (process_ef
);
1467 if (have_process_input
)
1468 process_command_input ();
1473 update_mode_lines
++;
1474 redisplay_preserve_echo_area ();
1478 waiting_for_ast
= 0;
1481 /* Get rid of any pending QIO, when we are about to suspend
1482 or when we want to throw away pending input.
1483 We wait for a positive sign that the AST routine has run
1484 and therefore there is no I/O request queued when we return.
1485 SYS$SETAST is used to avoid a timing error. */
1490 printf ("At end_kbd_input.\n");
1494 if (LIB$
AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_char! */
1496 SYS$
CANCEL (input_chan
);
1501 /* Clear a flag, and tell ast routine above to set it. */
1502 SYS$
CLREF (input_ef
);
1503 waiting_for_ast
= 1;
1505 SYS$
CANCEL (input_chan
);
1507 SYS$
WAITFR (input_ef
);
1508 waiting_for_ast
= 0;
1511 /* Wait for either input available or time interval expiry. */
1513 input_wait_timeout (timeval
)
1514 int timeval
; /* Time to wait, in seconds */
1517 static int zero
= 0;
1518 static int large
= -10000000;
1520 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1522 /* If already something, avoid doing system calls. */
1523 if (detect_input_pending ())
1527 /* Clear a flag, and tell ast routine above to set it. */
1528 SYS$
CLREF (input_ef
);
1529 waiting_for_ast
= 1;
1530 /* Check for timing error: ast happened while we were doing that. */
1531 if (!detect_input_pending ())
1533 /* No timing error: wait for flag to be set. */
1535 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1536 SYS$
WFLOR (timer_ef
, timer_eflist
); /* Wait for timer expiry or input */
1538 waiting_for_ast
= 0;
1541 /* The standard `sleep' routine works some other way
1542 and it stops working if you have ever quit out of it.
1543 This one continues to work. */
1549 static int zero
= 0;
1550 static int large
= -10000000;
1552 LIB$
EMUL (&timeval
, &large
, &zero
, time
); /* Convert to VMS format */
1555 if (SYS$
SETIMR (timer_ef
, time
, 0, 1) & 1) /* Set timer */
1556 SYS$
WAITFR (timer_ef
); /* Wait for timer expiry only */
1571 croak ("request sigio");
1576 croak ("unrequest sigio");
1581 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
1586 #ifndef SYSTEM_MALLOC
1593 /* Some systems that cannot dump also cannot implement these. */
1596 * Return the address of the start of the text segment prior to
1597 * doing an unexec. After unexec the return value is undefined.
1598 * See crt0.c for further explanation and _start.
1602 #ifndef CANNOT_UNEXEC
1607 return ((char *) TEXT_START
);
1611 return ((char *) csrt
);
1612 #else /* not GOULD */
1613 extern int _start ();
1614 return ((char *) _start
);
1616 #endif /* TEXT_START */
1618 #endif /* not CANNOT_UNEXEC */
1621 * Return the address of the start of the data segment prior to
1622 * doing an unexec. After unexec the return value is undefined.
1623 * See crt0.c for further information and definition of data_start.
1625 * Apparently, on BSD systems this is etext at startup. On
1626 * USG systems (swapping) this is highly mmu dependent and
1627 * is also dependent on whether or not the program is running
1628 * with shared text. Generally there is a (possibly large)
1629 * gap between end of text and start of data with shared text.
1631 * On Uniplus+ systems with shared text, data starts at a
1632 * fixed address. Each port (from a given oem) is generally
1633 * different, and the specific value of the start of data can
1634 * be obtained via the UniPlus+ specific "uvar" system call,
1635 * however the method outlined in crt0.c seems to be more portable.
1637 * Probably what will have to happen when a USG unexec is available,
1638 * at least on UniPlus, is temacs will have to be made unshared so
1639 * that text and data are contiguous. Then once loadup is complete,
1640 * unexec will produce a shared executable where the data can be
1641 * at the normal shared text boundry and the startofdata variable
1642 * will be patched by unexec to the correct value.
1650 return ((char *) DATA_START
);
1652 extern int data_start
;
1653 return ((char *) &data_start
);
1656 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1659 /* Some systems that cannot dump also cannot implement these. */
1662 * Return the address of the end of the text segment prior to
1663 * doing an unexec. After unexec the return value is undefined.
1670 return ((char *) TEXT_END
);
1673 return ((char *) &etext
);
1678 * Return the address of the end of the data segment prior to
1679 * doing an unexec. After unexec the return value is undefined.
1686 return ((char *) DATA_END
);
1689 return ((char *) &edata
);
1693 #endif /* not CANNOT_DUMP */
1695 /* Get_system_name returns as its value
1696 a string for the Lisp function system-name to return. */
1702 /* Can't have this within the function since `static' is #defined to
1703 * nothing for some USG systems.
1706 #ifdef HAVE_GETHOSTNAME
1707 static char get_system_name_name
[256];
1708 #else /* not HAVE_GETHOSTNAME */
1709 static struct utsname get_system_name_name
;
1710 #endif /* not HAVE_GETHOSTNAME */
1717 #ifdef HAVE_GETHOSTNAME
1718 gethostname (get_system_name_name
, sizeof (get_system_name_name
));
1719 return get_system_name_name
;
1720 #else /* not HAVE_GETHOSTNAME */
1721 uname (&get_system_name_name
);
1722 return (get_system_name_name
.nodename
);
1723 #endif /* not HAVE_GETHOSTNAME */
1727 #else /* not USG, not 4.1 */
1728 static char system_name_saved
[32];
1731 if ((sp
= egetenv ("SYS$NODE")) == 0)
1737 if ((end
= index (sp
, ':')) != 0)
1740 strcpy (system_name_saved
, sp
);
1742 gethostname (system_name_saved
, sizeof (system_name_saved
));
1743 #endif /* not VMS */
1744 return system_name_saved
;
1745 #endif /* not USG, not 4.1 */
1746 #endif /* not USG */
1751 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1752 * Only checks read descriptors.
1754 /* How long to wait between checking fds in select */
1755 #define SELECT_PAUSE 1
1758 /* For longjmp'ing back to read_input_waiting. */
1760 jmp_buf read_alarm_throw
;
1762 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1763 The read_socket_hook function sets this to 1 while it is waiting. */
1765 int read_alarm_should_throw
;
1772 #else /* not BSD4_1 */
1773 signal (SIGALRM
, SIG_IGN
);
1774 #endif /* not BSD4_1 */
1775 if (read_alarm_should_throw
)
1776 longjmp (read_alarm_throw
, 1);
1779 /* Only rfds are checked. */
1781 select (nfds
, rfds
, wfds
, efds
, timeout
)
1783 int *rfds
, *wfds
, *efds
, *timeout
;
1785 int ravail
= 0, orfds
= 0, old_alarm
;
1786 int timeoutval
= timeout
? *timeout
: 100000;
1787 int *local_timeout
= &timeoutval
;
1788 extern int kbd_count
;
1789 extern int proc_buffered_char
[];
1790 #ifndef subprocesses
1791 int process_tick
= 0, update_tick
= 0;
1793 extern int process_tick
, update_tick
;
1808 /* If we are looking only for the terminal, with no timeout,
1809 just read it and wait -- that's more efficient. */
1810 if (orfds
== 1 && (!timeout
|| *timeout
== 100000)
1811 && process_tick
== update_tick
)
1814 read_input_waiting ();
1819 /* Once a second, till the timer expires, check all the flagged read
1820 * descriptors to see if any input is available. If there is some then
1821 * set the corresponding bit in the return copy of rfds.
1825 register int to_check
, bit
, fd
;
1829 for (to_check
= nfds
, bit
= 1, fd
= 0; --to_check
>= 0; bit
<<= 1, fd
++)
1833 int avail
= 0, status
= 0;
1836 avail
= detect_input_pending (); /* Special keyboard handler */
1840 status
= ioctl (fd
, FIONREAD
, &avail
);
1841 #else /* no FIONREAD */
1842 /* Hoping it will return -1 if nothing available
1843 or 0 if all 0 chars requested are read. */
1844 if (proc_buffered_char
[fd
] >= 0)
1848 avail
= read (fd
, &buf
, 1);
1850 proc_buffered_char
[fd
] = buf
;
1852 #endif /* no FIONREAD */
1854 if (status
>= 0 && avail
> 0)
1862 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
1864 old_alarm
= alarm (0);
1865 old_trap
= (int (*)()) signal (SIGALRM
, select_alarm
);
1867 alarm (SELECT_PAUSE
);
1868 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1869 while (select_alarmed
== 0 && *local_timeout
!= 0
1870 && process_tick
== update_tick
)
1872 /* If we are interested in terminal input,
1873 wait by reading the terminal.
1874 That makes instant wakeup for terminal input at least. */
1877 read_input_waiting ();
1884 (*local_timeout
) -= SELECT_PAUSE
;
1885 /* Reset the old alarm if there was one */
1887 signal (SIGALRM
, old_trap
);
1890 /* Reset or forge an interrupt for the original handler. */
1891 old_alarm
-= SELECT_PAUSE
;
1893 kill (getpid (), SIGALRM
); /* Fake an alarm with the orig' handler */
1897 if (*local_timeout
== 0) /* Stop on timer being cleared */
1903 /* Read keyboard input into the standard buffer,
1904 waiting for at least one character. */
1906 /* Make all keyboard buffers much bigger when using X windows. */
1907 #ifdef HAVE_X_WINDOWS
1908 #define BUFFER_SIZE_FACTOR 16
1910 #define BUFFER_SIZE_FACTOR 1
1913 read_input_waiting ()
1915 extern int kbd_count
;
1916 extern unsigned char kbd_buffer
[];
1917 extern unsigned char *kbd_ptr
;
1920 if (read_socket_hook
)
1922 read_alarm_should_throw
= 0;
1923 if (! setjmp (read_alarm_throw
))
1924 val
= (*read_socket_hook
) (0, kbd_buffer
, 256 * BUFFER_SIZE_FACTOR
);
1929 val
= read (fileno (stdin
), kbd_buffer
, 1);
1933 kbd_ptr
= kbd_buffer
;
1938 #endif /* not HAVE_SELECT */
1948 * Partially emulate 4.2 open call.
1949 * open is defined as this in 4.1.
1951 * - added by Michael Bloom @ Citicorp/TTI
1956 sys_open (path
, oflag
, mode
)
1960 if (oflag
& O_CREAT
)
1961 return creat (path
, mode
);
1963 return open (path
, oflag
);
1970 lmode
= LINTRUP
| lmode
;
1971 ioctl (0, TIOCLSET
, &lmode
);
1978 lmode
= ~LINTRUP
& lmode
;
1979 ioctl (0, TIOCLSET
, &lmode
);
1986 interrupts_deferred
= 0;
1993 interrupts_deferred
= 1;
1996 /* still inside #ifdef BSD4_1 */
1999 int sigheld
; /* Mask of held signals */
2004 sigheld
|= sigbit (signum
);
2011 sigheld
|= sigbit (signum
);
2017 sigheld
&= ~sigbit (signum
);
2021 sigfree () /* Free all held signals */
2024 for (i
= 0; i
< NSIG
; i
++)
2025 if (sigheld
& sigbit (i
))
2032 return 1 << (i
- 1);
2034 #endif /* subprocesses */
2037 /* POSIX signals support - DJB */
2038 /* Anyone with POSIX signals should have ANSI C declarations */
2040 #ifdef POSIX_SIGNALS
2042 sigset_t signal_empty_mask
, signal_full_mask
;
2043 static struct sigaction new_action
, old_action
;
2047 #ifdef POSIX_SIGNALS
2048 sigemptyset (&signal_empty_mask
);
2049 sigfillset (&signal_full_mask
);
2053 typedef int (*signal_handler_t
) ();
2056 sys_signal (int signal_number
, signal_handler_t action
)
2059 /* This gets us restartable system calls for efficiency.
2060 The "else" code will works as well. */
2061 return (berk_signal (signal_number
, action
));
2063 sigemptyset (&new_action
.sa_mask
);
2064 new_action
.sa_handler
= action
;
2065 new_action
.sa_flags
= NULL
;
2066 sigaction (signal_number
, &new_action
, &old_action
);
2067 return (old_action
.sa_handler
);
2072 sys_sigpause (sigset_t new_mask
)
2074 /* pause emulating berk sigpause... */
2075 sigsuspend (&new_mask
);
2079 /* I'd like to have these guys return pointers to the mask storage in here,
2080 but there'd be trouble if the code was saving multiple masks. I'll be
2081 safe and pass the structure. It normally won't be more than 2 bytes
2085 sys_sigblock (sigset_t new_mask
)
2088 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2093 sys_sigunblock (sigset_t new_mask
)
2096 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2101 sys_sigsetmask (sigset_t new_mask
)
2104 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2108 #endif /* POSIX_SIGNALS */
2115 register int length
;
2119 long max_str
= 65535;
2121 while (length
> max_str
) {
2122 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2127 (void) LIB$
MOVC5 (&zero
, &zero
, &zero
, &max_str
, b
);
2129 while (length
-- > 0)
2131 #endif /* not VMS */
2134 /* Saying `void' requires a declaration, above, where bcopy is used
2135 and that declaration causes pain for systems where bcopy is a macro. */
2136 bcopy (b1
, b2
, length
)
2139 register int length
;
2142 long max_str
= 65535;
2144 while (length
> max_str
) {
2145 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2151 (void) LIB$
MOVC3 (&max_str
, b1
, b2
);
2153 while (length
-- > 0)
2155 #endif /* not VMS */
2159 bcmp (b1
, b2
, length
) /* This could be a macro! */
2162 register int length
;
2165 struct dsc$descriptor_s src1
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b1
};
2166 struct dsc$descriptor_s src2
= {length
, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, b2
};
2168 return STR$
COMPARE (&src1
, &src2
);
2170 while (length
-- > 0)
2175 #endif /* not VMS */
2177 #endif /* not BSTRING */
2201 * The BSD random returns numbers in the range of
2202 * 0 to 2e31 - 1. The USG rand(3C) returns numbers in the
2203 * range of 0 to 2e15 - 1. This is probably not significant
2210 /* Arrange to return a range centered on zero. */
2211 return rand () - (1 << 14);
2220 #endif /* HAVE_RANDOM */
2227 /* If any place else asks for the TERM variable,
2228 allow it to be overridden with the EMACS_TERM variable
2229 before attempting to translate the logical name TERM. As a last
2230 resort, ask for VAX C's special idea of the TERM variable. */
2237 static char buf
[256];
2238 static struct dsc$descriptor_s equiv
2239 = {sizeof (buf
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, buf
};
2240 static struct dsc$descriptor_s d_name
2241 = {0, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, 0};
2244 if (!strcmp (name
, "TERM"))
2246 val
= (char *) getenv ("EMACS_TERM");
2251 d_name
.dsc$w_length
= strlen (name
);
2252 d_name
.dsc$a_pointer
= name
;
2253 if (lib$
sys_trnlog (&d_name
, &eqlen
, &equiv
) == 1)
2255 char *str
= (char *) xmalloc (eqlen
+ 1);
2256 bcopy (buf
, str
, eqlen
);
2258 /* This is a storage leak, but a pain to fix. With luck,
2259 no one will ever notice. */
2262 return (char *) getenv (name
);
2267 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2268 to force a call on the debugger from within the image. */
2273 LIB$
SIGNAL (SS$_DEBUG
);
2279 #ifdef LINK_CRTL_SHARE
2280 #ifdef SHAREABLE_LIB_BUG
2281 /* Variables declared noshare and initialized in shareable libraries
2282 cannot be shared. The VMS linker incorrectly forces you to use a private
2283 version which is uninitialized... If not for this "feature", we
2284 could use the C library definition of sys_nerr and sys_errlist. */
2286 char *sys_errlist
[] =
2290 "no such file or directory",
2292 "interrupted system call",
2294 "no such device or address",
2295 "argument list too long",
2296 "exec format error",
2299 "no more processes",
2300 "not enough memory",
2301 "permission denied",
2303 "block device required",
2304 "mount devices busy",
2306 "cross-device link",
2311 "file table overflow",
2312 "too many open files",
2316 "no space left on device",
2318 "read-only file system",
2324 "vax/vms specific error code nontranslatable error"
2326 #endif /* SHAREABLE_LIB_BUG */
2327 #endif /* LINK_CRTL_SHARE */
2330 #ifdef INTERRUPTABLE_OPEN
2334 sys_open (path
, oflag
, mode
)
2338 register int rtnval
;
2340 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2341 && (errno
== EINTR
));
2345 #endif /* INTERRUPTABLE_OPEN */
2347 #ifdef INTERRUPTABLE_CLOSE
2352 register int rtnval
;
2354 while ((rtnval
= close (fd
)) == -1
2355 && (errno
== EINTR
));
2359 #endif /* INTERRUPTABLE_CLOSE */
2361 #ifdef INTERRUPTABLE_IO
2364 sys_read (fildes
, buf
, nbyte
)
2369 register int rtnval
;
2371 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2372 && (errno
== EINTR
));
2377 sys_write (fildes
, buf
, nbyte
)
2382 register int rtnval
;
2384 while ((rtnval
= write (fildes
, buf
, nbyte
)) == -1
2385 && (errno
== EINTR
));
2389 #endif /* INTERRUPTABLE_IO */
2393 * All of the following are for USG.
2395 * On USG systems the system calls are interruptable by signals
2396 * that the user program has elected to catch. Thus the system call
2397 * must be retried in these cases. To handle this without massive
2398 * changes in the source code, we remap the standard system call names
2399 * to names for our own functions in sysdep.c that do the system call
2400 * with retries. Actually, for portability reasons, it is good
2401 * programming practice, as this example shows, to limit all actual
2402 * system calls to a single occurance in the source. Sure, this
2403 * adds an extra level of function call overhead but it is almost
2404 * always negligible. Fred Fish, Unisoft Systems Inc.
2407 char *sys_siglist
[NSIG
+ 1] =
2410 /* AIX has changed the signals a bit */
2411 "bogus signal", /* 0 */
2412 "hangup", /* 1 SIGHUP */
2413 "interrupt", /* 2 SIGINT */
2414 "quit", /* 3 SIGQUIT */
2415 "illegal instruction", /* 4 SIGILL */
2416 "trace trap", /* 5 SIGTRAP */
2417 "IOT instruction", /* 6 SIGIOT */
2418 "crash likely", /* 7 SIGDANGER */
2419 "floating point exception", /* 8 SIGFPE */
2420 "kill", /* 9 SIGKILL */
2421 "bus error", /* 10 SIGBUS */
2422 "segmentation violation", /* 11 SIGSEGV */
2423 "bad argument to system call", /* 12 SIGSYS */
2424 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2425 "alarm clock", /* 14 SIGALRM */
2426 "software termination signum", /* 15 SIGTERM */
2427 "user defined signal 1", /* 16 SIGUSR1 */
2428 "user defined signal 2", /* 17 SIGUSR2 */
2429 "death of a child", /* 18 SIGCLD */
2430 "power-fail restart", /* 19 SIGPWR */
2431 "bogus signal", /* 20 */
2432 "bogus signal", /* 21 */
2433 "bogus signal", /* 22 */
2434 "bogus signal", /* 23 */
2435 "bogus signal", /* 24 */
2436 "LAN I/O interrupt", /* 25 SIGAIO */
2437 "PTY I/O interrupt", /* 26 SIGPTY */
2438 "I/O intervention required", /* 27 SIGIOINT */
2439 "HFT grant", /* 28 SIGGRANT */
2440 "HFT retract", /* 29 SIGRETRACT */
2441 "HFT sound done", /* 30 SIGSOUND */
2442 "HFT input ready", /* 31 SIGMSG */
2444 "bogus signal", /* 0 */
2445 "hangup", /* 1 SIGHUP */
2446 "interrupt", /* 2 SIGINT */
2447 "quit", /* 3 SIGQUIT */
2448 "illegal instruction", /* 4 SIGILL */
2449 "trace trap", /* 5 SIGTRAP */
2450 "IOT instruction", /* 6 SIGIOT */
2451 "EMT instruction", /* 7 SIGEMT */
2452 "floating point exception", /* 8 SIGFPE */
2453 "kill", /* 9 SIGKILL */
2454 "bus error", /* 10 SIGBUS */
2455 "segmentation violation", /* 11 SIGSEGV */
2456 "bad argument to system call", /* 12 SIGSYS */
2457 "write on a pipe with no one to read it", /* 13 SIGPIPE */
2458 "alarm clock", /* 14 SIGALRM */
2459 "software termination signum", /* 15 SIGTERM */
2460 "user defined signal 1", /* 16 SIGUSR1 */
2461 "user defined signal 2", /* 17 SIGUSR2 */
2462 "death of a child", /* 18 SIGCLD */
2463 "power-fail restart", /* 19 SIGPWR */
2464 #endif /* not AIX */
2469 * Warning, this function may not duplicate 4.2 action properly
2470 * under error conditions.
2474 /* In 4.1, param.h fails to define this. */
2475 #define MAXPATHLEN 1024
2484 char *npath
, *spath
;
2485 extern char *getcwd ();
2487 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2488 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2489 up to first slash. Should be harmless on other systems. */
2490 while (*npath
&& *npath
!= '/')
2492 strcpy (pathname
, npath
);
2493 free (spath
); /* getcwd uses malloc */
2497 #endif /* not HAVE_GETWD */
2502 * Emulate rename using unlink/link. Note that this is
2503 * only partially correct. Also, doesn't enforce restriction
2504 * that files be of same type (regular->regular, dir->dir, etc).
2508 #ifdef __STDC__ /* Avoid error if system has proper ANSI prototype. */
2516 if (access (from
, 0) == 0)
2519 if (link (from
, to
) == 0)
2520 if (unlink (from
) == 0)
2525 #endif /* not HAVE_RENAME */
2536 * Substitute fork(2) for vfork(2) on USG flavors.
2544 #endif /* not HAVE_VFORK */
2546 #ifdef MISSING_UTIMES
2548 /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */
2557 /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
2558 utimbuf structure defined anywhere but in the man page. */
2568 struct timeval tvp
[];
2571 utb
.actime
= tvp
[0].tv_sec
;
2572 utb
.modtime
= tvp
[1].tv_sec
;
2575 #endif /* IRIS_UTIME */
2581 /* HPUX curses library references perror, but as far as we know
2582 it won't be called. Anyway this definition will do for now. */
2594 * Emulate BSD dup2(2). First close newd if it already exists.
2595 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2596 * until we are, then close the unsuccessful ones.
2603 register int fd
, ret
;
2608 fd
= fcntl (oldd
, F_DUPFD
, newd
);
2610 error ("cant dup2 (%i,%i) : %s", oldd
, newd
, sys_errlist
[errno
]);
2617 ret
= dup2 (old
,new);
2623 #endif /* not HAVE_DUP2 */
2626 * Gettimeofday. Simulate as much as possible. Only accurate
2627 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2628 * Only needed when subprocesses are defined.
2632 #ifndef HAVE_GETTIMEOFDAY
2636 gettimeofday (tp
, tzp
)
2638 struct timezone
*tzp
;
2640 extern long time ();
2642 tp
->tv_sec
= time ((long *)0);
2648 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL */
2651 * This function will go away as soon as all the stubs fixed. (fnf)
2657 printf ("%s not yet implemented\r\n", badfunc
);
2666 char *sys_siglist
[NSIG
+ 1] =
2668 "null signal", /* 0 SIGNULL */
2669 "hangup", /* 1 SIGHUP */
2670 "interrupt", /* 2 SIGINT */
2671 "quit", /* 3 SIGQUIT */
2672 "illegal instruction", /* 4 SIGILL */
2673 "trace trap", /* 5 SIGTRAP */
2674 "abort termination", /* 6 SIGABRT */
2675 "SIGEMT", /* 7 SIGEMT */
2676 "floating point exception", /* 8 SIGFPE */
2677 "kill", /* 9 SIGKILL */
2678 "bus error", /* 10 SIGBUS */
2679 "segmentation violation", /* 11 SIGSEGV */
2680 "bad argument to system call", /* 12 SIGSYS */
2681 "write on a pipe with no reader", /* 13 SIGPIPE */
2682 "alarm clock", /* 14 SIGALRM */
2683 "software termination signal", /* 15 SIGTERM */
2684 "user defined signal 1", /* 16 SIGUSR1 */
2685 "user defined signal 2", /* 17 SIGUSR2 */
2686 "child stopped or terminated", /* 18 SIGCLD */
2687 "power-fail restart", /* 19 SIGPWR */
2688 "window size changed", /* 20 SIGWINCH */
2689 "undefined", /* 21 */
2690 "pollable event occured", /* 22 SIGPOLL */
2691 "sendable stop signal not from tty", /* 23 SIGSTOP */
2692 "stop signal from tty", /* 24 SIGSTP */
2693 "continue a stopped process", /* 25 SIGCONT */
2694 "attempted background tty read", /* 26 SIGTTIN */
2695 "attempted background tty write", /* 27 SIGTTOU */
2696 "undefined", /* 28 */
2697 "undefined", /* 29 */
2698 "undefined", /* 30 */
2699 "undefined", /* 31 */
2700 "undefined", /* 32 */
2701 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
2702 "I/O is possible", /* 34 SIGIO */
2703 "exceeded cpu time limit", /* 35 SIGXCPU */
2704 "exceeded file size limit", /* 36 SIGXFSZ */
2705 "virtual time alarm", /* 37 SIGVTALRM */
2706 "profiling time alarm", /* 38 SIGPROF */
2707 "undefined", /* 39 */
2708 "file record locks revoked", /* 40 SIGLOST */
2709 "undefined", /* 41 */
2710 "undefined", /* 42 */
2711 "undefined", /* 43 */
2712 "undefined", /* 44 */
2713 "undefined", /* 45 */
2714 "undefined", /* 46 */
2715 "undefined", /* 47 */
2716 "undefined", /* 48 */
2717 "undefined", /* 49 */
2718 "undefined", /* 50 */
2719 "undefined", /* 51 */
2720 "undefined", /* 52 */
2721 "undefined", /* 53 */
2722 "undefined", /* 54 */
2723 "undefined", /* 55 */
2724 "undefined", /* 56 */
2725 "undefined", /* 57 */
2726 "undefined", /* 58 */
2727 "undefined", /* 59 */
2728 "undefined", /* 60 */
2729 "undefined", /* 61 */
2730 "undefined", /* 62 */
2731 "undefined", /* 63 */
2732 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
2738 /* Directory routines for systems that don't have them. */
2740 #ifdef SYSV_SYSTEM_DIR
2744 #ifndef HAVE_CLOSEDIR
2747 register DIR *dirp
; /* stream from opendir */
2749 sys_close (dirp
->dd_fd
);
2750 free ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2751 free ((char *) dirp
);
2753 #endif /* not HAVE_CLOSEDIR */
2755 #endif /* SYSV_SYSTEM_DIR */
2757 #ifdef NONSYSTEM_DIR_LIBRARY
2761 char *filename
; /* name of directory */
2763 register DIR *dirp
; /* -> malloc'ed storage */
2764 register int fd
; /* file descriptor for read */
2765 struct stat sbuf
; /* result of fstat() */
2767 fd
= sys_open (filename
, 0);
2771 if (fstat (fd
, &sbuf
) < 0
2772 || (sbuf
.st_mode
& S_IFMT
) != S_IFDIR
2773 || (dirp
= (DIR *) malloc (sizeof (DIR))) == 0)
2776 return 0; /* bad luck today */
2780 dirp
->dd_loc
= dirp
->dd_size
= 0; /* refill needed */
2787 register DIR *dirp
; /* stream from opendir() */
2789 sys_close (dirp
->dd_fd
);
2790 free ((char *) dirp
);
2798 ino_t od_ino
; /* inode */
2799 char od_name
[DIRSIZ
]; /* filename */
2801 #endif /* not VMS */
2803 struct direct dir_static
; /* simulated directory contents */
2808 register DIR *dirp
; /* stream from opendir() */
2811 register struct olddir
*dp
; /* -> directory data */
2813 register struct dir$_name
*dp
; /* -> directory data */
2814 register struct dir$_version
*dv
; /* -> version data */
2819 if (dirp
->dd_loc
>= dirp
->dd_size
)
2820 dirp
->dd_loc
= dirp
->dd_size
= 0;
2822 if (dirp
->dd_size
== 0 /* refill buffer */
2823 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2827 dp
= (struct olddir
*) &dirp
->dd_buf
[dirp
->dd_loc
];
2828 dirp
->dd_loc
+= sizeof (struct olddir
);
2830 if (dp
->od_ino
!= 0) /* not deleted entry */
2832 dir_static
.d_ino
= dp
->od_ino
;
2833 strncpy (dir_static
.d_name
, dp
->od_name
, DIRSIZ
);
2834 dir_static
.d_name
[DIRSIZ
] = '\0';
2835 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2836 dir_static
.d_reclen
= sizeof (struct direct
)
2838 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2839 return &dir_static
; /* -> simulated structure */
2842 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2843 if (dirp
->dd_loc
== 0)
2844 dirp
->dd_loc
= (dp
->dir$b_namecount
&1) ? dp
->dir$b_namecount
+ 1
2845 : dp
->dir$b_namecount
;
2846 dv
= (struct dir$_version
*)&dp
->dir$t_name
[dirp
->dd_loc
];
2847 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2848 dir_static
.d_namlen
= dp
->dir$b_namecount
;
2849 dir_static
.d_reclen
= sizeof (struct direct
)
2851 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2852 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2853 dir_static
.d_name
[dir_static
.d_namlen
] = '\0';
2854 dirp
->dd_loc
= dirp
->dd_size
; /* only one record at a time */
2861 /* readdirver is just like readdir except it returns all versions of a file
2862 as separate entries. */
2867 register DIR *dirp
; /* stream from opendir() */
2869 register struct dir$_name
*dp
; /* -> directory data */
2870 register struct dir$_version
*dv
; /* -> version data */
2872 if (dirp
->dd_loc
>= dirp
->dd_size
- sizeof (struct dir$_name
))
2873 dirp
->dd_loc
= dirp
->dd_size
= 0;
2875 if (dirp
->dd_size
== 0 /* refill buffer */
2876 && (dirp
->dd_size
= sys_read (dirp
->dd_fd
, dirp
->dd_buf
, DIRBLKSIZ
)) <= 0)
2879 dp
= (struct dir$_name
*) dirp
->dd_buf
;
2880 if (dirp
->dd_loc
== 0)
2881 dirp
->dd_loc
= (dp
->dir$b_namecount
& 1) ? dp
->dir$b_namecount
+ 1
2882 : dp
->dir$b_namecount
;
2883 dv
= (struct dir$_version
*) &dp
->dir$t_name
[dirp
->dd_loc
];
2884 strncpy (dir_static
.d_name
, dp
->dir$t_name
, dp
->dir$b_namecount
);
2885 sprintf (&dir_static
.d_name
[dp
->dir$b_namecount
], ";%d", dv
->dir$w_version
);
2886 dir_static
.d_namlen
= strlen (dir_static
.d_name
);
2887 dir_static
.d_ino
= dv
->dir$w_fid_num
;
2888 dir_static
.d_reclen
= sizeof (struct direct
) - MAXNAMLEN
+ 3
2889 + dir_static
.d_namlen
- dir_static
.d_namlen
% 4;
2890 dirp
->dd_loc
= ((char *) (++dv
) - dp
->dir$t_name
);
2896 #endif /* NONSYSTEM_DIR_LIBRARY */
2898 /* Functions for VMS */
2900 #include "vms-pwd.h"
2905 /* Return as a string the VMS error string pertaining to STATUS.
2906 Reuses the same static buffer each time it is called. */
2910 int status
; /* VMS status code */
2914 static char buf
[257];
2916 bufadr
[0] = sizeof buf
- 1;
2917 bufadr
[1] = (int) buf
;
2918 if (! (SYS$
GETMSG (status
, &len
, bufadr
, 0x1, 0) & 1))
2919 return "untranslatable VMS error status";
2927 /* The following is necessary because 'access' emulation by VMS C (2.0) does
2928 * not work correctly. (It also doesn't work well in version 2.3.)
2933 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
2934 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
2938 unsigned short s_buflen
;
2939 unsigned short s_code
;
2941 unsigned short *s_retlenadr
;
2946 #define ITEMSETUP(CODE,VAR,RETLEN) \
2947 itemlst[cnt].s.s_buflen = sizeof (VAR); \
2948 itemlst[cnt].s.s_code = CODE; \
2949 itemlst[cnt].s.s_bufadr = (char *) &VAR; \
2950 itemlst[cnt++].s.s_retlenadr = (unsigned short *) &RETLEN
2952 #define R_OK 4 /* test for read permission */
2953 #define W_OK 2 /* test for write permission */
2954 #define X_OK 1 /* test for execute (search) permission */
2955 #define F_OK 0 /* test for presence of file */
2958 sys_access (path
, mode
)
2962 static char *user
= NULL
;
2965 /* translate possible directory spec into .DIR file name, so brain-dead
2966 * access() can treat the directory like a file. */
2967 if (directory_file_name (path
, dir_fn
))
2971 return access (path
, mode
);
2972 if (user
== NULL
&& (user
= (char *) getenv ("USER")) == NULL
)
2988 if ((mode
& X_OK
) && ((stat
= access(path
, mode
)) < 0 || mode
== X_OK
))
2991 flags
|= CHP$M_READ
;
2993 flags
|= CHP$M_WRITE
;
2997 /* Find privilege bits */
2998 stat
= sys$
setprv (0, 0, 0, prvmask
);
3000 /* Open the file, and find the particulars. */
3002 fab
.fab$b_fac
= FAB$M_GET
;
3003 fab
.fab$l_fna
= path
;
3004 fab
.fab$b_fns
= strlen (path
);
3005 fab
.fab$l_xab
= (char*) &xab
;
3006 xab
= cc$rms_xabpro
;
3007 xab
.xab$l_aclbuf
= (char*) alloca(60); /* Use 60 initially */;
3008 xab
.xab$w_aclsiz
= 60;
3009 stat
= sys$
open (&fab
, 0, 0);
3012 /* If ACL was not empty (2512) and error occurred, then deny access. */
3013 if ((xab
.xab$l_aclsts
!= 2512) && (! (xab
.xab$l_aclsts
& 1)))
3015 sys$
close (&fab
, 0, 0);
3017 /* See if we allocated enough space for the ACL. If not, create a larger
3018 buffer (now that we now know the actual size), and do it again. */
3020 if(xab
.xab$w_acllen
> xab
.xab$w_aclsiz
){
3021 xab
.xab$l_aclbuf
= (char *) alloca(xab
.xab$w_acllen
);
3022 xab
.xab$w_aclsiz
= xab
.xab$w_acllen
;
3023 xab
.xab$l_aclctx
= 0;
3024 stat
= sys$
open (&fab
, 0, 0);
3027 sys$
close (&fab
, 0, 0);
3030 ITEMSETUP(CHP$_OWNER
,xab
.xab$l_uic
,dummy
);
3031 ITEMSETUP(CHP$_PROT
,xab
.xab$w_pro
,dummy
);
3032 ITEMSETUP(CHP$_ACCESS
,acces
,dummy
);
3033 ITEMSETUP(CHP$_FLAGS
,flags
,dummy
);
3035 if (xab
.xab$w_acllen
!= 0)
3037 itemlst
[cnt
].s
.s_buflen
= xab
.xab$w_acllen
;
3038 itemlst
[cnt
].s
.s_code
= CHP$_ACL
;
3039 itemlst
[cnt
].s
.s_bufadr
= xab
.xab$l_aclbuf
;
3040 itemlst
[cnt
++].s
.s_retlenadr
= (unsigned short *) &dummy
;
3043 ITEMSETUP(CHP$_PRIV
,prvmask
,dummy
);
3044 /* ITEMSETUP(CHP$_PRIVUSED,pused,pusedl); For diagnostic purposes only */
3045 itemlst
[cnt
].s
.s_buflen
= 0;
3046 itemlst
[cnt
].s
.s_code
= CHP$_END
;
3048 /* SYS$CHECK_ACCESS can get privileges wrong. SYS$CHKPRO will not. */
3049 stat
= SYS$
CHKPRO(itemlst
);
3050 return stat
== SS$_NORMAL
? 0 : -1;
3054 #else /* not VMS4_4 */
3057 #define ACE$M_WRITE 2
3058 #define ACE$C_KEYID 1
3060 static unsigned short memid
, grpid
;
3061 static unsigned int uic
;
3063 /* Called from init_sys_modes, so it happens not very often
3064 but at least each time Emacs is loaded. */
3065 sys_access_reinit ()
3071 sys_access (filename
, type
)
3077 int status
, size
, i
, typecode
, acl_controlled
;
3078 unsigned int *aclptr
, *aclend
, aclbuf
[60];
3079 union prvdef prvmask
;
3081 /* Get UIC and GRP values for protection checking. */
3084 status
= LIB$
GETJPI (&JPI$_UIC
, 0, 0, &uic
, 0, 0);
3087 memid
= uic
& 0xFFFF;
3091 if (type
!= 2) /* not checking write access */
3092 return access (filename
, type
);
3094 /* Check write protection. */
3096 #define CHECKPRIV(bit) (prvmask.bit)
3097 #define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3099 /* Find privilege bits */
3100 status
= sys$
setprv (0, 0, 0, prvmask
);
3102 error ("Unable to find privileges: %s", vmserrstr (status
));
3103 if (CHECKPRIV (PRV$V_BYPASS
))
3104 return 0; /* BYPASS enabled */
3106 fab
.fab$b_fac
= FAB$M_GET
;
3107 fab
.fab$l_fna
= filename
;
3108 fab
.fab$b_fns
= strlen (filename
);
3109 fab
.fab$l_xab
= &xab
;
3110 xab
= cc$rms_xabpro
;
3111 xab
.xab$l_aclbuf
= aclbuf
;
3112 xab
.xab$w_aclsiz
= sizeof (aclbuf
);
3113 status
= sys$
open (&fab
, 0, 0);
3116 sys$
close (&fab
, 0, 0);
3117 /* Check system access */
3118 if (CHECKPRIV (PRV$V_SYSPRV
) && WRITEABLE (XAB$V_SYS
))
3120 /* Check ACL entries, if any */
3122 if (xab
.xab$w_acllen
> 0)
3125 aclend
= &aclbuf
[xab
.xab$w_acllen
/ 4];
3126 while (*aclptr
&& aclptr
< aclend
)
3128 size
= (*aclptr
& 0xff) / 4;
3129 typecode
= (*aclptr
>> 8) & 0xff;
3130 if (typecode
== ACE$C_KEYID
)
3131 for (i
= size
- 1; i
> 1; i
--)
3132 if (aclptr
[i
] == uic
)
3135 if (aclptr
[1] & ACE$M_WRITE
)
3136 return 0; /* Write access through ACL */
3138 aclptr
= &aclptr
[size
];
3140 if (acl_controlled
) /* ACL specified, prohibits write access */
3143 /* No ACL entries specified, check normal protection */
3144 if (WRITEABLE (XAB$V_WLD
)) /* World writeable */
3146 if (WRITEABLE (XAB$V_GRP
) &&
3147 (unsigned short) (xab
.xab$l_uic
>> 16) == grpid
)
3148 return 0; /* Group writeable */
3149 if (WRITEABLE (XAB$V_OWN
) &&
3150 (xab
.xab$l_uic
& 0xFFFF) == memid
)
3151 return 0; /* Owner writeable */
3153 return -1; /* Not writeable */
3155 #endif /* not VMS4_4 */
3158 static char vtbuf
[NAM$C_MAXRSS
+1];
3160 /* translate a vms file spec to a unix path */
3162 sys_translate_vms (vfile
)
3173 /* leading device or logical name is a root directory */
3174 if (p
= strchr (vfile
, ':'))
3183 if (*p
== '[' || *p
== '<')
3185 while (*++vfile
!= *p
+ 2)
3189 if (vfile
[-1] == *p
)
3212 static char utbuf
[NAM$C_MAXRSS
+1];
3214 /* translate a unix path to a VMS file spec */
3216 sys_translate_unix (ufile
)
3239 if (index (&ufile
[1], '/'))
3246 if (index (&ufile
[1], '/'))
3253 if (strncmp (ufile
, "./", 2) == 0)
3260 ufile
++; /* skip the dot */
3261 if (index (&ufile
[1], '/'))
3266 else if (strncmp (ufile
, "../", 3) == 0)
3274 ufile
+= 2; /* skip the dots */
3275 if (index (&ufile
[1], '/'))
3300 strcpy (pathname
, egetenv ("PATH"));
3305 if ('a' <= *ptr
&& *ptr
<= 'z')
3314 long item_code
= JPI$_OWNER
;
3315 unsigned long parent_id
;
3318 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &parent_id
)) & 1) == 0)
3321 vaxc$errno
= status
;
3331 return (getgid () << 16) | getuid ();
3335 sys_read (fildes
, buf
, nbyte
)
3340 return read (fildes
, buf
, (nbyte
< MAXIOSIZE
? nbyte
: MAXIOSIZE
));
3345 sys_write (fildes
, buf
, nbyte
)
3350 register int nwrote
, rtnval
= 0;
3352 while (nbyte
> MAXIOSIZE
&& (nwrote
= write (fildes
, buf
, MAXIOSIZE
)) > 0) {
3358 return rtnval
? rtnval
: -1;
3359 if ((nwrote
= write (fildes
, buf
, nbyte
)) < 0)
3360 return rtnval
? rtnval
: -1;
3361 return (rtnval
+ nwrote
);
3366 * VAX/VMS VAX C RTL really loses. It insists that records
3367 * end with a newline (carriage return) character, and if they
3368 * don't it adds one (nice of it isn't it!)
3370 * Thus we do this stupidity below.
3374 sys_write (fildes
, buf
, nbytes
)
3377 unsigned int nbytes
;
3384 fstat (fildes
, &st
);
3390 /* Handle fixed-length files with carriage control. */
3391 if (st
.st_fab_rfm
== FAB$C_FIX
3392 && ((st
.st_fab_rat
& (FAB$M_FTN
| FAB$M_CR
)) != 0))
3394 len
= st
.st_fab_mrs
;
3395 retval
= write (fildes
, p
, min (len
, nbytes
));
3398 retval
++; /* This skips the implied carriage control */
3402 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3403 while (*e
!= '\n' && e
> p
) e
--;
3404 if (p
== e
) /* Ok.. so here we add a newline... sigh. */
3405 e
= p
+ min (MAXIOSIZE
, nbytes
) - 1;
3407 retval
= write (fildes
, p
, len
);
3418 /* Create file NEW copying its attributes from file OLD. If
3419 OLD is 0 or does not exist, create based on the value of
3422 /* Protection value the file should ultimately have.
3423 Set by create_copy_attrs, and use by rename_sansversions. */
3424 static unsigned short int fab_final_pro
;
3427 creat_copy_attrs (old
, new)
3430 struct FAB fab
= cc$rms_fab
;
3431 struct XABPRO xabpro
;
3432 char aclbuf
[256]; /* Choice of size is arbitrary. See below. */
3433 extern int vms_stmlf_recfm
;
3437 fab
.fab$b_fac
= FAB$M_GET
;
3438 fab
.fab$l_fna
= old
;
3439 fab
.fab$b_fns
= strlen (old
);
3440 fab
.fab$l_xab
= (char *) &xabpro
;
3441 xabpro
= cc$rms_xabpro
;
3442 xabpro
.xab$l_aclbuf
= aclbuf
;
3443 xabpro
.xab$w_aclsiz
= sizeof aclbuf
;
3444 /* Call $OPEN to fill in the fab & xabpro fields. */
3445 if (sys$
open (&fab
, 0, 0) & 1)
3447 sys$
close (&fab
, 0, 0);
3448 fab
.fab$l_alq
= 0; /* zero the allocation quantity */
3449 if (xabpro
.xab$w_acllen
> 0)
3451 if (xabpro
.xab$w_acllen
> sizeof aclbuf
)
3452 /* If the acl buffer was too short, redo open with longer one.
3453 Wouldn't need to do this if there were some system imposed
3454 limit on the size of an ACL, but I can't find any such. */
3456 xabpro
.xab$l_aclbuf
= (char *) alloca (xabpro
.xab$w_acllen
);
3457 xabpro
.xab$w_aclsiz
= xabpro
.xab$w_acllen
;
3458 if (sys$
open (&fab
, 0, 0) & 1)
3459 sys$
close (&fab
, 0, 0);
3465 xabpro
.xab$l_aclbuf
= 0;
3470 fab
.fab$l_fna
= new;
3471 fab
.fab$b_fns
= strlen (new);
3475 fab
.fab$b_rfm
= vms_stmlf_recfm
? FAB$C_STMLF
: FAB$C_VAR
;
3476 fab
.fab$b_rat
= FAB$M_CR
;
3478 /* Set the file protections such that we will be able to manipulate
3479 this file. Once we are done writing and renaming it, we will set
3480 the protections back. */
3482 fab_final_pro
= xabpro
.xab$w_pro
;
3484 sys$
setdfprot (0, &fab_final_pro
);
3485 xabpro
.xab$w_pro
&= 0xff0f; /* set O:rewd for now. This is set back later. */
3486 /* Create the new file with either default attrs or attrs copied
3488 if (!(SYS$
CREATE (&fab
, 0, 0) & 1))
3490 sys$
close (&fab
, 0, 0);
3491 /* As this is a "replacement" for creat, return a file descriptor
3492 opened for writing. */
3493 return open (new, O_WRONLY
);
3498 #include <varargs.h>
3501 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
3505 sys_creat (va_alist
)
3508 va_list list_incrementor
;
3511 int rfd
; /* related file descriptor */
3512 int fd
; /* Our new file descriptor */
3519 extern int vms_stmlf_recfm
;
3522 va_start (list_incrementor
);
3523 name
= va_arg (list_incrementor
, char *);
3524 mode
= va_arg (list_incrementor
, int);
3526 rfd
= va_arg (list_incrementor
, int);
3527 va_end (list_incrementor
);
3530 /* Use information from the related file descriptor to set record
3531 format of the newly created file. */
3532 fstat (rfd
, &st_buf
);
3533 switch (st_buf
.st_fab_rfm
)
3536 strcpy (rfm
, "rfm = fix");
3537 sprintf (mrs
, "mrs = %d", st_buf
.st_fab_mrs
);
3538 strcpy (rat
, "rat = ");
3539 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3541 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3542 strcat (rat
, "ftn");
3543 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3544 strcat (rat
, "prn");
3545 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3546 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3547 strcat (rat
, ", blk");
3549 strcat (rat
, "blk");
3550 return creat (name
, 0, rfm
, rat
, mrs
);
3553 strcpy (rfm
, "rfm = vfc");
3554 sprintf (fsz
, "fsz = %d", st_buf
.st_fab_fsz
);
3555 strcpy (rat
, "rat = ");
3556 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3558 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3559 strcat (rat
, "ftn");
3560 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3561 strcat (rat
, "prn");
3562 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3563 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3564 strcat (rat
, ", blk");
3566 strcat (rat
, "blk");
3567 return creat (name
, 0, rfm
, rat
, fsz
);
3570 strcpy (rfm
, "rfm = stm");
3574 strcpy (rfm
, "rfm = stmcr");
3578 strcpy (rfm
, "rfm = stmlf");
3582 strcpy (rfm
, "rfm = udf");
3586 strcpy (rfm
, "rfm = var");
3589 strcpy (rat
, "rat = ");
3590 if (st_buf
.st_fab_rat
& FAB$M_CR
)
3592 else if (st_buf
.st_fab_rat
& FAB$M_FTN
)
3593 strcat (rat
, "ftn");
3594 else if (st_buf
.st_fab_rat
& FAB$M_PRN
)
3595 strcat (rat
, "prn");
3596 if (st_buf
.st_fab_rat
& FAB$M_BLK
)
3597 if (st_buf
.st_fab_rat
& (FAB$M_CR
|FAB$M_FTN
|FAB$M_PRN
))
3598 strcat (rat
, ", blk");
3600 strcat (rat
, "blk");
3604 strcpy (rfm
, vms_stmlf_recfm
? "rfm = stmlf" : "rfm=var");
3605 strcpy (rat
, "rat=cr");
3607 /* Until the VAX C RTL fixes the many bugs with modes, always use
3608 mode 0 to get the user's default protection. */
3609 fd
= creat (name
, 0, rfm
, rat
);
3610 if (fd
< 0 && errno
== EEXIST
)
3612 if (unlink (name
) < 0)
3613 report_file_error ("delete", build_string (name
));
3614 fd
= creat (name
, 0, rfm
, rat
);
3620 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
3621 sys_fwrite (ptr
, size
, num
, fp
)
3622 register char * ptr
;
3625 register int tot
= num
* size
;
3632 * The VMS C library routine creat() actually creates a new version of an
3633 * existing file rather than truncating the old version. There are times
3634 * when this is not the desired behavior, for instance, when writing an
3635 * auto save file (you only want one version), or when you don't have
3636 * write permission in the directory containing the file (but the file
3637 * itself is writable). Hence this routine, which is equivalent to
3638 * "close (creat (fn, 0));" on Unix if fn already exists.
3644 struct FAB xfab
= cc$rms_fab
;
3645 struct RAB xrab
= cc$rms_rab
;
3648 xfab
.fab$l_fop
= FAB$M_TEF
; /* free allocated but unused blocks on close */
3649 xfab
.fab$b_fac
= FAB$M_TRN
| FAB$M_GET
; /* allow truncate and get access */
3650 xfab
.fab$b_shr
= FAB$M_NIL
; /* allow no sharing - file must be locked */
3651 xfab
.fab$l_fna
= fn
;
3652 xfab
.fab$b_fns
= strlen (fn
);
3653 xfab
.fab$l_dna
= ";0"; /* default to latest version of the file */
3655 xrab
.rab$l_fab
= &xfab
;
3657 /* This gibberish opens the file, positions to the first record, and
3658 deletes all records from there until the end of file. */
3659 if ((sys$
open (&xfab
) & 01) == 01)
3661 if ((sys$
connect (&xrab
) & 01) == 01 &&
3662 (sys$
find (&xrab
) & 01) == 01 &&
3663 (sys$
truncate (&xrab
) & 01) == 01)
3674 /* Define this symbol to actually read SYSUAF.DAT. This requires either
3675 SYSPRV or a readable SYSUAF.DAT. */
3681 * Routine to read the VMS User Authorization File and return
3682 * a specific user's record.
3685 static struct UAF retuaf
;
3688 get_uaf_name (uname
)
3695 uaf_fab
= cc$rms_fab
;
3696 uaf_rab
= cc$rms_rab
;
3697 /* initialize fab fields */
3698 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3699 uaf_fab
.fab$b_fns
= 21;
3700 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3701 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3702 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3703 /* initialize rab fields */
3704 uaf_rab
.rab$l_fab
= &uaf_fab
;
3705 /* open the User Authorization File */
3706 status
= sys$
open (&uaf_fab
);
3710 vaxc$errno
= status
;
3713 status
= sys$
connect (&uaf_rab
);
3717 vaxc$errno
= status
;
3720 /* read the requested record - index is in uname */
3721 uaf_rab
.rab$l_kbf
= uname
;
3722 uaf_rab
.rab$b_ksz
= strlen (uname
);
3723 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3724 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3725 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3726 status
= sys$
get (&uaf_rab
);
3730 vaxc$errno
= status
;
3733 /* close the User Authorization File */
3734 status
= sys$
disconnect (&uaf_rab
);
3738 vaxc$errno
= status
;
3741 status
= sys$
close (&uaf_fab
);
3745 vaxc$errno
= status
;
3759 uaf_fab
= cc$rms_fab
;
3760 uaf_rab
= cc$rms_rab
;
3761 /* initialize fab fields */
3762 uaf_fab
.fab$l_fna
= "SYS$SYSTEM:SYSUAF.DAT";
3763 uaf_fab
.fab$b_fns
= 21;
3764 uaf_fab
.fab$b_fac
= FAB$M_GET
;
3765 uaf_fab
.fab$b_org
= FAB$C_IDX
;
3766 uaf_fab
.fab$b_shr
= FAB$M_GET
|FAB$M_PUT
|FAB$M_UPD
|FAB$M_DEL
;
3767 /* initialize rab fields */
3768 uaf_rab
.rab$l_fab
= &uaf_fab
;
3769 /* open the User Authorization File */
3770 status
= sys$
open (&uaf_fab
);
3774 vaxc$errno
= status
;
3777 status
= sys$
connect (&uaf_rab
);
3781 vaxc$errno
= status
;
3784 /* read the requested record - index is in uic */
3785 uaf_rab
.rab$b_krf
= 1; /* 1st alternate key */
3786 uaf_rab
.rab$l_kbf
= (char *) &uic
;
3787 uaf_rab
.rab$b_ksz
= sizeof uic
;
3788 uaf_rab
.rab$b_rac
= RAB$C_KEY
;
3789 uaf_rab
.rab$l_ubf
= (char *)&retuaf
;
3790 uaf_rab
.rab$w_usz
= sizeof retuaf
;
3791 status
= sys$
get (&uaf_rab
);
3795 vaxc$errno
= status
;
3798 /* close the User Authorization File */
3799 status
= sys$
disconnect (&uaf_rab
);
3803 vaxc$errno
= status
;
3806 status
= sys$
close (&uaf_fab
);
3810 vaxc$errno
= status
;
3816 static struct passwd retpw
;
3824 /* copy these out first because if the username is 32 chars, the next
3825 section will overwrite the first byte of the UIC */
3826 retpw
.pw_uid
= up
->uaf$w_mem
;
3827 retpw
.pw_gid
= up
->uaf$w_grp
;
3829 /* I suppose this is not the best sytle, to possibly overwrite one
3830 byte beyond the end of the field, but what the heck... */
3831 ptr
= &up
->uaf$t_username
[UAF$S_USERNAME
];
3832 while (ptr
[-1] == ' ')
3835 strcpy (retpw
.pw_name
, up
->uaf$t_username
);
3837 /* the rest of these are counted ascii strings */
3838 strncpy (retpw
.pw_gecos
, &up
->uaf$t_owner
[1], up
->uaf$t_owner
[0]);
3839 retpw
.pw_gecos
[up
->uaf$t_owner
[0]] = '\0';
3840 strncpy (retpw
.pw_dir
, &up
->uaf$t_defdev
[1], up
->uaf$t_defdev
[0]);
3841 retpw
.pw_dir
[up
->uaf$t_defdev
[0]] = '\0';
3842 strncat (retpw
.pw_dir
, &up
->uaf$t_defdir
[1], up
->uaf$t_defdir
[0]);
3843 retpw
.pw_dir
[up
->uaf$t_defdev
[0] + up
->uaf$t_defdir
[0]] = '\0';
3844 strncpy (retpw
.pw_shell
, &up
->uaf$t_defcli
[1], up
->uaf$t_defcli
[0]);
3845 retpw
.pw_shell
[up
->uaf$t_defcli
[0]] = '\0';
3849 #else /* not READ_SYSUAF */
3850 static struct passwd retpw
;
3851 #endif /* not READ_SYSUAF */
3862 unsigned char * full
;
3863 #endif /* READ_SYSUAF */
3868 if ('a' <= *ptr
&& *ptr
<= 'z')
3873 if (!(up
= get_uaf_name (name
)))
3875 return cnv_uaf_pw (up
);
3877 if (strcmp (name
, getenv ("USER")) == 0)
3879 retpw
.pw_uid
= getuid ();
3880 retpw
.pw_gid
= getgid ();
3881 strcpy (retpw
.pw_name
, name
);
3882 if (full
= (unsigned char*) egetenv ("FULLNAME"))
3883 strcpy (retpw
.pw_gecos
, full
);
3885 *retpw
.pw_gecos
= '\0';
3886 strcpy (retpw
.pw_dir
, egetenv ("HOME"));
3887 *retpw
.pw_shell
= '\0';
3892 #endif /* not READ_SYSUAF */
3902 if (!(up
= get_uaf_uic (uid
)))
3904 return cnv_uaf_pw (up
);
3906 if (uid
== sys_getuid ())
3907 return getpwnam (egetenv ("USER"));
3910 #endif /* not READ_SYSUAF */
3913 /* return total address space available to the current process. This is
3914 the sum of the current p0 size, p1 size and free page table entries
3919 unsigned long free_pages
;
3920 unsigned long frep0va
;
3921 unsigned long frep1va
;
3924 item_code
= JPI$_FREPTECNT
;
3925 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &free_pages
)) & 1) == 0)
3928 vaxc$errno
= status
;
3933 item_code
= JPI$_FREP0VA
;
3934 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep0va
)) & 1) == 0)
3937 vaxc$errno
= status
;
3940 item_code
= JPI$_FREP1VA
;
3941 if (((status
= LIB$
GETJPI (&item_code
, 0, 0, &frep1va
)) & 1) == 0)
3944 vaxc$errno
= status
;
3948 return free_pages
+ frep0va
+ (0x7fffffff - frep1va
);
3951 define_logical_name (varname
, string
)
3955 struct dsc$descriptor_s strdsc
=
3956 {strlen (string
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, string
};
3957 struct dsc$descriptor_s envdsc
=
3958 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3959 struct dsc$descriptor_s lnmdsc
=
3960 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3962 return LIB$
SET_LOGICAL (&envdsc
, &strdsc
, &lnmdsc
, 0, 0);
3965 delete_logical_name (varname
)
3968 struct dsc$descriptor_s envdsc
=
3969 {strlen (varname
), DSC$K_DTYPE_T
, DSC$K_CLASS_S
, varname
};
3970 struct dsc$descriptor_s lnmdsc
=
3971 {7, DSC$K_DTYPE_T
, DSC$K_CLASS_S
, "LNM$JOB"};
3973 return LIB$
DELETE_LOGICAL (&envdsc
, &lnmdsc
);
3987 error ("execvp system call not implemented");
3995 struct FAB from_fab
= cc$rms_fab
, to_fab
= cc$rms_fab
;
3996 struct NAM from_nam
= cc$rms_nam
, to_nam
= cc$rms_nam
;
3997 char from_esn
[NAM$C_MAXRSS
];
3998 char to_esn
[NAM$C_MAXRSS
];
4000 from_fab
.fab$l_fna
= from
;
4001 from_fab
.fab$b_fns
= strlen (from
);
4002 from_fab
.fab$l_nam
= &from_nam
;
4003 from_fab
.fab$l_fop
= FAB$M_NAM
;
4005 from_nam
.nam$l_esa
= from_esn
;
4006 from_nam
.nam$b_ess
= sizeof from_esn
;
4008 to_fab
.fab$l_fna
= to
;
4009 to_fab
.fab$b_fns
= strlen (to
);
4010 to_fab
.fab$l_nam
= &to_nam
;
4011 to_fab
.fab$l_fop
= FAB$M_NAM
;
4013 to_nam
.nam$l_esa
= to_esn
;
4014 to_nam
.nam$b_ess
= sizeof to_esn
;
4016 status
= SYS$
RENAME (&from_fab
, 0, 0, &to_fab
);
4022 if (status
== RMS$_DEV
)
4026 vaxc$errno
= status
;
4031 /* This function renames a file like `rename', but it strips
4032 the version number from the "to" filename, such that the "to" file is
4033 will always be a new version. It also sets the file protection once it is
4034 finished. The protection that we will use is stored in fab_final_pro,
4035 and was set when we did a creat_copy_attrs to create the file that we
4038 We could use the chmod function, but Eunichs uses 3 bits per user category
4039 to describe the protection, and VMS uses 4 (write and delete are seperate
4040 bits). To maintain portability, the VMS implementation of `chmod' wires
4041 the W and D bits together. */
4044 static struct fibdef fib
; /* We need this initialized to zero */
4045 char vms_file_written
[NAM$C_MAXRSS
];
4048 rename_sans_version (from
,to
)
4055 struct FAB to_fab
= cc$rms_fab
;
4056 struct NAM to_nam
= cc$rms_nam
;
4057 struct dsc$descriptor fib_d
={sizeof (fib
),0,0,(char*) &fib
};
4058 struct dsc$descriptor fib_attr
[2]
4059 = {{sizeof (fab_final_pro
),ATR$C_FPRO
,0,(char*) &fab_final_pro
},{0,0,0,0}};
4060 char to_esn
[NAM$C_MAXRSS
];
4062 $
DESCRIPTOR (disk
,to_esn
);
4064 to_fab
.fab$l_fna
= to
;
4065 to_fab
.fab$b_fns
= strlen (to
);
4066 to_fab
.fab$l_nam
= &to_nam
;
4067 to_fab
.fab$l_fop
= FAB$M_NAM
;
4069 to_nam
.nam$l_esa
= to_esn
;
4070 to_nam
.nam$b_ess
= sizeof to_esn
;
4072 status
= SYS$
PARSE (&to_fab
, 0, 0); /* figure out the full file name */
4074 if (to_nam
.nam$l_fnb
&& NAM$M_EXP_VER
)
4075 *(to_nam
.nam$l_ver
) = '\0';
4077 stat
= rename (from
, to_esn
);
4081 strcpy (vms_file_written
, to_esn
);
4083 to_fab
.fab$l_fna
= vms_file_written
; /* this points to the versionless name */
4084 to_fab
.fab$b_fns
= strlen (vms_file_written
);
4086 /* Now set the file protection to the correct value */
4087 sys$
open (&to_fab
, 0, 0); /* This fills in the nam$w_fid fields */
4089 /* Copy these fields into the fib */
4090 fib
.fib$r_fid_overlay
.fib$w_fid
[0] = to_nam
.nam$w_fid
[0];
4091 fib
.fib$r_fid_overlay
.fib$w_fid
[1] = to_nam
.nam$w_fid
[1];
4092 fib
.fib$r_fid_overlay
.fib$w_fid
[2] = to_nam
.nam$w_fid
[2];
4094 sys$
close (&to_fab
, 0, 0);
4096 stat
= sys$
assign (&disk
, &chan
, 0, 0); /* open a channel to the disk */
4099 stat
= sys$
qiow (0, chan
, IO$_MODIFY
, iosb
, 0, 0, &fib_d
,
4100 0, 0, 0, &fib_attr
, 0);
4103 stat
= sys$
dassgn (chan
);
4106 strcpy (vms_file_written
, to_esn
); /* We will write this to the screen*/
4116 unsigned short fid
[3];
4117 char esa
[NAM$C_MAXRSS
];
4120 fab
.fab$l_fop
= FAB$M_OFP
;
4121 fab
.fab$l_fna
= file
;
4122 fab
.fab$b_fns
= strlen (file
);
4123 fab
.fab$l_nam
= &nam
;
4126 nam
.nam$l_esa
= esa
;
4127 nam
.nam$b_ess
= NAM$C_MAXRSS
;
4129 status
= SYS$
PARSE (&fab
);
4130 if ((status
& 1) == 0)
4133 vaxc$errno
= status
;
4136 status
= SYS$
SEARCH (&fab
);
4137 if ((status
& 1) == 0)
4140 vaxc$errno
= status
;
4144 fid
[0] = nam
.nam$w_fid
[0];
4145 fid
[1] = nam
.nam$w_fid
[1];
4146 fid
[2] = nam
.nam$w_fid
[2];
4148 fab
.fab$l_fna
= new;
4149 fab
.fab$b_fns
= strlen (new);
4151 status
= SYS$
PARSE (&fab
);
4152 if ((status
& 1) == 0)
4155 vaxc$errno
= status
;
4159 nam
.nam$w_fid
[0] = fid
[0];
4160 nam
.nam$w_fid
[1] = fid
[1];
4161 nam
.nam$w_fid
[2] = fid
[2];
4163 nam
.nam$l_esa
= nam
.nam$l_name
;
4164 nam
.nam$b_esl
= nam
.nam$b_name
+ nam
.nam$b_type
+ nam
.nam$b_ver
;
4166 status
= SYS$
ENTER (&fab
);
4167 if ((status
& 1) == 0)
4170 vaxc$errno
= status
;
4180 printf ("%s not yet implemented\r\n", badfunc
);
4188 /* Arrange to return a range centered on zero. */
4189 return rand () - (1 << 30);
4198 #ifdef WRONG_NAME_INSQUE
4210 /* Called from init_sys_modes. */
4215 /* If we're not on an HFT we shouldn't do any of this. We determine
4216 if we are on an HFT by trying to get an HFT error code. If this
4217 call fails, we're not on an HFT. */
4219 if (ioctl (0, HFQERROR
, &junk
) < 0)
4221 #else /* not IBMR2AIX */
4222 if (ioctl (0, HFQEIO
, 0) < 0)
4224 #endif /* not IBMR2AIX */
4226 /* On AIX the default hft keyboard mapping uses backspace rather than delete
4227 as the rubout key's ASCII code. Here this is changed. The bug is that
4228 there's no way to determine the old mapping, so in reset_sys_modes
4229 we need to assume that the normal map had been present. Of course, this
4230 code also doesn't help if on a terminal emulator which doesn't understand
4234 struct hfkeymap keymap
;
4236 buf
.hf_bufp
= (char *)&keymap
;
4237 buf
.hf_buflen
= sizeof (keymap
);
4238 keymap
.hf_nkeys
= 2;
4239 keymap
.hfkey
[0].hf_kpos
= 15;
4240 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4242 keymap
.hfkey
[0].hf_keyidh
= '<';
4243 #else /* not IBMR2AIX */
4244 keymap
.hfkey
[0].hf_page
= '<';
4245 #endif /* not IBMR2AIX */
4246 keymap
.hfkey
[0].hf_char
= 127;
4247 keymap
.hfkey
[1].hf_kpos
= 15;
4248 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4250 keymap
.hfkey
[1].hf_keyidh
= '<';
4251 #else /* not IBMR2AIX */
4252 keymap
.hfkey
[1].hf_page
= '<';
4253 #endif /* not IBMR2AIX */
4254 keymap
.hfkey
[1].hf_char
= 127;
4255 hftctl (0, HFSKBD
, &buf
);
4257 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
4259 line_ins_del_ok
= char_ins_del_ok
= 0;
4262 /* Reset the rubout key to backspace. */
4267 struct hfkeymap keymap
;
4271 if (ioctl (0, HFQERROR
, &junk
) < 0)
4273 #else /* not IBMR2AIX */
4274 if (ioctl (0, HFQEIO
, 0) < 0)
4276 #endif /* not IBMR2AIX */
4278 buf
.hf_bufp
= (char *)&keymap
;
4279 buf
.hf_buflen
= sizeof (keymap
);
4280 keymap
.hf_nkeys
= 2;
4281 keymap
.hfkey
[0].hf_kpos
= 15;
4282 keymap
.hfkey
[0].hf_kstate
= HFMAPCHAR
| HFSHFNONE
;
4284 keymap
.hfkey
[0].hf_keyidh
= '<';
4285 #else /* not IBMR2AIX */
4286 keymap
.hfkey
[0].hf_page
= '<';
4287 #endif /* not IBMR2AIX */
4288 keymap
.hfkey
[0].hf_char
= 8;
4289 keymap
.hfkey
[1].hf_kpos
= 15;
4290 keymap
.hfkey
[1].hf_kstate
= HFMAPCHAR
| HFSHFSHFT
;
4292 keymap
.hfkey
[1].hf_keyidh
= '<';
4293 #else /* not IBMR2AIX */
4294 keymap
.hfkey
[1].hf_page
= '<';
4295 #endif /* not IBMR2AIX */
4296 keymap
.hfkey
[1].hf_char
= 8;
4297 hftctl (0, HFSKBD
, &buf
);