(struct window): New field too_small_ok.
[bpt/emacs.git] / src / sysdep.c
1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
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 2, or (at your option)
9 any later version.
10
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.
15
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, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 #include <signal.h>
23 #include <setjmp.h>
24
25 #include <config.h>
26 #include "lisp.h"
27 #include "blockinput.h"
28 #undef NULL
29
30 #define min(x,y) ((x) > (y) ? (y) : (x))
31
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. */
36 #ifndef read
37 #define sys_read read
38 #define sys_write write
39 #endif /* `read' is not a macro */
40
41 #undef read
42 #undef write
43
44 #ifdef WINDOWSNT
45 #define read _read
46 #define write _write
47 #include <windows.h>
48 extern int errno;
49 #endif /* not WINDOWSNT */
50
51 #ifndef close
52 #define sys_close close
53 #else
54 #undef close
55 #endif
56
57 #ifndef open
58 #define sys_open open
59 #else /* `open' is a macro */
60 #undef open
61 #endif /* `open' is a macro */
62
63 /* Does anyone other than VMS need this? */
64 #ifndef fwrite
65 #define sys_fwrite fwrite
66 #else
67 #undef fwrite
68 #endif
69
70 #ifndef HAVE_H_ERRNO
71 extern int h_errno;
72 #endif
73
74 #include <stdio.h>
75 #include <sys/types.h>
76 #include <sys/stat.h>
77 #include <errno.h>
78
79 /* Get _POSIX_VDISABLE, if it is available. */
80 #ifdef HAVE_UNISTD_H
81 #include <unistd.h>
82 #endif
83
84 /* Get SI_SRPC_DOMAIN, if it is available. */
85 #ifdef HAVE_SYS_SYSTEMINFO_H
86 #include <sys/systeminfo.h>
87 #endif
88
89 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
90 #include <dos.h>
91 #include "dosfns.h"
92 #include "msdos.h"
93 #include <sys/param.h>
94
95 #if __DJGPP__ > 1
96 extern int etext;
97 extern unsigned start __asm__ ("start");
98 #endif
99 #endif
100
101 extern int errno;
102
103 #ifdef VMS
104 #include <rms.h>
105 #include <ttdef.h>
106 #include <tt2def.h>
107 #include <iodef.h>
108 #include <ssdef.h>
109 #include <descrip.h>
110 #include <fibdef.h>
111 #include <atrdef.h>
112 #include <ctype.h>
113 #include <string.h>
114 #ifdef __GNUC__
115 #include <sys/file.h>
116 #else
117 #include <file.h>
118 #endif
119 #undef F_SETFL
120 #ifndef RAB$C_BID
121 #include <rab.h>
122 #endif
123 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
124 #endif /* VMS */
125
126 #ifndef BSD4_1
127 #ifdef BSD_SYSTEM /* avoid writing defined (BSD_SYSTEM) || defined (USG)
128 because the vms compiler doesn't grok `defined' */
129 #include <fcntl.h>
130 #endif
131 #ifdef USG
132 #ifndef USG5
133 #include <fcntl.h>
134 #endif
135 #endif
136 #endif /* not 4.1 bsd */
137
138 #ifndef MSDOS
139 #include <sys/ioctl.h>
140 #endif
141
142 #include "systty.h"
143 #include "syswait.h"
144
145 #ifdef BROKEN_TIOCGWINSZ
146 #undef TIOCGWINSZ
147 #undef TIOCSWINSZ
148 #endif
149
150 #if defined(USG) || defined(DGUX)
151 #include <sys/utsname.h>
152 #include <string.h>
153 #ifndef MEMORY_IN_STRING_H
154 #include <memory.h>
155 #endif
156 #if defined (TIOCGWINSZ) || defined (ISC4_0)
157 #ifdef NEED_SIOCTL
158 #include <sys/sioctl.h>
159 #endif
160 #ifdef NEED_PTEM_H
161 #include <sys/stream.h>
162 #include <sys/ptem.h>
163 #endif
164 #endif /* TIOCGWINSZ or ISC4_0 */
165 #endif /* USG or DGUX */
166
167 extern int quit_char;
168
169 #include "frame.h"
170 #include "window.h"
171 #include "termhooks.h"
172 #include "termchar.h"
173 #include "termopts.h"
174 #include "dispextern.h"
175 #include "process.h"
176
177 #ifdef WINDOWSNT
178 #include <direct.h>
179 /* In process.h which conflicts with the local copy. */
180 #define _P_WAIT 0
181 int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
182 int _CRTAPI1 _getpid (void);
183 #endif
184
185 #ifdef NONSYSTEM_DIR_LIBRARY
186 #include "ndir.h"
187 #endif /* NONSYSTEM_DIR_LIBRARY */
188
189 #include "syssignal.h"
190 #include "systime.h"
191 #ifdef HAVE_UTIME_H
192 #include <utime.h>
193 #endif
194
195 #ifndef HAVE_UTIMES
196 #ifndef HAVE_STRUCT_UTIMBUF
197 /* We want to use utime rather than utimes, but we couldn't find the
198 structure declaration. We'll use the traditional one. */
199 struct utimbuf {
200 long actime;
201 long modtime;
202 };
203 #endif
204 #endif
205
206 #ifndef VFORK_RETURN_TYPE
207 #define VFORK_RETURN_TYPE int
208 #endif
209
210 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
211 #ifndef LPASS8
212 #define LPASS8 0
213 #endif
214
215 #ifdef BSD4_1
216 #define LNOFLSH 0100000
217 #endif
218
219 static int baud_convert[] =
220 #ifdef BAUD_CONVERT
221 BAUD_CONVERT;
222 #else
223 {
224 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
225 1800, 2400, 4800, 9600, 19200, 38400
226 };
227 #endif
228
229 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
230 extern short ospeed;
231 #else
232 #if defined (HAVE_TERMIOS_H) && defined (LINUX)
233 #include <termios.h>
234 /* HJL's version of libc is said to need this on the Alpha.
235 On the other hand, DEC OSF1 on the Alpha needs ospeed to be a short. */
236 extern speed_t ospeed;
237 #else
238 extern short ospeed;
239 #endif
240 #endif
241
242 /* The file descriptor for Emacs's input terminal.
243 Under Unix, this is normally zero except when using X;
244 under VMS, we place the input channel number here. */
245 int input_fd;
246
247 void croak P_ ((char *));
248
249 #ifdef AIXHFT
250 void hft_init ();
251 void hft_reset ();
252 #endif
253
254 \f
255 /* Specify a different file descriptor for further input operations. */
256
257 void
258 change_input_fd (fd)
259 int fd;
260 {
261 input_fd = fd;
262 }
263
264 /* Discard pending input on descriptor input_fd. */
265
266 void
267 discard_tty_input ()
268 {
269 #ifndef WINDOWSNT
270 struct emacs_tty buf;
271
272 if (noninteractive)
273 return;
274
275 /* Discarding input is not safe when the input could contain
276 replies from the X server. So don't do it. */
277 if (read_socket_hook)
278 return;
279
280 #ifdef VMS
281 end_kbd_input ();
282 SYS$QIOW (0, input_fd, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
283 &buf.main, 0, 0, terminator_mask, 0, 0);
284 queue_kbd_input ();
285 #else /* not VMS */
286 #ifdef APOLLO
287 {
288 int zero = 0;
289 ioctl (input_fd, TIOCFLUSH, &zero);
290 }
291 #else /* not Apollo */
292 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
293 while (dos_keyread () != -1)
294 ;
295 #else /* not MSDOS */
296 EMACS_GET_TTY (input_fd, &buf);
297 EMACS_SET_TTY (input_fd, &buf, 0);
298 #endif /* not MSDOS */
299 #endif /* not Apollo */
300 #endif /* not VMS */
301 #endif /* not WINDOWSNT */
302 }
303
304 #ifdef SIGTSTP
305
306 /* Arrange for character C to be read as the next input from
307 the terminal. */
308
309 void
310 stuff_char (c)
311 char c;
312 {
313 if (read_socket_hook)
314 return;
315
316 /* Should perhaps error if in batch mode */
317 #ifdef TIOCSTI
318 ioctl (input_fd, TIOCSTI, &c);
319 #else /* no TIOCSTI */
320 error ("Cannot stuff terminal input characters in this version of Unix");
321 #endif /* no TIOCSTI */
322 }
323
324 #endif /* SIGTSTP */
325 \f
326 void
327 init_baud_rate ()
328 {
329 if (noninteractive)
330 ospeed = 0;
331 else
332 {
333 #ifdef INIT_BAUD_RATE
334 INIT_BAUD_RATE ();
335 #else
336 #ifdef DOS_NT
337 ospeed = 15;
338 #else /* not DOS_NT */
339 #ifdef VMS
340 struct sensemode sg;
341
342 SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
343 &sg.class, 12, 0, 0, 0, 0 );
344 ospeed = sg.xmit_baud;
345 #else /* not VMS */
346 #ifdef HAVE_TERMIOS
347 struct termios sg;
348
349 sg.c_cflag = B9600;
350 tcgetattr (input_fd, &sg);
351 ospeed = cfgetospeed (&sg);
352 #if defined (USE_GETOBAUD) && defined (getobaud)
353 /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
354 if (ospeed == 0)
355 ospeed = getobaud (sg.c_cflag);
356 #endif
357 #else /* neither VMS nor TERMIOS */
358 #ifdef HAVE_TERMIO
359 struct termio sg;
360
361 sg.c_cflag = B9600;
362 #ifdef HAVE_TCATTR
363 tcgetattr (input_fd, &sg);
364 #else
365 ioctl (input_fd, TCGETA, &sg);
366 #endif
367 ospeed = sg.c_cflag & CBAUD;
368 #else /* neither VMS nor TERMIOS nor TERMIO */
369 struct sgttyb sg;
370
371 sg.sg_ospeed = B9600;
372 if (ioctl (input_fd, TIOCGETP, &sg) < 0)
373 abort ();
374 ospeed = sg.sg_ospeed;
375 #endif /* not HAVE_TERMIO */
376 #endif /* not HAVE_TERMIOS */
377 #endif /* not VMS */
378 #endif /* not DOS_NT */
379 #endif /* not INIT_BAUD_RATE */
380 }
381
382 baud_rate = (ospeed < sizeof baud_convert / sizeof baud_convert[0]
383 ? baud_convert[ospeed] : 9600);
384 if (baud_rate == 0)
385 baud_rate = 1200;
386 }
387
388 /*ARGSUSED*/
389 void
390 set_exclusive_use (fd)
391 int fd;
392 {
393 #ifdef FIOCLEX
394 ioctl (fd, FIOCLEX, 0);
395 #endif
396 /* Ok to do nothing if this feature does not exist */
397 }
398 \f
399 #ifndef subprocesses
400
401 wait_without_blocking ()
402 {
403 #ifdef BSD_SYSTEM
404 wait3 (0, WNOHANG | WUNTRACED, 0);
405 #else
406 croak ("wait_without_blocking");
407 #endif
408 synch_process_alive = 0;
409 }
410
411 #endif /* not subprocesses */
412
413 int wait_debugging; /* Set nonzero to make following function work under dbx
414 (at least for bsd). */
415
416 SIGTYPE
417 wait_for_termination_signal ()
418 {}
419
420 /* Wait for subprocess with process id `pid' to terminate and
421 make sure it will get eliminated (not remain forever as a zombie) */
422
423 void
424 wait_for_termination (pid)
425 int pid;
426 {
427 while (1)
428 {
429 #ifdef subprocesses
430 #ifdef VMS
431 int status;
432
433 status = SYS$FORCEX (&pid, 0, 0);
434 break;
435 #else /* not VMS */
436 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
437 /* Note that kill returns -1 even if the process is just a zombie now.
438 But inevitably a SIGCHLD interrupt should be generated
439 and child_sig will do wait3 and make the process go away. */
440 /* There is some indication that there is a bug involved with
441 termination of subprocesses, perhaps involving a kernel bug too,
442 but no idea what it is. Just as a hunch we signal SIGCHLD to see
443 if that causes the problem to go away or get worse. */
444 sigsetmask (sigmask (SIGCHLD));
445 if (0 > kill (pid, 0))
446 {
447 sigsetmask (SIGEMPTYMASK);
448 kill (getpid (), SIGCHLD);
449 break;
450 }
451 if (wait_debugging)
452 sleep (1);
453 else
454 sigpause (SIGEMPTYMASK);
455 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
456 #if defined (UNIPLUS)
457 if (0 > kill (pid, 0))
458 break;
459 wait (0);
460 #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
461 #ifdef POSIX_SIGNALS /* would this work for LINUX as well? */
462 sigblock (sigmask (SIGCHLD));
463 if (0 > kill (pid, 0))
464 {
465 sigunblock (sigmask (SIGCHLD));
466 break;
467 }
468 sigpause (SIGEMPTYMASK);
469 #else /* not POSIX_SIGNALS */
470 #ifdef HAVE_SYSV_SIGPAUSE
471 sighold (SIGCHLD);
472 if (0 > kill (pid, 0))
473 {
474 sigrelse (SIGCHLD);
475 break;
476 }
477 sigpause (SIGCHLD);
478 #else /* not HAVE_SYSV_SIGPAUSE */
479 #ifdef WINDOWSNT
480 wait (0);
481 break;
482 #else /* not WINDOWSNT */
483 if (0 > kill (pid, 0))
484 break;
485 /* Using sleep instead of pause avoids timing error.
486 If the inferior dies just before the sleep,
487 we lose just one second. */
488 sleep (1);
489 #endif /* not WINDOWSNT */
490 #endif /* not HAVE_SYSV_SIGPAUSE */
491 #endif /* not POSIX_SIGNALS */
492 #endif /* not UNIPLUS */
493 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
494 #endif /* not VMS */
495 #else /* not subprocesses */
496 #if __DJGPP__ > 1
497 break;
498 #else /* not __DJGPP__ > 1 */
499 #ifndef BSD4_1
500 if (kill (pid, 0) < 0)
501 break;
502 wait (0);
503 #else /* BSD4_1 */
504 int status;
505 status = wait (0);
506 if (status == pid || status == -1)
507 break;
508 #endif /* BSD4_1 */
509 #endif /* not __DJGPP__ > 1*/
510 #endif /* not subprocesses */
511 }
512 }
513
514 #ifdef subprocesses
515
516 /*
517 * flush any pending output
518 * (may flush input as well; it does not matter the way we use it)
519 */
520
521 void
522 flush_pending_output (channel)
523 int channel;
524 {
525 #ifdef HAVE_TERMIOS
526 /* If we try this, we get hit with SIGTTIN, because
527 the child's tty belongs to the child's pgrp. */
528 #else
529 #ifdef TCFLSH
530 ioctl (channel, TCFLSH, 1);
531 #else
532 #ifdef TIOCFLUSH
533 int zero = 0;
534 /* 3rd arg should be ignored
535 but some 4.2 kernels actually want the address of an int
536 and nonzero means something different. */
537 ioctl (channel, TIOCFLUSH, &zero);
538 #endif
539 #endif
540 #endif
541 }
542 \f
543 #ifndef VMS
544 /* Set up the terminal at the other end of a pseudo-terminal that
545 we will be controlling an inferior through.
546 It should not echo or do line-editing, since that is done
547 in Emacs. No padding needed for insertion into an Emacs buffer. */
548
549 void
550 child_setup_tty (out)
551 int out;
552 {
553 #ifndef DOS_NT
554 struct emacs_tty s;
555
556 EMACS_GET_TTY (out, &s);
557
558 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
559 s.main.c_oflag |= OPOST; /* Enable output postprocessing */
560 s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */
561 #ifdef NLDLY
562 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
563 /* No output delays */
564 #endif
565 s.main.c_lflag &= ~ECHO; /* Disable echo */
566 s.main.c_lflag |= ISIG; /* Enable signals */
567 #ifdef IUCLC
568 s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */
569 #endif
570 #ifdef ISTRIP
571 s.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
572 #endif
573 #ifdef OLCUC
574 s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */
575 #endif
576 s.main.c_oflag &= ~TAB3; /* Disable tab expansion */
577 s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
578 #if 0
579 /* Said to be unnecessary: */
580 s.main.c_cc[VMIN] = 1; /* minimum number of characters to accept */
581 s.main.c_cc[VTIME] = 0; /* wait forever for at least 1 character */
582 #endif
583
584 s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */
585 s.main.c_cc[VEOF] = 04; /* insure that EOF is Control-D */
586 s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
587 s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
588
589 #ifdef HPUX
590 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
591 #endif /* HPUX */
592
593 #ifdef AIX
594 /* AIX enhanced edit loses NULs, so disable it */
595 #ifndef IBMR2AIX
596 s.main.c_line = 0;
597 s.main.c_iflag &= ~ASCEDIT;
598 #endif
599 /* Also, PTY overloads NUL and BREAK.
600 don't ignore break, but don't signal either, so it looks like NUL. */
601 s.main.c_iflag &= ~IGNBRK;
602 s.main.c_iflag &= ~BRKINT;
603 /* QUIT and INTR work better as signals, so disable character forms */
604 s.main.c_cc[VINTR] = 0377;
605 #ifdef SIGNALS_VIA_CHARACTERS
606 /* the QUIT and INTR character are used in process_send_signal
607 so set them here to something useful. */
608 if (s.main.c_cc[VQUIT] == 0377)
609 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
610 if (s.main.c_cc[VINTR] == 0377)
611 s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
612 #else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
613 /* QUIT and INTR work better as signals, so disable character forms */
614 s.main.c_cc[VQUIT] = 0377;
615 s.main.c_cc[VINTR] = 0377;
616 s.main.c_lflag &= ~ISIG;
617 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
618 s.main.c_cc[VEOL] = 0377;
619 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
620 #endif /* AIX */
621
622 #else /* not HAVE_TERMIO */
623
624 s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
625 | CBREAK | TANDEM);
626 s.main.sg_flags |= LPASS8;
627 s.main.sg_erase = 0377;
628 s.main.sg_kill = 0377;
629 s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */
630
631 #endif /* not HAVE_TERMIO */
632
633 EMACS_SET_TTY (out, &s, 0);
634
635 #ifdef BSD4_1
636 if (interrupt_input)
637 reset_sigio ();
638 #endif /* BSD4_1 */
639 #ifdef RTU
640 {
641 int zero = 0;
642 ioctl (out, FIOASYNC, &zero);
643 }
644 #endif /* RTU */
645 #endif /* not DOS_NT */
646 }
647 #endif /* not VMS */
648
649 #endif /* subprocesses */
650 \f
651 /* Record a signal code and the handler for it. */
652 struct save_signal
653 {
654 int code;
655 SIGTYPE (*handler) P_ ((int));
656 };
657
658 static void save_signal_handlers P_ ((struct save_signal *));
659 static void restore_signal_handlers P_ ((struct save_signal *));
660
661 /* Suspend the Emacs process; give terminal to its superior. */
662
663 void
664 sys_suspend ()
665 {
666 #ifdef VMS
667 /* "Foster" parentage allows emacs to return to a subprocess that attached
668 to the current emacs as a cheaper than starting a whole new process. This
669 is set up by KEPTEDITOR.COM. */
670 unsigned long parent_id, foster_parent_id;
671 char *fpid_string;
672
673 fpid_string = getenv ("EMACS_PARENT_PID");
674 if (fpid_string != NULL)
675 {
676 sscanf (fpid_string, "%x", &foster_parent_id);
677 if (foster_parent_id != 0)
678 parent_id = foster_parent_id;
679 else
680 parent_id = getppid ();
681 }
682 else
683 parent_id = getppid ();
684
685 xfree (fpid_string); /* On VMS, this was malloc'd */
686
687 if (parent_id && parent_id != 0xffffffff)
688 {
689 SIGTYPE (*oldsig)() = (int) signal (SIGINT, SIG_IGN);
690 int status = LIB$ATTACH (&parent_id) & 1;
691 signal (SIGINT, oldsig);
692 return status;
693 }
694 else
695 {
696 struct {
697 int l;
698 char *a;
699 } d_prompt;
700 d_prompt.l = sizeof ("Emacs: "); /* Our special prompt */
701 d_prompt.a = "Emacs: "; /* Just a reminder */
702 LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0);
703 return 1;
704 }
705 return -1;
706 #else
707 #if defined(SIGTSTP) && !defined(MSDOS)
708
709 {
710 int pgrp = EMACS_GETPGRP (0);
711 EMACS_KILLPG (pgrp, SIGTSTP);
712 }
713
714 #else /* No SIGTSTP */
715 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
716 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
717 kill (getpid (), SIGQUIT);
718
719 #else /* No SIGTSTP or USG_JOBCTRL */
720
721 /* On a system where suspending is not implemented,
722 instead fork a subshell and let it talk directly to the terminal
723 while we wait. */
724 sys_subshell ();
725
726 #endif /* no USG_JOBCTRL */
727 #endif /* no SIGTSTP */
728 #endif /* not VMS */
729 }
730
731 /* Fork a subshell. */
732
733 void
734 sys_subshell ()
735 {
736 #ifndef VMS
737 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
738 int st;
739 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
740 #endif
741 int pid;
742 struct save_signal saved_handlers[5];
743 Lisp_Object dir;
744 unsigned char *str = 0;
745 int len;
746
747 saved_handlers[0].code = SIGINT;
748 saved_handlers[1].code = SIGQUIT;
749 saved_handlers[2].code = SIGTERM;
750 #ifdef SIGIO
751 saved_handlers[3].code = SIGIO;
752 saved_handlers[4].code = 0;
753 #else
754 saved_handlers[3].code = 0;
755 #endif
756
757 /* Mentioning current_buffer->buffer would mean including buffer.h,
758 which somehow wedges the hp compiler. So instead... */
759
760 dir = intern ("default-directory");
761 if (NILP (Fboundp (dir)))
762 goto xyzzy;
763 dir = Fsymbol_value (dir);
764 if (!STRINGP (dir))
765 goto xyzzy;
766
767 dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
768 str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
769 len = XSTRING (dir)->size;
770 bcopy (XSTRING (dir)->data, str, len);
771 if (str[len - 1] != '/') str[len++] = '/';
772 str[len] = 0;
773 xyzzy:
774
775 #ifdef DOS_NT
776 pid = 0;
777 #if __DJGPP__ > 1
778 save_signal_handlers (saved_handlers);
779 synch_process_alive = 1;
780 #endif /* __DJGPP__ > 1 */
781 #else
782 pid = vfork ();
783 if (pid == -1)
784 error ("Can't spawn subshell");
785 #endif
786
787 if (pid == 0)
788 {
789 char *sh = 0;
790
791 #ifdef DOS_NT /* MW, Aug 1993 */
792 getwd (oldwd);
793 if (sh == 0)
794 sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
795 #endif
796 if (sh == 0)
797 sh = (char *) egetenv ("SHELL");
798 if (sh == 0)
799 sh = "sh";
800
801 /* Use our buffer's default directory for the subshell. */
802 if (str)
803 chdir ((char *) str);
804
805 #ifdef subprocesses
806 close_process_descs (); /* Close Emacs's pipes/ptys */
807 #endif
808
809 #ifdef SET_EMACS_PRIORITY
810 {
811 extern int emacs_priority;
812
813 if (emacs_priority < 0)
814 nice (-emacs_priority);
815 }
816 #endif
817
818 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
819 st = system (sh);
820 chdir (oldwd);
821 #if 0 /* This is also reported if last command executed in subshell failed, KFS */
822 if (st)
823 report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
824 #endif
825 #else /* not MSDOS */
826 #ifdef WINDOWSNT
827 /* Waits for process completion */
828 pid = _spawnlp (_P_WAIT, sh, sh, NULL);
829 chdir (oldwd);
830 if (pid == -1)
831 write (1, "Can't execute subshell", 22);
832 #else /* not WINDOWSNT */
833 execlp (sh, sh, 0);
834 write (1, "Can't execute subshell", 22);
835 _exit (1);
836 #endif /* not WINDOWSNT */
837 #endif /* not MSDOS */
838 }
839
840 /* Do this now if we did not do it before. */
841 #if !defined (MSDOS) || __DJGPP__ == 1
842 save_signal_handlers (saved_handlers);
843 synch_process_alive = 1;
844 #endif
845
846 #ifndef DOS_NT
847 wait_for_termination (pid);
848 #endif
849 restore_signal_handlers (saved_handlers);
850 synch_process_alive = 0;
851 #endif /* !VMS */
852 }
853
854 static void
855 save_signal_handlers (saved_handlers)
856 struct save_signal *saved_handlers;
857 {
858 while (saved_handlers->code)
859 {
860 saved_handlers->handler
861 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
862 saved_handlers++;
863 }
864 }
865
866 static void
867 restore_signal_handlers (saved_handlers)
868 struct save_signal *saved_handlers;
869 {
870 while (saved_handlers->code)
871 {
872 signal (saved_handlers->code, saved_handlers->handler);
873 saved_handlers++;
874 }
875 }
876 \f
877 #ifdef F_SETFL
878
879 int old_fcntl_flags;
880
881 void
882 init_sigio (fd)
883 int fd;
884 {
885 #ifdef FASYNC
886 old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC;
887 fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC);
888 #endif
889 interrupts_deferred = 0;
890 }
891
892 void
893 reset_sigio ()
894 {
895 unrequest_sigio ();
896 }
897
898 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
899
900 void
901 request_sigio ()
902 {
903 if (read_socket_hook)
904 return;
905
906 #ifdef SIGWINCH
907 sigunblock (sigmask (SIGWINCH));
908 #endif
909 fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC);
910
911 interrupts_deferred = 0;
912 }
913
914 void
915 unrequest_sigio ()
916 {
917 if (read_socket_hook)
918 return;
919
920 #ifdef SIGWINCH
921 sigblock (sigmask (SIGWINCH));
922 #endif
923 fcntl (input_fd, F_SETFL, old_fcntl_flags);
924 interrupts_deferred = 1;
925 }
926
927 #else /* no FASYNC */
928 #ifdef STRIDE /* Stride doesn't have FASYNC - use FIOASYNC */
929
930 void
931 request_sigio ()
932 {
933 int on = 1;
934
935 if (read_socket_hook)
936 return;
937
938 ioctl (input_fd, FIOASYNC, &on);
939 interrupts_deferred = 0;
940 }
941
942 void
943 unrequest_sigio ()
944 {
945 int off = 0;
946
947 if (read_socket_hook)
948 return;
949
950 ioctl (input_fd, FIOASYNC, &off);
951 interrupts_deferred = 1;
952 }
953
954 #else /* not FASYNC, not STRIDE */
955
956 #ifdef _CX_UX
957
958 #include <termios.h>
959
960 void
961 request_sigio ()
962 {
963 int on = 1;
964 sigset_t st;
965
966 if (read_socket_hook)
967 return;
968
969 sigemptyset(&st);
970 sigaddset(&st, SIGIO);
971 ioctl (input_fd, FIOASYNC, &on);
972 interrupts_deferred = 0;
973 sigprocmask(SIG_UNBLOCK, &st, (sigset_t *)0);
974 }
975
976 void
977 unrequest_sigio ()
978 {
979 int off = 0;
980
981 if (read_socket_hook)
982 return;
983
984 ioctl (input_fd, FIOASYNC, &off);
985 interrupts_deferred = 1;
986 }
987
988 #else /* ! _CX_UX */
989
990 void
991 request_sigio ()
992 {
993 if (read_socket_hook)
994 return;
995
996 croak ("request_sigio");
997 }
998
999 void
1000 unrequest_sigio ()
1001 {
1002 if (read_socket_hook)
1003 return;
1004
1005 croak ("unrequest_sigio");
1006 }
1007
1008 #endif /* _CX_UX */
1009 #endif /* STRIDE */
1010 #endif /* FASYNC */
1011 #endif /* F_SETFL */
1012 \f
1013 /* Saving and restoring the process group of Emacs's terminal. */
1014
1015 #ifdef BSD_PGRPS
1016
1017 /* The process group of which Emacs was a member when it initially
1018 started.
1019
1020 If Emacs was in its own process group (i.e. inherited_pgroup ==
1021 getpid ()), then we know we're running under a shell with job
1022 control (Emacs would never be run as part of a pipeline).
1023 Everything is fine.
1024
1025 If Emacs was not in its own process group, then we know we're
1026 running under a shell (or a caller) that doesn't know how to
1027 separate itself from Emacs (like sh). Emacs must be in its own
1028 process group in order to receive SIGIO correctly. In this
1029 situation, we put ourselves in our own pgroup, forcibly set the
1030 tty's pgroup to our pgroup, and make sure to restore and reinstate
1031 the tty's pgroup just like any other terminal setting. If
1032 inherited_group was not the tty's pgroup, then we'll get a
1033 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1034 it goes foreground in the future, which is what should happen. */
1035 int inherited_pgroup;
1036
1037 /* Split off the foreground process group to Emacs alone.
1038 When we are in the foreground, but not started in our own process
1039 group, redirect the TTY to point to our own process group. We need
1040 to be in our own process group to receive SIGIO properly. */
1041 void
1042 narrow_foreground_group ()
1043 {
1044 int me = getpid ();
1045
1046 setpgrp (0, inherited_pgroup);
1047 if (inherited_pgroup != me)
1048 EMACS_SET_TTY_PGRP (input_fd, &me);
1049 setpgrp (0, me);
1050 }
1051
1052 /* Set the tty to our original foreground group. */
1053 void
1054 widen_foreground_group ()
1055 {
1056 if (inherited_pgroup != getpid ())
1057 EMACS_SET_TTY_PGRP (input_fd, &inherited_pgroup);
1058 setpgrp (0, inherited_pgroup);
1059 }
1060
1061 #endif /* BSD_PGRPS */
1062 \f
1063 /* Getting and setting emacs_tty structures. */
1064
1065 /* Set *TC to the parameters associated with the terminal FD.
1066 Return zero if all's well, or -1 if we ran into an error we
1067 couldn't deal with. */
1068 int
1069 emacs_get_tty (fd, settings)
1070 int fd;
1071 struct emacs_tty *settings;
1072 {
1073 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1074 #ifdef HAVE_TCATTR
1075 /* We have those nifty POSIX tcmumbleattr functions. */
1076 bzero (&settings->main, sizeof (settings->main));
1077 if (tcgetattr (fd, &settings->main) < 0)
1078 return -1;
1079
1080 #else
1081 #ifdef HAVE_TERMIO
1082 /* The SYSV-style interface? */
1083 if (ioctl (fd, TCGETA, &settings->main) < 0)
1084 return -1;
1085
1086 #else
1087 #ifdef VMS
1088 /* Vehemently Monstrous System? :-) */
1089 if (! (SYS$QIOW (0, fd, IO$_SENSEMODE, settings, 0, 0,
1090 &settings->main.class, 12, 0, 0, 0, 0)
1091 & 1))
1092 return -1;
1093
1094 #else
1095 #ifndef DOS_NT
1096 /* I give up - I hope you have the BSD ioctls. */
1097 if (ioctl (fd, TIOCGETP, &settings->main) < 0)
1098 return -1;
1099 #endif /* not DOS_NT */
1100 #endif
1101 #endif
1102 #endif
1103
1104 /* Suivant - Do we have to get struct ltchars data? */
1105 #ifdef HAVE_LTCHARS
1106 if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
1107 return -1;
1108 #endif
1109
1110 /* How about a struct tchars and a wordful of lmode bits? */
1111 #ifdef HAVE_TCHARS
1112 if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
1113 || ioctl (fd, TIOCLGET, &settings->lmode) < 0)
1114 return -1;
1115 #endif
1116
1117 /* We have survived the tempest. */
1118 return 0;
1119 }
1120
1121
1122 /* Set the parameters of the tty on FD according to the contents of
1123 *SETTINGS. If FLUSHP is non-zero, we discard input.
1124 Return 0 if all went well, and -1 if anything failed. */
1125
1126 int
1127 emacs_set_tty (fd, settings, flushp)
1128 int fd;
1129 struct emacs_tty *settings;
1130 int flushp;
1131 {
1132 /* Set the primary parameters - baud rate, character size, etcetera. */
1133 #ifdef HAVE_TCATTR
1134 int i;
1135 /* We have those nifty POSIX tcmumbleattr functions.
1136 William J. Smith <wjs@wiis.wang.com> writes:
1137 "POSIX 1003.1 defines tcsetattr() to return success if it was
1138 able to perform any of the requested actions, even if some
1139 of the requested actions could not be performed.
1140 We must read settings back to ensure tty setup properly.
1141 AIX requires this to keep tty from hanging occasionally." */
1142 /* This make sure that we don't loop indefinitely in here. */
1143 for (i = 0 ; i < 10 ; i++)
1144 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
1145 {
1146 if (errno == EINTR)
1147 continue;
1148 else
1149 return -1;
1150 }
1151 else
1152 {
1153 struct termios new;
1154
1155 bzero (&new, sizeof (new));
1156 /* Get the current settings, and see if they're what we asked for. */
1157 tcgetattr (fd, &new);
1158 /* We cannot use memcmp on the whole structure here because under
1159 * aix386 the termios structure has some reserved field that may
1160 * not be filled in.
1161 */
1162 if ( new.c_iflag == settings->main.c_iflag
1163 && new.c_oflag == settings->main.c_oflag
1164 && new.c_cflag == settings->main.c_cflag
1165 && new.c_lflag == settings->main.c_lflag
1166 && memcmp(new.c_cc, settings->main.c_cc, NCCS) == 0)
1167 break;
1168 else
1169 continue;
1170 }
1171
1172 #else
1173 #ifdef HAVE_TERMIO
1174 /* The SYSV-style interface? */
1175 if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
1176 return -1;
1177
1178 #else
1179 #ifdef VMS
1180 /* Vehemently Monstrous System? :-) */
1181 if (! (SYS$QIOW (0, fd, IO$_SETMODE, &input_iosb, 0, 0,
1182 &settings->main.class, 12, 0, 0, 0, 0)
1183 & 1))
1184 return -1;
1185
1186 #else
1187 #ifndef DOS_NT
1188 /* I give up - I hope you have the BSD ioctls. */
1189 if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
1190 return -1;
1191 #endif /* not DOS_NT */
1192
1193 #endif
1194 #endif
1195 #endif
1196
1197 /* Suivant - Do we have to get struct ltchars data? */
1198 #ifdef HAVE_LTCHARS
1199 if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
1200 return -1;
1201 #endif
1202
1203 /* How about a struct tchars and a wordful of lmode bits? */
1204 #ifdef HAVE_TCHARS
1205 if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
1206 || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
1207 return -1;
1208 #endif
1209
1210 /* We have survived the tempest. */
1211 return 0;
1212 }
1213
1214 \f
1215 /* The initial tty mode bits */
1216 struct emacs_tty old_tty;
1217
1218 /* 1 if we have been through init_sys_modes. */
1219 int term_initted;
1220
1221 /* 1 if outer tty status has been recorded. */
1222 int old_tty_valid;
1223
1224 #ifdef BSD4_1
1225 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1226 sigio. */
1227 int lmode;
1228 #endif
1229
1230 #ifndef F_SETOWN_BUG
1231 #ifdef F_SETOWN
1232 int old_fcntl_owner;
1233 #endif /* F_SETOWN */
1234 #endif /* F_SETOWN_BUG */
1235
1236 /* This may also be defined in stdio,
1237 but if so, this does no harm,
1238 and using the same name avoids wasting the other one's space. */
1239
1240 #ifdef nec_ews_svr4
1241 extern char *_sobuf ;
1242 #else
1243 #if defined (USG) || defined (DGUX)
1244 unsigned char _sobuf[BUFSIZ+8];
1245 #else
1246 char _sobuf[BUFSIZ];
1247 #endif
1248 #endif
1249
1250 #ifdef HAVE_LTCHARS
1251 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
1252 #endif
1253 #ifdef HAVE_TCHARS
1254 static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
1255 #endif
1256
1257 void
1258 init_sys_modes ()
1259 {
1260 struct emacs_tty tty;
1261
1262 #ifdef VMS
1263 #if 0
1264 static int oob_chars[2] = {0, 1 << 7}; /* catch C-g's */
1265 extern int (*interrupt_signal) ();
1266 #endif
1267 #endif
1268
1269 Vtty_erase_char = Qnil;
1270
1271 if (noninteractive)
1272 return;
1273
1274 #ifdef VMS
1275 if (!input_ef)
1276 input_ef = get_kbd_event_flag ();
1277 /* LIB$GET_EF (&input_ef); */
1278 SYS$CLREF (input_ef);
1279 waiting_for_ast = 0;
1280 if (!timer_ef)
1281 timer_ef = get_timer_event_flag ();
1282 /* LIB$GET_EF (&timer_ef); */
1283 SYS$CLREF (timer_ef);
1284 #if 0
1285 if (!process_ef)
1286 {
1287 LIB$GET_EF (&process_ef);
1288 SYS$CLREF (process_ef);
1289 }
1290 if (input_ef / 32 != process_ef / 32)
1291 croak ("Input and process event flags in different clusters.");
1292 #endif
1293 if (input_ef / 32 != timer_ef / 32)
1294 croak ("Input and timer event flags in different clusters.");
1295 #if 0
1296 input_eflist = ((unsigned) 1 << (input_ef % 32)) |
1297 ((unsigned) 1 << (process_ef % 32));
1298 #endif
1299 timer_eflist = ((unsigned) 1 << (input_ef % 32)) |
1300 ((unsigned) 1 << (timer_ef % 32));
1301 #ifndef VMS4_4
1302 sys_access_reinit ();
1303 #endif
1304 #endif /* not VMS */
1305
1306 #ifdef BSD_PGRPS
1307 if (! read_socket_hook && EQ (Vwindow_system, Qnil))
1308 narrow_foreground_group ();
1309 #endif
1310
1311 #ifdef HAVE_WINDOW_SYSTEM
1312 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1313 needs the initialization code below. */
1314 if (!read_socket_hook && EQ (Vwindow_system, Qnil))
1315 #endif
1316 {
1317 EMACS_GET_TTY (input_fd, &old_tty);
1318
1319 old_tty_valid = 1;
1320
1321 tty = old_tty;
1322
1323 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1324 XSETINT (Vtty_erase_char, old_tty.main.c_cc[VERASE]);
1325
1326 #ifdef DGUX
1327 /* This allows meta to be sent on 8th bit. */
1328 tty.main.c_iflag &= ~INPCK; /* don't check input for parity */
1329 #endif
1330 tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
1331 tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
1332 #ifdef INLCR /* I'm just being cautious,
1333 since I can't check how widespread INLCR is--rms. */
1334 tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
1335 #endif
1336 #ifdef ISTRIP
1337 tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
1338 #endif
1339 tty.main.c_lflag &= ~ECHO; /* Disable echo */
1340 tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */
1341 #ifdef IEXTEN
1342 tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
1343 #endif
1344 tty.main.c_lflag |= ISIG; /* Enable signals */
1345 if (flow_control)
1346 {
1347 tty.main.c_iflag |= IXON; /* Enable start/stop output control */
1348 #ifdef IXANY
1349 tty.main.c_iflag &= ~IXANY;
1350 #endif /* IXANY */
1351 }
1352 else
1353 tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
1354 tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
1355 on output */
1356 tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */
1357 #ifdef CS8
1358 if (meta_key)
1359 {
1360 tty.main.c_cflag |= CS8; /* allow 8th bit on input */
1361 tty.main.c_cflag &= ~PARENB;/* Don't check parity */
1362 }
1363 #endif
1364 tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
1365 /* Set up C-g for both SIGQUIT and SIGINT.
1366 We don't know which we will get, but we handle both alike
1367 so which one it really gives us does not matter. */
1368 tty.main.c_cc[VQUIT] = quit_char;
1369 tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
1370 tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
1371 #ifdef VSWTCH
1372 tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
1373 of C-z */
1374 #endif /* VSWTCH */
1375
1376 #if defined (mips) || defined (HAVE_TCATTR)
1377 #ifdef VSUSP
1378 tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
1379 #endif /* VSUSP */
1380 #ifdef V_DSUSP
1381 tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
1382 #endif /* V_DSUSP */
1383 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1384 tty.main.c_cc[VDSUSP] = CDISABLE;
1385 #endif /* VDSUSP */
1386 #ifdef VLNEXT
1387 tty.main.c_cc[VLNEXT] = CDISABLE;
1388 #endif /* VLNEXT */
1389 #ifdef VREPRINT
1390 tty.main.c_cc[VREPRINT] = CDISABLE;
1391 #endif /* VREPRINT */
1392 #ifdef VWERASE
1393 tty.main.c_cc[VWERASE] = CDISABLE;
1394 #endif /* VWERASE */
1395 #ifdef VDISCARD
1396 tty.main.c_cc[VDISCARD] = CDISABLE;
1397 #endif /* VDISCARD */
1398
1399 if (flow_control)
1400 {
1401 #ifdef VSTART
1402 tty.main.c_cc[VSTART] = '\021';
1403 #endif /* VSTART */
1404 #ifdef VSTOP
1405 tty.main.c_cc[VSTOP] = '\023';
1406 #endif /* VSTOP */
1407 }
1408 else
1409 {
1410 #ifdef VSTART
1411 tty.main.c_cc[VSTART] = CDISABLE;
1412 #endif /* VSTART */
1413 #ifdef VSTOP
1414 tty.main.c_cc[VSTOP] = CDISABLE;
1415 #endif /* VSTOP */
1416 }
1417 #endif /* mips or HAVE_TCATTR */
1418
1419 #ifdef SET_LINE_DISCIPLINE
1420 /* Need to explicitly request TERMIODISC line discipline or
1421 Ultrix's termios does not work correctly. */
1422 tty.main.c_line = SET_LINE_DISCIPLINE;
1423 #endif
1424 #ifdef AIX
1425 #ifndef IBMR2AIX
1426 /* AIX enhanced edit loses NULs, so disable it. */
1427 tty.main.c_line = 0;
1428 tty.main.c_iflag &= ~ASCEDIT;
1429 #else
1430 tty.main.c_cc[VSTRT] = 255;
1431 tty.main.c_cc[VSTOP] = 255;
1432 tty.main.c_cc[VSUSP] = 255;
1433 tty.main.c_cc[VDSUSP] = 255;
1434 #endif /* IBMR2AIX */
1435 if (flow_control)
1436 {
1437 #ifdef VSTART
1438 tty.main.c_cc[VSTART] = '\021';
1439 #endif /* VSTART */
1440 #ifdef VSTOP
1441 tty.main.c_cc[VSTOP] = '\023';
1442 #endif /* VSTOP */
1443 }
1444 /* Also, PTY overloads NUL and BREAK.
1445 don't ignore break, but don't signal either, so it looks like NUL.
1446 This really serves a purpose only if running in an XTERM window
1447 or via TELNET or the like, but does no harm elsewhere. */
1448 tty.main.c_iflag &= ~IGNBRK;
1449 tty.main.c_iflag &= ~BRKINT;
1450 #endif
1451 #else /* if not HAVE_TERMIO */
1452 #ifdef VMS
1453 tty.main.tt_char |= TT$M_NOECHO;
1454 if (meta_key)
1455 tty.main.tt_char |= TT$M_EIGHTBIT;
1456 if (flow_control)
1457 tty.main.tt_char |= TT$M_TTSYNC;
1458 else
1459 tty.main.tt_char &= ~TT$M_TTSYNC;
1460 tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
1461 #else /* not VMS (BSD, that is) */
1462 #ifndef DOS_NT
1463 XSETINT (Vtty_erase_char, tty.main.sg_erase);
1464 tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1465 if (meta_key)
1466 tty.main.sg_flags |= ANYP;
1467 tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
1468 #endif /* not DOS_NT */
1469 #endif /* not VMS (BSD, that is) */
1470 #endif /* not HAVE_TERMIO */
1471
1472 /* If going to use CBREAK mode, we must request C-g to interrupt
1473 and turn off start and stop chars, etc. If not going to use
1474 CBREAK mode, do this anyway so as to turn off local flow
1475 control for user coming over network on 4.2; in this case,
1476 only t_stopc and t_startc really matter. */
1477 #ifndef HAVE_TERMIO
1478 #ifdef HAVE_TCHARS
1479 /* Note: if not using CBREAK mode, it makes no difference how we
1480 set this */
1481 tty.tchars = new_tchars;
1482 tty.tchars.t_intrc = quit_char;
1483 if (flow_control)
1484 {
1485 tty.tchars.t_startc = '\021';
1486 tty.tchars.t_stopc = '\023';
1487 }
1488
1489 tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_tty.lmode;
1490 #ifdef ultrix
1491 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1492 anything, and leaving it in breaks the meta key. Go figure. */
1493 tty.lmode &= ~LLITOUT;
1494 #endif
1495
1496 #ifdef BSD4_1
1497 lmode = tty.lmode;
1498 #endif
1499
1500 #endif /* HAVE_TCHARS */
1501 #endif /* not HAVE_TERMIO */
1502
1503 #ifdef HAVE_LTCHARS
1504 tty.ltchars = new_ltchars;
1505 #endif /* HAVE_LTCHARS */
1506 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1507 if (!term_initted)
1508 internal_terminal_init ();
1509 dos_ttraw ();
1510 #endif
1511
1512 EMACS_SET_TTY (input_fd, &tty, 0);
1513
1514 /* This code added to insure that, if flow-control is not to be used,
1515 we have an unlocked terminal at the start. */
1516
1517 #ifdef TCXONC
1518 if (!flow_control) ioctl (input_fd, TCXONC, 1);
1519 #endif
1520 #ifndef APOLLO
1521 #ifdef TIOCSTART
1522 if (!flow_control) ioctl (input_fd, TIOCSTART, 0);
1523 #endif
1524 #endif
1525
1526 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1527 #ifdef TCOON
1528 if (!flow_control) tcflow (input_fd, TCOON);
1529 #endif
1530 #endif
1531
1532 #ifdef AIXHFT
1533 hft_init ();
1534 #ifdef IBMR2AIX
1535 {
1536 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1537 to be only LF. This is the way that is done. */
1538 struct termio tty;
1539
1540 if (ioctl (1, HFTGETID, &tty) != -1)
1541 write (1, "\033[20l", 5);
1542 }
1543 #endif
1544 #endif /* AIXHFT */
1545
1546 #ifdef VMS
1547 /* Appears to do nothing when in PASTHRU mode.
1548 SYS$QIOW (0, input_fd, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1549 interrupt_signal, oob_chars, 0, 0, 0, 0);
1550 */
1551 queue_kbd_input (0);
1552 #endif /* VMS */
1553 }
1554
1555 #ifdef F_SETFL
1556 #ifndef F_SETOWN_BUG
1557 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1558 if (interrupt_input
1559 && ! read_socket_hook && EQ (Vwindow_system, Qnil))
1560 {
1561 old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0);
1562 fcntl (input_fd, F_SETOWN, getpid ());
1563 init_sigio (input_fd);
1564 }
1565 #endif /* F_GETOWN */
1566 #endif /* F_SETOWN_BUG */
1567 #endif /* F_SETFL */
1568
1569 #ifdef BSD4_1
1570 if (interrupt_input)
1571 init_sigio (input_fd);
1572 #endif
1573
1574 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1575 #undef _IOFBF
1576 #endif
1577 #ifdef _IOFBF
1578 /* This symbol is defined on recent USG systems.
1579 Someone says without this call USG won't really buffer the file
1580 even with a call to setbuf. */
1581 setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
1582 #else
1583 setbuf (stdout, (char *) _sobuf);
1584 #endif
1585 #ifdef HAVE_WINDOW_SYSTEM
1586 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1587 needs the initialization code below. */
1588 if (EQ (Vwindow_system, Qnil)
1589 #ifndef WINDOWSNT
1590 /* When running in tty mode on NT/Win95, we have a read_socket
1591 hook, but still need the rest of the initialization code below. */
1592 && (! read_socket_hook)
1593 #endif
1594 )
1595 #endif
1596 set_terminal_modes ();
1597
1598 if (!term_initted
1599 && FRAMEP (Vterminal_frame)
1600 && FRAME_TERMCAP_P (XFRAME (Vterminal_frame)))
1601 init_frame_faces (XFRAME (Vterminal_frame));
1602
1603 if (term_initted && no_redraw_on_reenter)
1604 {
1605 if (display_completed)
1606 direct_output_forward_char (0);
1607 }
1608 else
1609 {
1610 frame_garbaged = 1;
1611 if (FRAMEP (Vterminal_frame))
1612 FRAME_GARBAGED_P (XFRAME (Vterminal_frame)) = 1;
1613 }
1614
1615 term_initted = 1;
1616 }
1617
1618 /* Return nonzero if safe to use tabs in output.
1619 At the time this is called, init_sys_modes has not been done yet. */
1620
1621 int
1622 tabs_safe_p ()
1623 {
1624 struct emacs_tty tty;
1625
1626 EMACS_GET_TTY (input_fd, &tty);
1627 return EMACS_TTY_TABS_OK (&tty);
1628 }
1629 \f
1630 /* Get terminal size from system.
1631 Store number of lines into *HEIGHTP and width into *WIDTHP.
1632 We store 0 if there's no valid information. */
1633
1634 void
1635 get_frame_size (widthp, heightp)
1636 int *widthp, *heightp;
1637 {
1638
1639 #ifdef TIOCGWINSZ
1640
1641 /* BSD-style. */
1642 struct winsize size;
1643
1644 if (ioctl (input_fd, TIOCGWINSZ, &size) == -1)
1645 *widthp = *heightp = 0;
1646 else
1647 {
1648 *widthp = size.ws_col;
1649 *heightp = size.ws_row;
1650 }
1651
1652 #else
1653 #ifdef TIOCGSIZE
1654
1655 /* SunOS - style. */
1656 struct ttysize size;
1657
1658 if (ioctl (input_fd, TIOCGSIZE, &size) == -1)
1659 *widthp = *heightp = 0;
1660 else
1661 {
1662 *widthp = size.ts_cols;
1663 *heightp = size.ts_lines;
1664 }
1665
1666 #else
1667 #ifdef VMS
1668
1669 struct sensemode tty;
1670
1671 SYS$QIOW (0, input_fd, IO$_SENSEMODE, &tty, 0, 0,
1672 &tty.class, 12, 0, 0, 0, 0);
1673 *widthp = tty.scr_wid;
1674 *heightp = tty.scr_len;
1675
1676 #else
1677 #ifdef MSDOS
1678 *widthp = ScreenCols ();
1679 *heightp = ScreenRows ();
1680 #else /* system doesn't know size */
1681 *widthp = 0;
1682 *heightp = 0;
1683 #endif
1684
1685 #endif /* not VMS */
1686 #endif /* not SunOS-style */
1687 #endif /* not BSD-style */
1688 }
1689
1690 /* Set the logical window size associated with descriptor FD
1691 to HEIGHT and WIDTH. This is used mainly with ptys. */
1692
1693 int
1694 set_window_size (fd, height, width)
1695 int fd, height, width;
1696 {
1697 #ifdef TIOCSWINSZ
1698
1699 /* BSD-style. */
1700 struct winsize size;
1701 size.ws_row = height;
1702 size.ws_col = width;
1703
1704 if (ioctl (fd, TIOCSWINSZ, &size) == -1)
1705 return 0; /* error */
1706 else
1707 return 1;
1708
1709 #else
1710 #ifdef TIOCSSIZE
1711
1712 /* SunOS - style. */
1713 struct ttysize size;
1714 size.ts_lines = height;
1715 size.ts_cols = width;
1716
1717 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1718 return 0;
1719 else
1720 return 1;
1721 #else
1722 return -1;
1723 #endif /* not SunOS-style */
1724 #endif /* not BSD-style */
1725 }
1726
1727 \f
1728 /* Prepare the terminal for exiting Emacs; move the cursor to the
1729 bottom of the frame, turn off interrupt-driven I/O, etc. */
1730 void
1731 reset_sys_modes ()
1732 {
1733 if (noninteractive)
1734 {
1735 fflush (stdout);
1736 return;
1737 }
1738 if (!term_initted)
1739 return;
1740 #ifdef HAVE_WINDOW_SYSTEM
1741 /* Emacs' window system on MSDOG uses the `internal terminal' and therefore
1742 needs the clean-up code below. */
1743 if (!EQ (Vwindow_system, Qnil)
1744 #ifndef WINDOWSNT
1745 /* When running in tty mode on NT/Win95, we have a read_socket
1746 hook, but still need the rest of the clean-up code below. */
1747 || read_socket_hook
1748 #endif
1749 )
1750 return;
1751 #endif
1752 cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
1753 clear_end_of_line (FRAME_WIDTH (selected_frame));
1754 /* clear_end_of_line may move the cursor */
1755 cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0);
1756 #if defined (IBMR2AIX) && defined (AIXHFT)
1757 {
1758 /* HFT devices normally use ^J as a LF/CR. We forced it to
1759 do the LF only. Now, we need to reset it. */
1760 struct termio tty;
1761
1762 if (ioctl (1, HFTGETID, &tty) != -1)
1763 write (1, "\033[20h", 5);
1764 }
1765 #endif
1766
1767 reset_terminal_modes ();
1768 fflush (stdout);
1769 #ifdef BSD_SYSTEM
1770 #ifndef BSD4_1
1771 /* Avoid possible loss of output when changing terminal modes. */
1772 fsync (fileno (stdout));
1773 #endif
1774 #endif
1775
1776 #ifdef F_SETFL
1777 #ifndef F_SETOWN_BUG
1778 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1779 if (interrupt_input)
1780 {
1781 reset_sigio ();
1782 fcntl (input_fd, F_SETOWN, old_fcntl_owner);
1783 }
1784 #endif /* F_SETOWN */
1785 #endif /* F_SETOWN_BUG */
1786 #ifdef O_NDELAY
1787 fcntl (input_fd, F_SETFL, fcntl (input_fd, F_GETFL, 0) & ~O_NDELAY);
1788 #endif
1789 #endif /* F_SETFL */
1790 #ifdef BSD4_1
1791 if (interrupt_input)
1792 reset_sigio ();
1793 #endif /* BSD4_1 */
1794
1795 if (old_tty_valid)
1796 while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR)
1797 ;
1798
1799 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1800 dos_ttcooked ();
1801 #endif
1802
1803 #ifdef SET_LINE_DISCIPLINE
1804 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1805 A different old line discipline is therefore not restored, yet.
1806 Restore the old line discipline by hand. */
1807 ioctl (0, TIOCSETD, &old_tty.main.c_line);
1808 #endif
1809
1810 #ifdef AIXHFT
1811 hft_reset ();
1812 #endif
1813
1814 #ifdef BSD_PGRPS
1815 widen_foreground_group ();
1816 #endif
1817 }
1818 \f
1819 #ifdef HAVE_PTYS
1820
1821 /* Set up the proper status flags for use of a pty. */
1822
1823 void
1824 setup_pty (fd)
1825 int fd;
1826 {
1827 /* I'm told that TOICREMOTE does not mean control chars
1828 "can't be sent" but rather that they don't have
1829 input-editing or signaling effects.
1830 That should be good, because we have other ways
1831 to do those things in Emacs.
1832 However, telnet mode seems not to work on 4.2.
1833 So TIOCREMOTE is turned off now. */
1834
1835 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1836 will hang. In particular, the "timeout" feature (which
1837 causes a read to return if there is no data available)
1838 does this. Also it is known that telnet mode will hang
1839 in such a way that Emacs must be stopped (perhaps this
1840 is the same problem).
1841
1842 If TIOCREMOTE is turned off, then there is a bug in
1843 hp-ux which sometimes loses data. Apparently the
1844 code which blocks the master process when the internal
1845 buffer fills up does not work. Other than this,
1846 though, everything else seems to work fine.
1847
1848 Since the latter lossage is more benign, we may as well
1849 lose that way. -- cph */
1850 #ifdef FIONBIO
1851 #ifdef SYSV_PTYS
1852 {
1853 int on = 1;
1854 ioctl (fd, FIONBIO, &on);
1855 }
1856 #endif
1857 #endif
1858 #ifdef IBMRTAIX
1859 /* On AIX, the parent gets SIGHUP when a pty attached child dies. So, we */
1860 /* ignore SIGHUP once we've started a child on a pty. Note that this may */
1861 /* cause EMACS not to die when it should, i.e., when its own controlling */
1862 /* tty goes away. I've complained to the AIX developers, and they may */
1863 /* change this behavior, but I'm not going to hold my breath. */
1864 signal (SIGHUP, SIG_IGN);
1865 #endif
1866 }
1867 #endif /* HAVE_PTYS */
1868 \f
1869 #ifdef VMS
1870
1871 /* Assigning an input channel is done at the start of Emacs execution.
1872 This is called each time Emacs is resumed, also, but does nothing
1873 because input_chain is no longer zero. */
1874
1875 void
1876 init_vms_input ()
1877 {
1878 int status;
1879
1880 if (input_fd == 0)
1881 {
1882 status = SYS$ASSIGN (&input_dsc, &input_fd, 0, 0);
1883 if (! (status & 1))
1884 LIB$STOP (status);
1885 }
1886 }
1887
1888 /* Deassigning the input channel is done before exiting. */
1889
1890 void
1891 stop_vms_input ()
1892 {
1893 return SYS$DASSGN (input_fd);
1894 }
1895
1896 short input_buffer;
1897
1898 /* Request reading one character into the keyboard buffer.
1899 This is done as soon as the buffer becomes empty. */
1900
1901 void
1902 queue_kbd_input ()
1903 {
1904 int status;
1905 extern kbd_input_ast ();
1906
1907 waiting_for_ast = 0;
1908 stop_input = 0;
1909 status = SYS$QIO (0, input_fd, IO$_READVBLK,
1910 &input_iosb, kbd_input_ast, 1,
1911 &input_buffer, 1, 0, terminator_mask, 0, 0);
1912 }
1913
1914 int input_count;
1915
1916 /* Ast routine that is called when keyboard input comes in
1917 in accord with the SYS$QIO above. */
1918
1919 void
1920 kbd_input_ast ()
1921 {
1922 register int c = -1;
1923 int old_errno = errno;
1924 extern EMACS_TIME *input_available_clear_time;
1925
1926 if (waiting_for_ast)
1927 SYS$SETEF (input_ef);
1928 waiting_for_ast = 0;
1929 input_count++;
1930 #ifdef ASTDEBUG
1931 if (input_count == 25)
1932 exit (1);
1933 printf ("Ast # %d,", input_count);
1934 printf (" iosb = %x, %x, %x, %x",
1935 input_iosb.offset, input_iosb.status, input_iosb.termlen,
1936 input_iosb.term);
1937 #endif
1938 if (input_iosb.offset)
1939 {
1940 c = input_buffer;
1941 #ifdef ASTDEBUG
1942 printf (", char = 0%o", c);
1943 #endif
1944 }
1945 #ifdef ASTDEBUG
1946 printf ("\n");
1947 fflush (stdout);
1948 sleep (1);
1949 #endif
1950 if (! stop_input)
1951 queue_kbd_input ();
1952 if (c >= 0)
1953 {
1954 struct input_event e;
1955 e.kind = ascii_keystroke;
1956 XSETINT (e.code, c);
1957 XSETFRAME (e.frame_or_window, selected_frame);
1958 kbd_buffer_store_event (&e);
1959 }
1960 if (input_available_clear_time)
1961 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
1962 errno = old_errno;
1963 }
1964
1965 /* Wait until there is something in kbd_buffer. */
1966
1967 void
1968 wait_for_kbd_input ()
1969 {
1970 extern int have_process_input, process_exited;
1971
1972 /* If already something, avoid doing system calls. */
1973 if (detect_input_pending ())
1974 {
1975 return;
1976 }
1977 /* Clear a flag, and tell ast routine above to set it. */
1978 SYS$CLREF (input_ef);
1979 waiting_for_ast = 1;
1980 /* Check for timing error: ast happened while we were doing that. */
1981 if (!detect_input_pending ())
1982 {
1983 /* No timing error: wait for flag to be set. */
1984 set_waiting_for_input (0);
1985 SYS$WFLOR (input_ef, input_eflist);
1986 clear_waiting_for_input (0);
1987 if (!detect_input_pending ())
1988 /* Check for subprocess input availability */
1989 {
1990 int dsp = have_process_input || process_exited;
1991
1992 SYS$CLREF (process_ef);
1993 if (have_process_input)
1994 process_command_input ();
1995 if (process_exited)
1996 process_exit ();
1997 if (dsp)
1998 {
1999 update_mode_lines++;
2000 prepare_menu_bars ();
2001 redisplay_preserve_echo_area ();
2002 }
2003 }
2004 }
2005 waiting_for_ast = 0;
2006 }
2007
2008 /* Get rid of any pending QIO, when we are about to suspend
2009 or when we want to throw away pending input.
2010 We wait for a positive sign that the AST routine has run
2011 and therefore there is no I/O request queued when we return.
2012 SYS$SETAST is used to avoid a timing error. */
2013
2014 void
2015 end_kbd_input ()
2016 {
2017 #ifdef ASTDEBUG
2018 printf ("At end_kbd_input.\n");
2019 fflush (stdout);
2020 sleep (1);
2021 #endif
2022 if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2023 {
2024 SYS$CANCEL (input_fd);
2025 return;
2026 }
2027
2028 SYS$SETAST (0);
2029 /* Clear a flag, and tell ast routine above to set it. */
2030 SYS$CLREF (input_ef);
2031 waiting_for_ast = 1;
2032 stop_input = 1;
2033 SYS$CANCEL (input_fd);
2034 SYS$SETAST (1);
2035 SYS$WAITFR (input_ef);
2036 waiting_for_ast = 0;
2037 }
2038
2039 /* Wait for either input available or time interval expiry. */
2040
2041 void
2042 input_wait_timeout (timeval)
2043 int timeval; /* Time to wait, in seconds */
2044 {
2045 int time [2];
2046 static int zero = 0;
2047 static int large = -10000000;
2048
2049 LIB$EMUL (&timeval, &large, &zero, time); /* Convert to VMS format */
2050
2051 /* If already something, avoid doing system calls. */
2052 if (detect_input_pending ())
2053 {
2054 return;
2055 }
2056 /* Clear a flag, and tell ast routine above to set it. */
2057 SYS$CLREF (input_ef);
2058 waiting_for_ast = 1;
2059 /* Check for timing error: ast happened while we were doing that. */
2060 if (!detect_input_pending ())
2061 {
2062 /* No timing error: wait for flag to be set. */
2063 SYS$CANTIM (1, 0);
2064 if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
2065 SYS$WFLOR (timer_ef, timer_eflist); /* Wait for timer expiry or input */
2066 }
2067 waiting_for_ast = 0;
2068 }
2069
2070 /* The standard `sleep' routine works some other way
2071 and it stops working if you have ever quit out of it.
2072 This one continues to work. */
2073
2074 sys_sleep (timeval)
2075 int timeval;
2076 {
2077 int time [2];
2078 static int zero = 0;
2079 static int large = -10000000;
2080
2081 LIB$EMUL (&timeval, &large, &zero, time); /* Convert to VMS format */
2082
2083 SYS$CANTIM (1, 0);
2084 if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
2085 SYS$WAITFR (timer_ef); /* Wait for timer expiry only */
2086 }
2087
2088 void
2089 init_sigio (fd)
2090 int fd;
2091 {
2092 request_sigio ();
2093 }
2094
2095 reset_sigio ()
2096 {
2097 unrequest_sigio ();
2098 }
2099
2100 void
2101 request_sigio ()
2102 {
2103 croak ("request sigio");
2104 }
2105
2106 void
2107 unrequest_sigio ()
2108 {
2109 croak ("unrequest sigio");
2110 }
2111
2112 #endif /* VMS */
2113 \f
2114 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2115 #ifndef CANNOT_DUMP
2116 #define NEED_STARTS
2117 #endif
2118
2119 #ifndef SYSTEM_MALLOC
2120 #ifndef NEED_STARTS
2121 #define NEED_STARTS
2122 #endif
2123 #endif
2124
2125 #ifdef NEED_STARTS
2126 /* Some systems that cannot dump also cannot implement these. */
2127
2128 /*
2129 * Return the address of the start of the text segment prior to
2130 * doing an unexec. After unexec the return value is undefined.
2131 * See crt0.c for further explanation and _start.
2132 *
2133 */
2134
2135 #ifndef HAVE_TEXT_START
2136 char *
2137 start_of_text ()
2138 {
2139 #ifdef TEXT_START
2140 return ((char *) TEXT_START);
2141 #else
2142 #ifdef GOULD
2143 extern csrt ();
2144 return ((char *) csrt);
2145 #else /* not GOULD */
2146 extern int _start ();
2147 return ((char *) _start);
2148 #endif /* GOULD */
2149 #endif /* TEXT_START */
2150 }
2151 #endif /* not HAVE_TEXT_START */
2152
2153 /*
2154 * Return the address of the start of the data segment prior to
2155 * doing an unexec. After unexec the return value is undefined.
2156 * See crt0.c for further information and definition of data_start.
2157 *
2158 * Apparently, on BSD systems this is etext at startup. On
2159 * USG systems (swapping) this is highly mmu dependent and
2160 * is also dependent on whether or not the program is running
2161 * with shared text. Generally there is a (possibly large)
2162 * gap between end of text and start of data with shared text.
2163 *
2164 * On Uniplus+ systems with shared text, data starts at a
2165 * fixed address. Each port (from a given oem) is generally
2166 * different, and the specific value of the start of data can
2167 * be obtained via the UniPlus+ specific "uvar" system call,
2168 * however the method outlined in crt0.c seems to be more portable.
2169 *
2170 * Probably what will have to happen when a USG unexec is available,
2171 * at least on UniPlus, is temacs will have to be made unshared so
2172 * that text and data are contiguous. Then once loadup is complete,
2173 * unexec will produce a shared executable where the data can be
2174 * at the normal shared text boundary and the startofdata variable
2175 * will be patched by unexec to the correct value.
2176 *
2177 */
2178
2179 char *
2180 start_of_data ()
2181 {
2182 #ifdef DATA_START
2183 return ((char *) DATA_START);
2184 #else
2185 #ifdef ORDINARY_LINK
2186 /*
2187 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2188 * data_start isn't defined. We take the address of environ, which
2189 * is known to live at or near the start of the system crt0.c, and
2190 * we don't sweat the handful of bytes that might lose.
2191 */
2192 extern char **environ;
2193
2194 return((char *) &environ);
2195 #else
2196 extern int data_start;
2197 return ((char *) &data_start);
2198 #endif /* ORDINARY_LINK */
2199 #endif /* DATA_START */
2200 }
2201 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2202
2203 #ifndef CANNOT_DUMP
2204 /* Some systems that cannot dump also cannot implement these. */
2205
2206 /*
2207 * Return the address of the end of the text segment prior to
2208 * doing an unexec. After unexec the return value is undefined.
2209 */
2210
2211 char *
2212 end_of_text ()
2213 {
2214 #ifdef TEXT_END
2215 return ((char *) TEXT_END);
2216 #else
2217 extern int etext;
2218 return ((char *) &etext);
2219 #endif
2220 }
2221
2222 /*
2223 * Return the address of the end of the data segment prior to
2224 * doing an unexec. After unexec the return value is undefined.
2225 */
2226
2227 char *
2228 end_of_data ()
2229 {
2230 #ifdef DATA_END
2231 return ((char *) DATA_END);
2232 #else
2233 extern int edata;
2234 return ((char *) &edata);
2235 #endif
2236 }
2237
2238 #endif /* not CANNOT_DUMP */
2239 \f
2240 /* init_system_name sets up the string for the Lisp function
2241 system-name to return. */
2242
2243 #ifdef BSD4_1
2244 #include <whoami.h>
2245 #endif
2246
2247 extern Lisp_Object Vsystem_name;
2248
2249 #ifndef BSD4_1
2250 #ifndef VMS
2251 #ifdef HAVE_SOCKETS
2252 #include <sys/socket.h>
2253 #include <netdb.h>
2254 #endif /* HAVE_SOCKETS */
2255 #endif /* not VMS */
2256 #endif /* not BSD4_1 */
2257
2258 void
2259 init_system_name ()
2260 {
2261 #ifdef BSD4_1
2262 Vsystem_name = build_string (sysname);
2263 #else
2264 #ifdef VMS
2265 char *sp, *end;
2266 if ((sp = egetenv ("SYS$NODE")) == 0)
2267 Vsystem_name = build_string ("vax-vms");
2268 else if ((end = index (sp, ':')) == 0)
2269 Vsystem_name = build_string (sp);
2270 else
2271 Vsystem_name = make_string (sp, end - sp);
2272 #else
2273 #ifndef HAVE_GETHOSTNAME
2274 struct utsname uts;
2275 uname (&uts);
2276 Vsystem_name = build_string (uts.nodename);
2277 #else /* HAVE_GETHOSTNAME */
2278 unsigned int hostname_size = 256;
2279 char *hostname = (char *) alloca (hostname_size);
2280
2281 /* Try to get the host name; if the buffer is too short, try
2282 again. Apparently, the only indication gethostname gives of
2283 whether the buffer was large enough is the presence or absence
2284 of a '\0' in the string. Eech. */
2285 for (;;)
2286 {
2287 gethostname (hostname, hostname_size - 1);
2288 hostname[hostname_size - 1] = '\0';
2289
2290 /* Was the buffer large enough for the '\0'? */
2291 if (strlen (hostname) < hostname_size - 1)
2292 break;
2293
2294 hostname_size <<= 1;
2295 hostname = (char *) alloca (hostname_size);
2296 }
2297 #ifdef HAVE_SOCKETS
2298 /* Turn the hostname into the official, fully-qualified hostname.
2299 Don't do this if we're going to dump; this can confuse system
2300 libraries on some machines and make the dumped emacs core dump. */
2301 #ifndef CANNOT_DUMP
2302 if (initialized)
2303 #endif /* not CANNOT_DUMP */
2304 if (! index (hostname, '.'))
2305 {
2306 struct hostent *hp;
2307 int count;
2308 for (count = 0;; count++)
2309 {
2310 #ifdef TRY_AGAIN
2311 h_errno = 0;
2312 #endif
2313 hp = gethostbyname (hostname);
2314 #ifdef TRY_AGAIN
2315 if (! (hp == 0 && h_errno == TRY_AGAIN))
2316 #endif
2317 break;
2318 if (count >= 5)
2319 break;
2320 Fsleep_for (make_number (1), Qnil);
2321 }
2322 if (hp)
2323 {
2324 char *fqdn = (char *) hp->h_name;
2325 char *p;
2326
2327 if (!index (fqdn, '.'))
2328 {
2329 /* We still don't have a fully qualified domain name.
2330 Try to find one in the list of alternate names */
2331 char **alias = hp->h_aliases;
2332 while (*alias && !index (*alias, '.'))
2333 alias++;
2334 if (*alias)
2335 fqdn = *alias;
2336 }
2337 hostname = fqdn;
2338 #if 0
2339 /* Convert the host name to lower case. */
2340 /* Using ctype.h here would introduce a possible locale
2341 dependence that is probably wrong for hostnames. */
2342 p = hostname;
2343 while (*p)
2344 {
2345 if (*p >= 'A' && *p <= 'Z')
2346 *p += 'a' - 'A';
2347 p++;
2348 }
2349 #endif
2350 }
2351 }
2352 #endif /* HAVE_SOCKETS */
2353 /* We used to try using getdomainname here,
2354 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2355 getdomainname gets the NIS/YP domain which often is not the same
2356 as in Internet domain name. */
2357 #if 0 /* Turned off because sysinfo is not really likely to return the
2358 correct Internet domain. */
2359 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2360 if (! index (hostname, '.'))
2361 {
2362 /* The hostname is not fully qualified. Append the domain name. */
2363
2364 int hostlen = strlen (hostname);
2365 int domain_size = 256;
2366
2367 for (;;)
2368 {
2369 char *domain = (char *) alloca (domain_size + 1);
2370 char *fqdn = (char *) alloca (hostlen + 1 + domain_size + 1);
2371 int sys_domain_size = sysinfo (SI_SRPC_DOMAIN, domain, domain_size);
2372 if (sys_domain_size <= 0)
2373 break;
2374 if (domain_size < sys_domain_size)
2375 {
2376 domain_size = sys_domain_size;
2377 continue;
2378 }
2379 strcpy (fqdn, hostname);
2380 if (domain[0] == '.')
2381 strcpy (fqdn + hostlen, domain);
2382 else if (domain[0] != 0)
2383 {
2384 fqdn[hostlen] = '.';
2385 strcpy (fqdn + hostlen + 1, domain);
2386 }
2387 hostname = fqdn;
2388 break;
2389 }
2390 }
2391 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2392 #endif /* 0 */
2393 Vsystem_name = build_string (hostname);
2394 #endif /* HAVE_GETHOSTNAME */
2395 #endif /* VMS */
2396 #endif /* BSD4_1 */
2397 {
2398 unsigned char *p;
2399 for (p = XSTRING (Vsystem_name)->data; *p; p++)
2400 if (*p == ' ' || *p == '\t')
2401 *p = '-';
2402 }
2403 }
2404 \f
2405 #ifndef MSDOS
2406 #ifndef VMS
2407 #if !defined (HAVE_SELECT) || defined (BROKEN_SELECT_NON_X)
2408
2409 #include "sysselect.h"
2410 #undef select
2411
2412 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2413 /* Cause explanatory error message at compile time,
2414 since the select emulation is not good enough for X. */
2415 int *x = &x_windows_lose_if_no_select_system_call;
2416 #endif
2417
2418 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2419 * Only checks read descriptors.
2420 */
2421 /* How long to wait between checking fds in select */
2422 #define SELECT_PAUSE 1
2423 int select_alarmed;
2424
2425 /* For longjmp'ing back to read_input_waiting. */
2426
2427 jmp_buf read_alarm_throw;
2428
2429 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2430 The read_socket_hook function sets this to 1 while it is waiting. */
2431
2432 int read_alarm_should_throw;
2433
2434 SIGTYPE
2435 select_alarm ()
2436 {
2437 select_alarmed = 1;
2438 #ifdef BSD4_1
2439 sigrelse (SIGALRM);
2440 #else /* not BSD4_1 */
2441 signal (SIGALRM, SIG_IGN);
2442 #endif /* not BSD4_1 */
2443 if (read_alarm_should_throw)
2444 longjmp (read_alarm_throw, 1);
2445 }
2446
2447 #ifndef WINDOWSNT
2448 /* Only rfds are checked. */
2449 int
2450 sys_select (nfds, rfds, wfds, efds, timeout)
2451 int nfds;
2452 SELECT_TYPE *rfds, *wfds, *efds;
2453 EMACS_TIME *timeout;
2454 {
2455 int ravail = 0, old_alarm;
2456 SELECT_TYPE orfds;
2457 int timeoutval;
2458 int *local_timeout;
2459 extern int proc_buffered_char[];
2460 #ifndef subprocesses
2461 int process_tick = 0, update_tick = 0;
2462 #else
2463 extern int process_tick, update_tick;
2464 #endif
2465 SIGTYPE (*old_trap) ();
2466 unsigned char buf;
2467
2468 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2469 /* If we're using X, then the native select will work; we only need the
2470 emulation for non-X usage. */
2471 if (!NILP (Vwindow_system))
2472 return select (nfds, rfds, wfds, efds, timeout);
2473 #endif
2474 timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
2475 local_timeout = &timeoutval;
2476 FD_ZERO (&orfds);
2477 if (rfds)
2478 {
2479 orfds = *rfds;
2480 FD_ZERO (rfds);
2481 }
2482 if (wfds)
2483 FD_ZERO (wfds);
2484 if (efds)
2485 FD_ZERO (efds);
2486
2487 /* If we are looking only for the terminal, with no timeout,
2488 just read it and wait -- that's more efficient. */
2489 if (*local_timeout == 100000 && process_tick == update_tick
2490 && FD_ISSET (0, &orfds))
2491 {
2492 int fd;
2493 for (fd = 1; fd < nfds; ++fd)
2494 if (FD_ISSET (fd, &orfds))
2495 goto hardway;
2496 if (! detect_input_pending ())
2497 read_input_waiting ();
2498 FD_SET (0, rfds);
2499 return 1;
2500 }
2501
2502 hardway:
2503 /* Once a second, till the timer expires, check all the flagged read
2504 * descriptors to see if any input is available. If there is some then
2505 * set the corresponding bit in the return copy of rfds.
2506 */
2507 while (1)
2508 {
2509 register int to_check, fd;
2510
2511 if (rfds)
2512 {
2513 for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
2514 {
2515 if (FD_ISSET (fd, &orfds))
2516 {
2517 int avail = 0, status = 0;
2518
2519 if (fd == 0)
2520 avail = detect_input_pending (); /* Special keyboard handler */
2521 else
2522 {
2523 #ifdef FIONREAD
2524 status = ioctl (fd, FIONREAD, &avail);
2525 #else /* no FIONREAD */
2526 /* Hoping it will return -1 if nothing available
2527 or 0 if all 0 chars requested are read. */
2528 if (proc_buffered_char[fd] >= 0)
2529 avail = 1;
2530 else
2531 {
2532 avail = read (fd, &buf, 1);
2533 if (avail > 0)
2534 proc_buffered_char[fd] = buf;
2535 }
2536 #endif /* no FIONREAD */
2537 }
2538 if (status >= 0 && avail > 0)
2539 {
2540 FD_SET (fd, rfds);
2541 ravail++;
2542 }
2543 }
2544 }
2545 }
2546 if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
2547 break;
2548 old_alarm = alarm (0);
2549 old_trap = signal (SIGALRM, select_alarm);
2550 select_alarmed = 0;
2551 alarm (SELECT_PAUSE);
2552 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2553 while (select_alarmed == 0 && *local_timeout != 0
2554 && process_tick == update_tick)
2555 {
2556 /* If we are interested in terminal input,
2557 wait by reading the terminal.
2558 That makes instant wakeup for terminal input at least. */
2559 if (FD_ISSET (0, &orfds))
2560 {
2561 read_input_waiting ();
2562 if (detect_input_pending ())
2563 select_alarmed = 1;
2564 }
2565 else
2566 pause ();
2567 }
2568 (*local_timeout) -= SELECT_PAUSE;
2569 /* Reset the old alarm if there was one */
2570 alarm (0);
2571 signal (SIGALRM, old_trap);
2572 if (old_alarm != 0)
2573 {
2574 /* Reset or forge an interrupt for the original handler. */
2575 old_alarm -= SELECT_PAUSE;
2576 if (old_alarm <= 0)
2577 kill (getpid (), SIGALRM); /* Fake an alarm with the orig' handler */
2578 else
2579 alarm (old_alarm);
2580 }
2581 if (*local_timeout == 0) /* Stop on timer being cleared */
2582 break;
2583 }
2584 return ravail;
2585 }
2586 #endif /* not WINDOWSNT */
2587
2588 /* Read keyboard input into the standard buffer,
2589 waiting for at least one character. */
2590
2591 /* Make all keyboard buffers much bigger when using a window system. */
2592 #ifdef HAVE_WINDOW_SYSTEM
2593 #define BUFFER_SIZE_FACTOR 16
2594 #else
2595 #define BUFFER_SIZE_FACTOR 1
2596 #endif
2597
2598 void
2599 read_input_waiting ()
2600 {
2601 struct input_event e;
2602 int nread, i;
2603 extern int quit_char;
2604
2605 if (read_socket_hook)
2606 {
2607 struct input_event buf[256];
2608
2609 read_alarm_should_throw = 0;
2610 if (! setjmp (read_alarm_throw))
2611 nread = (*read_socket_hook) (0, buf, 256, 1, 0);
2612 else
2613 nread = -1;
2614
2615 /* Scan the chars for C-g and store them in kbd_buffer. */
2616 for (i = 0; i < nread; i++)
2617 {
2618 kbd_buffer_store_event (&buf[i]);
2619 /* Don't look at input that follows a C-g too closely.
2620 This reduces lossage due to autorepeat on C-g. */
2621 if (buf[i].kind == ascii_keystroke
2622 && buf[i].code == quit_char)
2623 break;
2624 }
2625 }
2626 else
2627 {
2628 char buf[3];
2629 nread = read (fileno (stdin), buf, 1);
2630
2631 /* Scan the chars for C-g and store them in kbd_buffer. */
2632 e.kind = ascii_keystroke;
2633 XSETFRAME (e.frame_or_window, selected_frame);
2634 e.modifiers = 0;
2635 for (i = 0; i < nread; i++)
2636 {
2637 /* Convert chars > 0177 to meta events if desired.
2638 We do this under the same conditions that read_avail_input does. */
2639 if (read_socket_hook == 0)
2640 {
2641 /* If the user says she has a meta key, then believe her. */
2642 if (meta_key == 1 && (buf[i] & 0x80))
2643 e.modifiers = meta_modifier;
2644 if (meta_key != 2)
2645 buf[i] &= ~0x80;
2646 }
2647
2648 XSETINT (e.code, buf[i]);
2649 kbd_buffer_store_event (&e);
2650 /* Don't look at input that follows a C-g too closely.
2651 This reduces lossage due to autorepeat on C-g. */
2652 if (buf[i] == quit_char)
2653 break;
2654 }
2655 }
2656 }
2657
2658 #endif /* not HAVE_SELECT */
2659 #endif /* not VMS */
2660 #endif /* not MSDOS */
2661 \f
2662 #ifdef BSD4_1
2663 /*
2664 * Partially emulate 4.2 open call.
2665 * open is defined as this in 4.1.
2666 *
2667 * - added by Michael Bloom @ Citicorp/TTI
2668 *
2669 */
2670
2671 int
2672 sys_open (path, oflag, mode)
2673 char *path;
2674 int oflag, mode;
2675 {
2676 if (oflag & O_CREAT)
2677 return creat (path, mode);
2678 else
2679 return open (path, oflag);
2680 }
2681
2682 void
2683 init_sigio (fd)
2684 int fd;
2685 {
2686 if (noninteractive)
2687 return;
2688 lmode = LINTRUP | lmode;
2689 ioctl (fd, TIOCLSET, &lmode);
2690 }
2691
2692 void
2693 reset_sigio ()
2694 {
2695 if (noninteractive)
2696 return;
2697 lmode = ~LINTRUP & lmode;
2698 ioctl (0, TIOCLSET, &lmode);
2699 }
2700
2701 void
2702 request_sigio ()
2703 {
2704 sigrelse (SIGTINT);
2705
2706 interrupts_deferred = 0;
2707 }
2708
2709 void
2710 unrequest_sigio ()
2711 {
2712 sighold (SIGTINT);
2713
2714 interrupts_deferred = 1;
2715 }
2716
2717 /* still inside #ifdef BSD4_1 */
2718 #ifdef subprocesses
2719
2720 int sigheld; /* Mask of held signals */
2721
2722 void
2723 sigholdx (signum)
2724 int signum;
2725 {
2726 sigheld |= sigbit (signum);
2727 sighold (signum);
2728 }
2729
2730 void
2731 sigisheld (signum)
2732 int signum;
2733 {
2734 sigheld |= sigbit (signum);
2735 }
2736
2737 void
2738 sigunhold (signum)
2739 int signum;
2740 {
2741 sigheld &= ~sigbit (signum);
2742 sigrelse (signum);
2743 }
2744
2745 void
2746 sigfree () /* Free all held signals */
2747 {
2748 int i;
2749 for (i = 0; i < NSIG; i++)
2750 if (sigheld & sigbit (i))
2751 sigrelse (i);
2752 sigheld = 0;
2753 }
2754
2755 int
2756 sigbit (i)
2757 {
2758 return 1 << (i - 1);
2759 }
2760 #endif /* subprocesses */
2761 #endif /* BSD4_1 */
2762 \f
2763 /* POSIX signals support - DJB */
2764 /* Anyone with POSIX signals should have ANSI C declarations */
2765
2766 #ifdef POSIX_SIGNALS
2767
2768 sigset_t empty_mask, full_mask;
2769
2770 void
2771 init_signals ()
2772 {
2773 sigemptyset (&empty_mask);
2774 sigfillset (&full_mask);
2775 }
2776
2777 signal_handler_t
2778 sys_signal (int signal_number, signal_handler_t action)
2779 {
2780 struct sigaction new_action, old_action;
2781 sigemptyset (&new_action.sa_mask);
2782 new_action.sa_handler = action;
2783 #ifdef SA_RESTART
2784 /* Emacs mostly works better with restartable system services. If this
2785 * flag exists, we probably want to turn it on here.
2786 */
2787 new_action.sa_flags = SA_RESTART;
2788 #else
2789 new_action.sa_flags = 0;
2790 #endif
2791 sigaction (signal_number, &new_action, &old_action);
2792 return (old_action.sa_handler);
2793 }
2794
2795 #ifndef __GNUC__
2796 /* If we're compiling with GCC, we don't need this function, since it
2797 can be written as a macro. */
2798 sigset_t
2799 sys_sigmask (int sig)
2800 {
2801 sigset_t mask;
2802 sigemptyset (&mask);
2803 sigaddset (&mask, sig);
2804 return mask;
2805 }
2806 #endif
2807
2808 /* I'd like to have these guys return pointers to the mask storage in here,
2809 but there'd be trouble if the code was saving multiple masks. I'll be
2810 safe and pass the structure. It normally won't be more than 2 bytes
2811 anyhow. - DJB */
2812
2813 sigset_t
2814 sys_sigblock (sigset_t new_mask)
2815 {
2816 sigset_t old_mask;
2817 sigprocmask (SIG_BLOCK, &new_mask, &old_mask);
2818 return (old_mask);
2819 }
2820
2821 sigset_t
2822 sys_sigunblock (sigset_t new_mask)
2823 {
2824 sigset_t old_mask;
2825 sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask);
2826 return (old_mask);
2827 }
2828
2829 sigset_t
2830 sys_sigsetmask (sigset_t new_mask)
2831 {
2832 sigset_t old_mask;
2833 sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
2834 return (old_mask);
2835 }
2836
2837 #endif /* POSIX_SIGNALS */
2838 \f
2839 #ifndef HAVE_RANDOM
2840 #ifdef random
2841 #define HAVE_RANDOM
2842 #endif
2843 #endif
2844
2845 /* Figure out how many bits the system's random number generator uses.
2846 `random' and `lrand48' are assumed to return 31 usable bits.
2847 BSD `rand' returns a 31 bit value but the low order bits are unusable;
2848 so we'll shift it and treat it like the 15-bit USG `rand'. */
2849
2850 #ifndef RAND_BITS
2851 # ifdef HAVE_RANDOM
2852 # define RAND_BITS 31
2853 # else /* !HAVE_RANDOM */
2854 # ifdef HAVE_LRAND48
2855 # define RAND_BITS 31
2856 # define random lrand48
2857 # else /* !HAVE_LRAND48 */
2858 # define RAND_BITS 15
2859 # if RAND_MAX == 32767
2860 # define random rand
2861 # else /* RAND_MAX != 32767 */
2862 # if RAND_MAX == 2147483647
2863 # define random() (rand () >> 16)
2864 # else /* RAND_MAX != 2147483647 */
2865 # ifdef USG
2866 # define random rand
2867 # else
2868 # define random() (rand () >> 16)
2869 # endif /* !USG */
2870 # endif /* RAND_MAX != 2147483647 */
2871 # endif /* RAND_MAX != 32767 */
2872 # endif /* !HAVE_LRAND48 */
2873 # endif /* !HAVE_RANDOM */
2874 #endif /* !RAND_BITS */
2875
2876 void
2877 seed_random (arg)
2878 long arg;
2879 {
2880 #ifdef HAVE_RANDOM
2881 srandom ((unsigned int)arg);
2882 #else
2883 # ifdef HAVE_LRAND48
2884 srand48 (arg);
2885 # else
2886 srand ((unsigned int)arg);
2887 # endif
2888 #endif
2889 }
2890
2891 /*
2892 * Build a full Emacs-sized word out of whatever we've got.
2893 * This suffices even for a 64-bit architecture with a 15-bit rand.
2894 */
2895 long
2896 get_random ()
2897 {
2898 long val = random ();
2899 #if VALBITS > RAND_BITS
2900 val = (val << RAND_BITS) ^ random ();
2901 #if VALBITS > 2*RAND_BITS
2902 val = (val << RAND_BITS) ^ random ();
2903 #if VALBITS > 3*RAND_BITS
2904 val = (val << RAND_BITS) ^ random ();
2905 #if VALBITS > 4*RAND_BITS
2906 val = (val << RAND_BITS) ^ random ();
2907 #endif /* need at least 5 */
2908 #endif /* need at least 4 */
2909 #endif /* need at least 3 */
2910 #endif /* need at least 2 */
2911 return val & ((1L << VALBITS) - 1);
2912 }
2913 \f
2914 #ifdef WRONG_NAME_INSQUE
2915
2916 insque (q,p)
2917 caddr_t q,p;
2918 {
2919 _insque (q,p);
2920 }
2921
2922 #endif
2923 \f
2924 #ifdef VMS
2925
2926 #ifdef getenv
2927 /* If any place else asks for the TERM variable,
2928 allow it to be overridden with the EMACS_TERM variable
2929 before attempting to translate the logical name TERM. As a last
2930 resort, ask for VAX C's special idea of the TERM variable. */
2931 #undef getenv
2932 char *
2933 sys_getenv (name)
2934 char *name;
2935 {
2936 register char *val;
2937 static char buf[256];
2938 static struct dsc$descriptor_s equiv
2939 = {sizeof (buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf};
2940 static struct dsc$descriptor_s d_name
2941 = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
2942 short eqlen;
2943
2944 if (!strcmp (name, "TERM"))
2945 {
2946 val = (char *) getenv ("EMACS_TERM");
2947 if (val)
2948 return val;
2949 }
2950
2951 d_name.dsc$w_length = strlen (name);
2952 d_name.dsc$a_pointer = name;
2953 if (LIB$SYS_TRNLOG (&d_name, &eqlen, &equiv) == 1)
2954 {
2955 char *str = (char *) xmalloc (eqlen + 1);
2956 bcopy (buf, str, eqlen);
2957 str[eqlen] = '\0';
2958 /* This is a storage leak, but a pain to fix. With luck,
2959 no one will ever notice. */
2960 return str;
2961 }
2962 return (char *) getenv (name);
2963 }
2964 #endif /* getenv */
2965
2966 #ifdef abort
2967 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
2968 to force a call on the debugger from within the image. */
2969 #undef abort
2970 sys_abort ()
2971 {
2972 reset_sys_modes ();
2973 LIB$SIGNAL (SS$_DEBUG);
2974 }
2975 #endif /* abort */
2976 #endif /* VMS */
2977 \f
2978 #ifdef VMS
2979 #ifdef LINK_CRTL_SHARE
2980 #ifdef SHARABLE_LIB_BUG
2981 /* Variables declared noshare and initialized in sharable libraries
2982 cannot be shared. The VMS linker incorrectly forces you to use a private
2983 version which is uninitialized... If not for this "feature", we
2984 could use the C library definition of sys_nerr and sys_errlist. */
2985 int sys_nerr = 35;
2986 char *sys_errlist[] =
2987 {
2988 "error 0",
2989 "not owner",
2990 "no such file or directory",
2991 "no such process",
2992 "interrupted system call",
2993 "i/o error",
2994 "no such device or address",
2995 "argument list too long",
2996 "exec format error",
2997 "bad file number",
2998 "no child process",
2999 "no more processes",
3000 "not enough memory",
3001 "permission denied",
3002 "bad address",
3003 "block device required",
3004 "mount devices busy",
3005 "file exists",
3006 "cross-device link",
3007 "no such device",
3008 "not a directory",
3009 "is a directory",
3010 "invalid argument",
3011 "file table overflow",
3012 "too many open files",
3013 "not a typewriter",
3014 "text file busy",
3015 "file too big",
3016 "no space left on device",
3017 "illegal seek",
3018 "read-only file system",
3019 "too many links",
3020 "broken pipe",
3021 "math argument",
3022 "result too large",
3023 "I/O stream empty",
3024 "vax/vms specific error code nontranslatable error"
3025 };
3026 #endif /* SHARABLE_LIB_BUG */
3027 #endif /* LINK_CRTL_SHARE */
3028 #endif /* VMS */
3029
3030 #ifndef HAVE_STRERROR
3031 #ifndef WINDOWSNT
3032 char *
3033 strerror (errnum)
3034 int errnum;
3035 {
3036 extern char *sys_errlist[];
3037 extern int sys_nerr;
3038
3039 if (errnum >= 0 && errnum < sys_nerr)
3040 return sys_errlist[errnum];
3041 return (char *) "Unknown error";
3042 }
3043 #endif /* not WINDOWSNT */
3044 #endif /* ! HAVE_STRERROR */
3045 \f
3046 #ifdef INTERRUPTIBLE_OPEN
3047
3048 int
3049 /* VARARGS 2 */
3050 sys_open (path, oflag, mode)
3051 char *path;
3052 int oflag, mode;
3053 {
3054 register int rtnval;
3055
3056 while ((rtnval = open (path, oflag, mode)) == -1
3057 && (errno == EINTR));
3058 return (rtnval);
3059 }
3060
3061 #endif /* INTERRUPTIBLE_OPEN */
3062
3063 #ifdef INTERRUPTIBLE_CLOSE
3064
3065 int
3066 sys_close (fd)
3067 int fd;
3068 {
3069 int did_retry = 0;
3070 register int rtnval;
3071
3072 while ((rtnval = close (fd)) == -1
3073 && (errno == EINTR))
3074 did_retry = 1;
3075
3076 /* If close is interrupted SunOS 4.1 may or may not have closed the
3077 file descriptor. If it did the second close will fail with
3078 errno = EBADF. That means we have succeeded. */
3079 if (rtnval == -1 && did_retry && errno == EBADF)
3080 return 0;
3081
3082 return rtnval;
3083 }
3084
3085 #endif /* INTERRUPTIBLE_CLOSE */
3086
3087 #ifdef INTERRUPTIBLE_IO
3088
3089 int
3090 sys_read (fildes, buf, nbyte)
3091 int fildes;
3092 char *buf;
3093 unsigned int nbyte;
3094 {
3095 register int rtnval;
3096
3097 while ((rtnval = read (fildes, buf, nbyte)) == -1
3098 && (errno == EINTR));
3099 return (rtnval);
3100 }
3101
3102 int
3103 sys_write (fildes, buf, nbyte)
3104 int fildes;
3105 char *buf;
3106 unsigned int nbyte;
3107 {
3108 register int rtnval, bytes_written;
3109
3110 bytes_written = 0;
3111
3112 while (nbyte > 0)
3113 {
3114 rtnval = write (fildes, buf, nbyte);
3115
3116 if (rtnval == -1)
3117 {
3118 if (errno == EINTR)
3119 continue;
3120 else
3121 return (bytes_written ? bytes_written : -1);
3122 }
3123
3124 buf += rtnval;
3125 nbyte -= rtnval;
3126 bytes_written += rtnval;
3127 }
3128 return (bytes_written);
3129 }
3130
3131 #endif /* INTERRUPTIBLE_IO */
3132 \f
3133 #ifndef HAVE_VFORK
3134 #ifndef WINDOWSNT
3135 /*
3136 * Substitute fork for vfork on USG flavors.
3137 */
3138
3139 VFORK_RETURN_TYPE
3140 vfork ()
3141 {
3142 return (fork ());
3143 }
3144 #endif /* not WINDOWSNT */
3145 #endif /* not HAVE_VFORK */
3146 \f
3147 #ifdef USG
3148 /*
3149 * All of the following are for USG.
3150 *
3151 * On USG systems the system calls are INTERRUPTIBLE by signals
3152 * that the user program has elected to catch. Thus the system call
3153 * must be retried in these cases. To handle this without massive
3154 * changes in the source code, we remap the standard system call names
3155 * to names for our own functions in sysdep.c that do the system call
3156 * with retries. Actually, for portability reasons, it is good
3157 * programming practice, as this example shows, to limit all actual
3158 * system calls to a single occurrence in the source. Sure, this
3159 * adds an extra level of function call overhead but it is almost
3160 * always negligible. Fred Fish, Unisoft Systems Inc.
3161 */
3162
3163 #ifndef HAVE_SYS_SIGLIST
3164 char *sys_siglist[NSIG + 1] =
3165 {
3166 #ifdef AIX
3167 /* AIX has changed the signals a bit */
3168 "bogus signal", /* 0 */
3169 "hangup", /* 1 SIGHUP */
3170 "interrupt", /* 2 SIGINT */
3171 "quit", /* 3 SIGQUIT */
3172 "illegal instruction", /* 4 SIGILL */
3173 "trace trap", /* 5 SIGTRAP */
3174 "IOT instruction", /* 6 SIGIOT */
3175 "crash likely", /* 7 SIGDANGER */
3176 "floating point exception", /* 8 SIGFPE */
3177 "kill", /* 9 SIGKILL */
3178 "bus error", /* 10 SIGBUS */
3179 "segmentation violation", /* 11 SIGSEGV */
3180 "bad argument to system call", /* 12 SIGSYS */
3181 "write on a pipe with no one to read it", /* 13 SIGPIPE */
3182 "alarm clock", /* 14 SIGALRM */
3183 "software termination signum", /* 15 SIGTERM */
3184 "user defined signal 1", /* 16 SIGUSR1 */
3185 "user defined signal 2", /* 17 SIGUSR2 */
3186 "death of a child", /* 18 SIGCLD */
3187 "power-fail restart", /* 19 SIGPWR */
3188 "bogus signal", /* 20 */
3189 "bogus signal", /* 21 */
3190 "bogus signal", /* 22 */
3191 "bogus signal", /* 23 */
3192 "bogus signal", /* 24 */
3193 "LAN I/O interrupt", /* 25 SIGAIO */
3194 "PTY I/O interrupt", /* 26 SIGPTY */
3195 "I/O intervention required", /* 27 SIGIOINT */
3196 #ifdef AIXHFT
3197 "HFT grant", /* 28 SIGGRANT */
3198 "HFT retract", /* 29 SIGRETRACT */
3199 "HFT sound done", /* 30 SIGSOUND */
3200 "HFT input ready", /* 31 SIGMSG */
3201 #endif
3202 #else /* not AIX */
3203 "bogus signal", /* 0 */
3204 "hangup", /* 1 SIGHUP */
3205 "interrupt", /* 2 SIGINT */
3206 "quit", /* 3 SIGQUIT */
3207 "illegal instruction", /* 4 SIGILL */
3208 "trace trap", /* 5 SIGTRAP */
3209 "IOT instruction", /* 6 SIGIOT */
3210 "EMT instruction", /* 7 SIGEMT */
3211 "floating point exception", /* 8 SIGFPE */
3212 "kill", /* 9 SIGKILL */
3213 "bus error", /* 10 SIGBUS */
3214 "segmentation violation", /* 11 SIGSEGV */
3215 "bad argument to system call", /* 12 SIGSYS */
3216 "write on a pipe with no one to read it", /* 13 SIGPIPE */
3217 "alarm clock", /* 14 SIGALRM */
3218 "software termination signum", /* 15 SIGTERM */
3219 "user defined signal 1", /* 16 SIGUSR1 */
3220 "user defined signal 2", /* 17 SIGUSR2 */
3221 "death of a child", /* 18 SIGCLD */
3222 "power-fail restart", /* 19 SIGPWR */
3223 #ifdef sun
3224 "window size change", /* 20 SIGWINCH */
3225 "urgent socket condition", /* 21 SIGURG */
3226 "pollable event occurred", /* 22 SIGPOLL */
3227 "stop (cannot be caught or ignored)", /* 23 SIGSTOP */
3228 "user stop requested from tty", /* 24 SIGTSTP */
3229 "stopped process has been continued", /* 25 SIGCONT */
3230 "background tty read attempted", /* 26 SIGTTIN */
3231 "background tty write attempted", /* 27 SIGTTOU */
3232 "virtual timer expired", /* 28 SIGVTALRM */
3233 "profiling timer expired", /* 29 SIGPROF */
3234 "exceeded cpu limit", /* 30 SIGXCPU */
3235 "exceeded file size limit", /* 31 SIGXFSZ */
3236 "process's lwps are blocked", /* 32 SIGWAITING */
3237 "special signal used by thread library", /* 33 SIGLWP */
3238 #ifdef SIGFREEZE
3239 "Special Signal Used By CPR", /* 34 SIGFREEZE */
3240 #endif
3241 #ifdef SIGTHAW
3242 "Special Signal Used By CPR", /* 35 SIGTHAW */
3243 #endif
3244 #endif /* sun */
3245 #endif /* not AIX */
3246 0
3247 };
3248 #endif /* HAVE_SYS_SIGLIST */
3249
3250 /*
3251 * Warning, this function may not duplicate 4.2 action properly
3252 * under error conditions.
3253 */
3254
3255 #ifndef MAXPATHLEN
3256 /* In 4.1, param.h fails to define this. */
3257 #define MAXPATHLEN 1024
3258 #endif
3259
3260 #ifndef HAVE_GETWD
3261
3262 char *
3263 getwd (pathname)
3264 char *pathname;
3265 {
3266 char *npath, *spath;
3267 extern char *getcwd ();
3268
3269 BLOCK_INPUT; /* getcwd uses malloc */
3270 spath = npath = getcwd ((char *) 0, MAXPATHLEN);
3271 if (spath == 0)
3272 return spath;
3273 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3274 up to first slash. Should be harmless on other systems. */
3275 while (*npath && *npath != '/')
3276 npath++;
3277 strcpy (pathname, npath);
3278 free (spath); /* getcwd uses malloc */
3279 UNBLOCK_INPUT;
3280 return pathname;
3281 }
3282
3283 #endif /* HAVE_GETWD */
3284
3285 /*
3286 * Emulate rename using unlink/link. Note that this is
3287 * only partially correct. Also, doesn't enforce restriction
3288 * that files be of same type (regular->regular, dir->dir, etc).
3289 */
3290
3291 #ifndef HAVE_RENAME
3292
3293 rename (from, to)
3294 const char *from;
3295 const char *to;
3296 {
3297 if (access (from, 0) == 0)
3298 {
3299 unlink (to);
3300 if (link (from, to) == 0)
3301 if (unlink (from) == 0)
3302 return (0);
3303 }
3304 return (-1);
3305 }
3306
3307 #endif
3308
3309
3310 #ifdef HPUX
3311 #ifndef HAVE_PERROR
3312
3313 /* HPUX curses library references perror, but as far as we know
3314 it won't be called. Anyway this definition will do for now. */
3315
3316 perror ()
3317 {
3318 }
3319
3320 #endif /* not HAVE_PERROR */
3321 #endif /* HPUX */
3322
3323 #ifndef HAVE_DUP2
3324
3325 /*
3326 * Emulate BSD dup2. First close newd if it already exists.
3327 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3328 * until we are, then close the unsuccessful ones.
3329 */
3330
3331 dup2 (oldd, newd)
3332 int oldd;
3333 int newd;
3334 {
3335 register int fd, ret;
3336
3337 sys_close (newd);
3338
3339 #ifdef F_DUPFD
3340 fd = fcntl (oldd, F_DUPFD, newd);
3341 if (fd != newd)
3342 error ("can't dup2 (%i,%i) : %s", oldd, newd, strerror (errno));
3343 #else
3344 fd = dup (old);
3345 if (fd == -1)
3346 return -1;
3347 if (fd == new)
3348 return new;
3349 ret = dup2 (old,new);
3350 sys_close (fd);
3351 return ret;
3352 #endif
3353 }
3354
3355 #endif /* not HAVE_DUP2 */
3356
3357 /*
3358 * Gettimeofday. Simulate as much as possible. Only accurate
3359 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3360 * Only needed when subprocesses are defined.
3361 */
3362
3363 #ifdef subprocesses
3364 #ifndef VMS
3365 #ifndef HAVE_GETTIMEOFDAY
3366 #ifdef HAVE_TIMEVAL
3367
3368 /* ARGSUSED */
3369 int
3370 gettimeofday (tp, tzp)
3371 struct timeval *tp;
3372 struct timezone *tzp;
3373 {
3374 extern long time ();
3375
3376 tp->tv_sec = time ((long *)0);
3377 tp->tv_usec = 0;
3378 if (tzp != 0)
3379 tzp->tz_minuteswest = -1;
3380 return 0;
3381 }
3382
3383 #endif
3384 #endif
3385 #endif
3386 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3387
3388 /*
3389 * This function will go away as soon as all the stubs fixed. (fnf)
3390 */
3391
3392 void
3393 croak (badfunc)
3394 char *badfunc;
3395 {
3396 printf ("%s not yet implemented\r\n", badfunc);
3397 reset_sys_modes ();
3398 exit (1);
3399 }
3400
3401 #endif /* USG */
3402 \f
3403 #ifdef DGUX
3404
3405 char *sys_siglist[NSIG + 1] =
3406 {
3407 "null signal", /* 0 SIGNULL */
3408 "hangup", /* 1 SIGHUP */
3409 "interrupt", /* 2 SIGINT */
3410 "quit", /* 3 SIGQUIT */
3411 "illegal instruction", /* 4 SIGILL */
3412 "trace trap", /* 5 SIGTRAP */
3413 "abort termination", /* 6 SIGABRT */
3414 "SIGEMT", /* 7 SIGEMT */
3415 "floating point exception", /* 8 SIGFPE */
3416 "kill", /* 9 SIGKILL */
3417 "bus error", /* 10 SIGBUS */
3418 "segmentation violation", /* 11 SIGSEGV */
3419 "bad argument to system call", /* 12 SIGSYS */
3420 "write on a pipe with no reader", /* 13 SIGPIPE */
3421 "alarm clock", /* 14 SIGALRM */
3422 "software termination signal", /* 15 SIGTERM */
3423 "user defined signal 1", /* 16 SIGUSR1 */
3424 "user defined signal 2", /* 17 SIGUSR2 */
3425 "child stopped or terminated", /* 18 SIGCLD */
3426 "power-fail restart", /* 19 SIGPWR */
3427 "window size changed", /* 20 SIGWINCH */
3428 "undefined", /* 21 */
3429 "pollable event occurred", /* 22 SIGPOLL */
3430 "sendable stop signal not from tty", /* 23 SIGSTOP */
3431 "stop signal from tty", /* 24 SIGSTP */
3432 "continue a stopped process", /* 25 SIGCONT */
3433 "attempted background tty read", /* 26 SIGTTIN */
3434 "attempted background tty write", /* 27 SIGTTOU */
3435 "undefined", /* 28 */
3436 "undefined", /* 29 */
3437 "undefined", /* 30 */
3438 "undefined", /* 31 */
3439 "undefined", /* 32 */
3440 "socket (TCP/IP) urgent data arrival", /* 33 SIGURG */
3441 "I/O is possible", /* 34 SIGIO */
3442 "exceeded cpu time limit", /* 35 SIGXCPU */
3443 "exceeded file size limit", /* 36 SIGXFSZ */
3444 "virtual time alarm", /* 37 SIGVTALRM */
3445 "profiling time alarm", /* 38 SIGPROF */
3446 "undefined", /* 39 */
3447 "file record locks revoked", /* 40 SIGLOST */
3448 "undefined", /* 41 */
3449 "undefined", /* 42 */
3450 "undefined", /* 43 */
3451 "undefined", /* 44 */
3452 "undefined", /* 45 */
3453 "undefined", /* 46 */
3454 "undefined", /* 47 */
3455 "undefined", /* 48 */
3456 "undefined", /* 49 */
3457 "undefined", /* 50 */
3458 "undefined", /* 51 */
3459 "undefined", /* 52 */
3460 "undefined", /* 53 */
3461 "undefined", /* 54 */
3462 "undefined", /* 55 */
3463 "undefined", /* 56 */
3464 "undefined", /* 57 */
3465 "undefined", /* 58 */
3466 "undefined", /* 59 */
3467 "undefined", /* 60 */
3468 "undefined", /* 61 */
3469 "undefined", /* 62 */
3470 "undefined", /* 63 */
3471 "notification message in mess. queue", /* 64 SIGDGNOTIFY */
3472 0
3473 };
3474
3475 #endif /* DGUX */
3476 \f
3477 /* Directory routines for systems that don't have them. */
3478
3479 #ifdef SYSV_SYSTEM_DIR
3480
3481 #include <dirent.h>
3482
3483 #if defined(BROKEN_CLOSEDIR) || !defined(HAVE_CLOSEDIR)
3484
3485 int
3486 closedir (dirp)
3487 register DIR *dirp; /* stream from opendir */
3488 {
3489 int rtnval;
3490
3491 rtnval = sys_close (dirp->dd_fd);
3492
3493 /* Some systems (like Solaris) allocate the buffer and the DIR all
3494 in one block. Why in the world are we freeing this ourselves
3495 anyway? */
3496 #if ! (defined (sun) && defined (USG5_4))
3497 xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
3498 #endif
3499 xfree ((char *) dirp);
3500
3501 return rtnval;
3502 }
3503 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3504 #endif /* SYSV_SYSTEM_DIR */
3505
3506 #ifdef NONSYSTEM_DIR_LIBRARY
3507
3508 DIR *
3509 opendir (filename)
3510 char *filename; /* name of directory */
3511 {
3512 register DIR *dirp; /* -> malloc'ed storage */
3513 register int fd; /* file descriptor for read */
3514 struct stat sbuf; /* result of fstat */
3515
3516 fd = sys_open (filename, 0);
3517 if (fd < 0)
3518 return 0;
3519
3520 BLOCK_INPUT;
3521 if (fstat (fd, &sbuf) < 0
3522 || (sbuf.st_mode & S_IFMT) != S_IFDIR
3523 || (dirp = (DIR *) malloc (sizeof (DIR))) == 0)
3524 {
3525 sys_close (fd);
3526 UNBLOCK_INPUT;
3527 return 0; /* bad luck today */
3528 }
3529 UNBLOCK_INPUT;
3530
3531 dirp->dd_fd = fd;
3532 dirp->dd_loc = dirp->dd_size = 0; /* refill needed */
3533
3534 return dirp;
3535 }
3536
3537 void
3538 closedir (dirp)
3539 register DIR *dirp; /* stream from opendir */
3540 {
3541 sys_close (dirp->dd_fd);
3542 xfree ((char *) dirp);
3543 }
3544
3545
3546 #ifndef VMS
3547 #define DIRSIZ 14
3548 struct olddir
3549 {
3550 ino_t od_ino; /* inode */
3551 char od_name[DIRSIZ]; /* filename */
3552 };
3553 #endif /* not VMS */
3554
3555 struct direct dir_static; /* simulated directory contents */
3556
3557 /* ARGUSED */
3558 struct direct *
3559 readdir (dirp)
3560 register DIR *dirp; /* stream from opendir */
3561 {
3562 #ifndef VMS
3563 register struct olddir *dp; /* -> directory data */
3564 #else /* VMS */
3565 register struct dir$_name *dp; /* -> directory data */
3566 register struct dir$_version *dv; /* -> version data */
3567 #endif /* VMS */
3568
3569 for (; ;)
3570 {
3571 if (dirp->dd_loc >= dirp->dd_size)
3572 dirp->dd_loc = dirp->dd_size = 0;
3573
3574 if (dirp->dd_size == 0 /* refill buffer */
3575 && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3576 return 0;
3577
3578 #ifndef VMS
3579 dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
3580 dirp->dd_loc += sizeof (struct olddir);
3581
3582 if (dp->od_ino != 0) /* not deleted entry */
3583 {
3584 dir_static.d_ino = dp->od_ino;
3585 strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
3586 dir_static.d_name[DIRSIZ] = '\0';
3587 dir_static.d_namlen = strlen (dir_static.d_name);
3588 dir_static.d_reclen = sizeof (struct direct)
3589 - MAXNAMLEN + 3
3590 + dir_static.d_namlen - dir_static.d_namlen % 4;
3591 return &dir_static; /* -> simulated structure */
3592 }
3593 #else /* VMS */
3594 dp = (struct dir$_name *) dirp->dd_buf;
3595 if (dirp->dd_loc == 0)
3596 dirp->dd_loc = (dp->dir$b_namecount&1) ? dp->dir$b_namecount + 1
3597 : dp->dir$b_namecount;
3598 dv = (struct dir$_version *)&dp->dir$t_name[dirp->dd_loc];
3599 dir_static.d_ino = dv->dir$w_fid_num;
3600 dir_static.d_namlen = dp->dir$b_namecount;
3601 dir_static.d_reclen = sizeof (struct direct)
3602 - MAXNAMLEN + 3
3603 + dir_static.d_namlen - dir_static.d_namlen % 4;
3604 strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
3605 dir_static.d_name[dir_static.d_namlen] = '\0';
3606 dirp->dd_loc = dirp->dd_size; /* only one record at a time */
3607 return &dir_static;
3608 #endif /* VMS */
3609 }
3610 }
3611
3612 #ifdef VMS
3613 /* readdirver is just like readdir except it returns all versions of a file
3614 as separate entries. */
3615
3616 /* ARGUSED */
3617 struct direct *
3618 readdirver (dirp)
3619 register DIR *dirp; /* stream from opendir */
3620 {
3621 register struct dir$_name *dp; /* -> directory data */
3622 register struct dir$_version *dv; /* -> version data */
3623
3624 if (dirp->dd_loc >= dirp->dd_size - sizeof (struct dir$_name))
3625 dirp->dd_loc = dirp->dd_size = 0;
3626
3627 if (dirp->dd_size == 0 /* refill buffer */
3628 && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3629 return 0;
3630
3631 dp = (struct dir$_name *) dirp->dd_buf;
3632 if (dirp->dd_loc == 0)
3633 dirp->dd_loc = (dp->dir$b_namecount & 1) ? dp->dir$b_namecount + 1
3634 : dp->dir$b_namecount;
3635 dv = (struct dir$_version *) &dp->dir$t_name[dirp->dd_loc];
3636 strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
3637 sprintf (&dir_static.d_name[dp->dir$b_namecount], ";%d", dv->dir$w_version);
3638 dir_static.d_namlen = strlen (dir_static.d_name);
3639 dir_static.d_ino = dv->dir$w_fid_num;
3640 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3
3641 + dir_static.d_namlen - dir_static.d_namlen % 4;
3642 dirp->dd_loc = ((char *) (++dv) - dp->dir$t_name);
3643 return &dir_static;
3644 }
3645
3646 #endif /* VMS */
3647
3648 #endif /* NONSYSTEM_DIR_LIBRARY */
3649
3650 \f
3651 int
3652 set_file_times (filename, atime, mtime)
3653 char *filename;
3654 EMACS_TIME atime, mtime;
3655 {
3656 #ifdef HAVE_UTIMES
3657 struct timeval tv[2];
3658 tv[0] = atime;
3659 tv[1] = mtime;
3660 return utimes (filename, tv);
3661 #else /* not HAVE_UTIMES */
3662 struct utimbuf utb;
3663 utb.actime = EMACS_SECS (atime);
3664 utb.modtime = EMACS_SECS (mtime);
3665 return utime (filename, &utb);
3666 #endif /* not HAVE_UTIMES */
3667 }
3668 \f
3669 /* mkdir and rmdir functions, for systems which don't have them. */
3670
3671 #ifndef HAVE_MKDIR
3672 /*
3673 * Written by Robert Rother, Mariah Corporation, August 1985.
3674 *
3675 * If you want it, it's yours. All I ask in return is that if you
3676 * figure out how to do this in a Bourne Shell script you send me
3677 * a copy.
3678 * sdcsvax!rmr or rmr@uscd
3679 *
3680 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3681 * subroutine. 11Mar86; hoptoad!gnu
3682 *
3683 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3684 * subroutine didn't return EEXIST. It does now.
3685 */
3686
3687 /*
3688 * Make a directory.
3689 */
3690 #ifdef MKDIR_PROTOTYPE
3691 MKDIR_PROTOTYPE
3692 #else
3693 int
3694 mkdir (dpath, dmode)
3695 char *dpath;
3696 int dmode;
3697 #endif
3698 {
3699 int cpid, status, fd;
3700 struct stat statbuf;
3701
3702 if (stat (dpath, &statbuf) == 0)
3703 {
3704 errno = EEXIST; /* Stat worked, so it already exists */
3705 return -1;
3706 }
3707
3708 /* If stat fails for a reason other than non-existence, return error */
3709 if (errno != ENOENT)
3710 return -1;
3711
3712 synch_process_alive = 1;
3713 switch (cpid = fork ())
3714 {
3715
3716 case -1: /* Error in fork */
3717 return (-1); /* Errno is set already */
3718
3719 case 0: /* Child process */
3720 /*
3721 * Cheap hack to set mode of new directory. Since this
3722 * child process is going away anyway, we zap its umask.
3723 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3724 * directory. Does anybody care?
3725 */
3726 status = umask (0); /* Get current umask */
3727 status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
3728 fd = sys_open("/dev/null", 2);
3729 if (fd >= 0)
3730 {
3731 dup2 (fd, 0);
3732 dup2 (fd, 1);
3733 dup2 (fd, 2);
3734 }
3735 execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
3736 _exit (-1); /* Can't exec /bin/mkdir */
3737
3738 default: /* Parent process */
3739 wait_for_termination (cpid);
3740 }
3741
3742 if (synch_process_death != 0 || synch_process_retcode != 0)
3743 {
3744 errno = EIO; /* We don't know why, but */
3745 return -1; /* /bin/mkdir failed */
3746 }
3747
3748 return 0;
3749 }
3750 #endif /* not HAVE_MKDIR */
3751
3752 #ifndef HAVE_RMDIR
3753 int
3754 rmdir (dpath)
3755 char *dpath;
3756 {
3757 int cpid, status, fd;
3758 struct stat statbuf;
3759
3760 if (stat (dpath, &statbuf) != 0)
3761 {
3762 /* Stat just set errno. We don't have to */
3763 return -1;
3764 }
3765
3766 synch_process_alive = 1;
3767 switch (cpid = fork ())
3768 {
3769
3770 case -1: /* Error in fork */
3771 return (-1); /* Errno is set already */
3772
3773 case 0: /* Child process */
3774 fd = sys_open("/dev/null", 2);
3775 if (fd >= 0)
3776 {
3777 dup2 (fd, 0);
3778 dup2 (fd, 1);
3779 dup2 (fd, 2);
3780 }
3781 execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
3782 _exit (-1); /* Can't exec /bin/rmdir */
3783
3784 default: /* Parent process */
3785 wait_for_termination (cpid);
3786 }
3787
3788 if (synch_process_death != 0 || synch_process_retcode != 0)
3789 {
3790 errno = EIO; /* We don't know why, but */
3791 return -1; /* /bin/rmdir failed */
3792 }
3793
3794 return 0;
3795 }
3796 #endif /* !HAVE_RMDIR */
3797
3798
3799 \f
3800 /* Functions for VMS */
3801 #ifdef VMS
3802 #include "vms-pwd.h"
3803 #include <acldef.h>
3804 #include <chpdef.h>
3805 #include <jpidef.h>
3806
3807 /* Return as a string the VMS error string pertaining to STATUS.
3808 Reuses the same static buffer each time it is called. */
3809
3810 char *
3811 vmserrstr (status)
3812 int status; /* VMS status code */
3813 {
3814 int bufadr[2];
3815 short len;
3816 static char buf[257];
3817
3818 bufadr[0] = sizeof buf - 1;
3819 bufadr[1] = (int) buf;
3820 if (! (SYS$GETMSG (status, &len, bufadr, 0x1, 0) & 1))
3821 return "untranslatable VMS error status";
3822 buf[len] = '\0';
3823 return buf;
3824 }
3825
3826 #ifdef access
3827 #undef access
3828
3829 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3830 * not work correctly. (It also doesn't work well in version 2.3.)
3831 */
3832
3833 #ifdef VMS4_4
3834
3835 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3836 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3837
3838 typedef union {
3839 struct {
3840 unsigned short s_buflen;
3841 unsigned short s_code;
3842 char *s_bufadr;
3843 unsigned short *s_retlenadr;
3844 } s;
3845 int end;
3846 } item;
3847 #define buflen s.s_buflen
3848 #define code s.s_code
3849 #define bufadr s.s_bufadr
3850 #define retlenadr s.s_retlenadr
3851
3852 #define R_OK 4 /* test for read permission */
3853 #define W_OK 2 /* test for write permission */
3854 #define X_OK 1 /* test for execute (search) permission */
3855 #define F_OK 0 /* test for presence of file */
3856
3857 int
3858 sys_access (path, mode)
3859 char *path;
3860 int mode;
3861 {
3862 static char *user = NULL;
3863 char dir_fn[512];
3864
3865 /* translate possible directory spec into .DIR file name, so brain-dead
3866 * access can treat the directory like a file. */
3867 if (directory_file_name (path, dir_fn))
3868 path = dir_fn;
3869
3870 if (mode == F_OK)
3871 return access (path, mode);
3872 if (user == NULL && (user = (char *) getenv ("USER")) == NULL)
3873 return -1;
3874 {
3875 int stat;
3876 int flags;
3877 int acces;
3878 unsigned short int dummy;
3879 item itemlst[3];
3880 static int constant = ACL$C_FILE;
3881 DESCRIPTOR (path_desc, path);
3882 DESCRIPTOR (user_desc, user);
3883
3884 flags = 0;
3885 acces = 0;
3886 if ((mode & X_OK) && ((stat = access (path, mode)) < 0 || mode == X_OK))
3887 return stat;
3888 if (mode & R_OK)
3889 acces |= CHP$M_READ;
3890 if (mode & W_OK)
3891 acces |= CHP$M_WRITE;
3892 itemlst[0].buflen = sizeof (int);
3893 itemlst[0].code = CHP$_FLAGS;
3894 itemlst[0].bufadr = (char *) &flags;
3895 itemlst[0].retlenadr = &dummy;
3896 itemlst[1].buflen = sizeof (int);
3897 itemlst[1].code = CHP$_ACCESS;
3898 itemlst[1].bufadr = (char *) &acces;
3899 itemlst[1].retlenadr = &dummy;
3900 itemlst[2].end = CHP$_END;
3901 stat = SYS$CHECK_ACCESS (&constant, &path_desc, &user_desc, itemlst);
3902 return stat == SS$_NORMAL ? 0 : -1;
3903 }
3904 }
3905
3906 #else /* not VMS4_4 */
3907
3908 #include <prvdef.h>
3909 #define ACE$M_WRITE 2
3910 #define ACE$C_KEYID 1
3911
3912 static unsigned short memid, grpid;
3913 static unsigned int uic;
3914
3915 /* Called from init_sys_modes, so it happens not very often
3916 but at least each time Emacs is loaded. */
3917 void
3918 sys_access_reinit ()
3919 {
3920 uic = 0;
3921 }
3922
3923 int
3924 sys_access (filename, type)
3925 char * filename;
3926 int type;
3927 {
3928 struct FAB fab;
3929 struct XABPRO xab;
3930 int status, size, i, typecode, acl_controlled;
3931 unsigned int *aclptr, *aclend, aclbuf[60];
3932 union prvdef prvmask;
3933
3934 /* Get UIC and GRP values for protection checking. */
3935 if (uic == 0)
3936 {
3937 status = LIB$GETJPI (&JPI$_UIC, 0, 0, &uic, 0, 0);
3938 if (! (status & 1))
3939 return -1;
3940 memid = uic & 0xFFFF;
3941 grpid = uic >> 16;
3942 }
3943
3944 if (type != 2) /* not checking write access */
3945 return access (filename, type);
3946
3947 /* Check write protection. */
3948
3949 #define CHECKPRIV(bit) (prvmask.bit)
3950 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
3951
3952 /* Find privilege bits */
3953 status = SYS$SETPRV (0, 0, 0, prvmask);
3954 if (! (status & 1))
3955 error ("Unable to find privileges: %s", vmserrstr (status));
3956 if (CHECKPRIV (PRV$V_BYPASS))
3957 return 0; /* BYPASS enabled */
3958 fab = cc$rms_fab;
3959 fab.fab$b_fac = FAB$M_GET;
3960 fab.fab$l_fna = filename;
3961 fab.fab$b_fns = strlen (filename);
3962 fab.fab$l_xab = &xab;
3963 xab = cc$rms_xabpro;
3964 xab.xab$l_aclbuf = aclbuf;
3965 xab.xab$w_aclsiz = sizeof (aclbuf);
3966 status = SYS$OPEN (&fab, 0, 0);
3967 if (! (status & 1))
3968 return -1;
3969 SYS$CLOSE (&fab, 0, 0);
3970 /* Check system access */
3971 if (CHECKPRIV (PRV$V_SYSPRV) && WRITABLE (XAB$V_SYS))
3972 return 0;
3973 /* Check ACL entries, if any */
3974 acl_controlled = 0;
3975 if (xab.xab$w_acllen > 0)
3976 {
3977 aclptr = aclbuf;
3978 aclend = &aclbuf[xab.xab$w_acllen / 4];
3979 while (*aclptr && aclptr < aclend)
3980 {
3981 size = (*aclptr & 0xff) / 4;
3982 typecode = (*aclptr >> 8) & 0xff;
3983 if (typecode == ACE$C_KEYID)
3984 for (i = size - 1; i > 1; i--)
3985 if (aclptr[i] == uic)
3986 {
3987 acl_controlled = 1;
3988 if (aclptr[1] & ACE$M_WRITE)
3989 return 0; /* Write access through ACL */
3990 }
3991 aclptr = &aclptr[size];
3992 }
3993 if (acl_controlled) /* ACL specified, prohibits write access */
3994 return -1;
3995 }
3996 /* No ACL entries specified, check normal protection */
3997 if (WRITABLE (XAB$V_WLD)) /* World writable */
3998 return 0;
3999 if (WRITABLE (XAB$V_GRP) &&
4000 (unsigned short) (xab.xab$l_uic >> 16) == grpid)
4001 return 0; /* Group writable */
4002 if (WRITABLE (XAB$V_OWN) &&
4003 (xab.xab$l_uic & 0xFFFF) == memid)
4004 return 0; /* Owner writable */
4005
4006 return -1; /* Not writable */
4007 }
4008 #endif /* not VMS4_4 */
4009 #endif /* access */
4010
4011 static char vtbuf[NAM$C_MAXRSS+1];
4012
4013 /* translate a vms file spec to a unix path */
4014 char *
4015 sys_translate_vms (vfile)
4016 char * vfile;
4017 {
4018 char * p;
4019 char * targ;
4020
4021 if (!vfile)
4022 return 0;
4023
4024 targ = vtbuf;
4025
4026 /* leading device or logical name is a root directory */
4027 if (p = strchr (vfile, ':'))
4028 {
4029 *targ++ = '/';
4030 while (vfile < p)
4031 *targ++ = *vfile++;
4032 vfile++;
4033 *targ++ = '/';
4034 }
4035 p = vfile;
4036 if (*p == '[' || *p == '<')
4037 {
4038 while (*++vfile != *p + 2)
4039 switch (*vfile)
4040 {
4041 case '.':
4042 if (vfile[-1] == *p)
4043 *targ++ = '.';
4044 *targ++ = '/';
4045 break;
4046
4047 case '-':
4048 *targ++ = '.';
4049 *targ++ = '.';
4050 break;
4051
4052 default:
4053 *targ++ = *vfile;
4054 break;
4055 }
4056 vfile++;
4057 *targ++ = '/';
4058 }
4059 while (*vfile)
4060 *targ++ = *vfile++;
4061
4062 return vtbuf;
4063 }
4064
4065 static char utbuf[NAM$C_MAXRSS+1];
4066
4067 /* translate a unix path to a VMS file spec */
4068 char *
4069 sys_translate_unix (ufile)
4070 char * ufile;
4071 {
4072 int slash_seen = 0;
4073 char *p;
4074 char * targ;
4075
4076 if (!ufile)
4077 return 0;
4078
4079 targ = utbuf;
4080
4081 if (*ufile == '/')
4082 {
4083 ufile++;
4084 }
4085
4086 while (*ufile)
4087 {
4088 switch (*ufile)
4089 {
4090 case '/':
4091 if (slash_seen)
4092 if (index (&ufile[1], '/'))
4093 *targ++ = '.';
4094 else
4095 *targ++ = ']';
4096 else
4097 {
4098 *targ++ = ':';
4099 if (index (&ufile[1], '/'))
4100 *targ++ = '[';
4101 slash_seen = 1;
4102 }
4103 break;
4104
4105 case '.':
4106 if (strncmp (ufile, "./", 2) == 0)
4107 {
4108 if (!slash_seen)
4109 {
4110 *targ++ = '[';
4111 slash_seen = 1;
4112 }
4113 ufile++; /* skip the dot */
4114 if (index (&ufile[1], '/'))
4115 *targ++ = '.';
4116 else
4117 *targ++ = ']';
4118 }
4119 else if (strncmp (ufile, "../", 3) == 0)
4120 {
4121 if (!slash_seen)
4122 {
4123 *targ++ = '[';
4124 slash_seen = 1;
4125 }
4126 *targ++ = '-';
4127 ufile += 2; /* skip the dots */
4128 if (index (&ufile[1], '/'))
4129 *targ++ = '.';
4130 else
4131 *targ++ = ']';
4132 }
4133 else
4134 *targ++ = *ufile;
4135 break;
4136
4137 default:
4138 *targ++ = *ufile;
4139 break;
4140 }
4141 ufile++;
4142 }
4143 *targ = '\0';
4144
4145 return utbuf;
4146 }
4147
4148 char *
4149 getwd (pathname)
4150 char *pathname;
4151 {
4152 char *ptr, *val;
4153 extern char *getcwd ();
4154
4155 #define MAXPATHLEN 1024
4156
4157 ptr = xmalloc (MAXPATHLEN);
4158 val = getcwd (ptr, MAXPATHLEN);
4159 if (val == 0)
4160 {
4161 xfree (ptr);
4162 return val;
4163 }
4164 strcpy (pathname, ptr);
4165 xfree (ptr);
4166
4167 return pathname;
4168 }
4169
4170 int
4171 getppid ()
4172 {
4173 long item_code = JPI$_OWNER;
4174 unsigned long parent_id;
4175 int status;
4176
4177 if (((status = LIB$GETJPI (&item_code, 0, 0, &parent_id)) & 1) == 0)
4178 {
4179 errno = EVMSERR;
4180 vaxc$errno = status;
4181 return -1;
4182 }
4183 return parent_id;
4184 }
4185
4186 #undef getuid
4187 unsigned
4188 sys_getuid ()
4189 {
4190 return (getgid () << 16) | getuid ();
4191 }
4192
4193 int
4194 sys_read (fildes, buf, nbyte)
4195 int fildes;
4196 char *buf;
4197 unsigned int nbyte;
4198 {
4199 return read (fildes, buf, (nbyte < MAXIOSIZE ? nbyte : MAXIOSIZE));
4200 }
4201
4202 #if 0
4203 int
4204 sys_write (fildes, buf, nbyte)
4205 int fildes;
4206 char *buf;
4207 unsigned int nbyte;
4208 {
4209 register int nwrote, rtnval = 0;
4210
4211 while (nbyte > MAXIOSIZE && (nwrote = write (fildes, buf, MAXIOSIZE)) > 0) {
4212 nbyte -= nwrote;
4213 buf += nwrote;
4214 rtnval += nwrote;
4215 }
4216 if (nwrote < 0)
4217 return rtnval ? rtnval : -1;
4218 if ((nwrote = write (fildes, buf, nbyte)) < 0)
4219 return rtnval ? rtnval : -1;
4220 return (rtnval + nwrote);
4221 }
4222 #endif /* 0 */
4223
4224 /*
4225 * VAX/VMS VAX C RTL really loses. It insists that records
4226 * end with a newline (carriage return) character, and if they
4227 * don't it adds one (nice of it isn't it!)
4228 *
4229 * Thus we do this stupidity below.
4230 */
4231
4232 int
4233 sys_write (fildes, buf, nbytes)
4234 int fildes;
4235 char *buf;
4236 unsigned int nbytes;
4237 {
4238 register char *p;
4239 register char *e;
4240 int sum = 0;
4241 struct stat st;
4242
4243 fstat (fildes, &st);
4244 p = buf;
4245 while (nbytes > 0)
4246 {
4247 int len, retval;
4248
4249 /* Handle fixed-length files with carriage control. */
4250 if (st.st_fab_rfm == FAB$C_FIX
4251 && ((st.st_fab_rat & (FAB$M_FTN | FAB$M_CR)) != 0))
4252 {
4253 len = st.st_fab_mrs;
4254 retval = write (fildes, p, min (len, nbytes));
4255 if (retval != len)
4256 return -1;
4257 retval++; /* This skips the implied carriage control */
4258 }
4259 else
4260 {
4261 e = p + min (MAXIOSIZE, nbytes) - 1;
4262 while (*e != '\n' && e > p) e--;
4263 if (p == e) /* Ok.. so here we add a newline... sigh. */
4264 e = p + min (MAXIOSIZE, nbytes) - 1;
4265 len = e + 1 - p;
4266 retval = write (fildes, p, len);
4267 if (retval != len)
4268 return -1;
4269 }
4270 p += retval;
4271 sum += retval;
4272 nbytes -= retval;
4273 }
4274 return sum;
4275 }
4276
4277 /* Create file NEW copying its attributes from file OLD. If
4278 OLD is 0 or does not exist, create based on the value of
4279 vms_stmlf_recfm. */
4280
4281 /* Protection value the file should ultimately have.
4282 Set by create_copy_attrs, and use by rename_sansversions. */
4283 static unsigned short int fab_final_pro;
4284
4285 int
4286 creat_copy_attrs (old, new)
4287 char *old, *new;
4288 {
4289 struct FAB fab = cc$rms_fab;
4290 struct XABPRO xabpro;
4291 char aclbuf[256]; /* Choice of size is arbitrary. See below. */
4292 extern int vms_stmlf_recfm;
4293
4294 if (old)
4295 {
4296 fab.fab$b_fac = FAB$M_GET;
4297 fab.fab$l_fna = old;
4298 fab.fab$b_fns = strlen (old);
4299 fab.fab$l_xab = (char *) &xabpro;
4300 xabpro = cc$rms_xabpro;
4301 xabpro.xab$l_aclbuf = aclbuf;
4302 xabpro.xab$w_aclsiz = sizeof aclbuf;
4303 /* Call $OPEN to fill in the fab & xabpro fields. */
4304 if (SYS$OPEN (&fab, 0, 0) & 1)
4305 {
4306 SYS$CLOSE (&fab, 0, 0);
4307 fab.fab$l_alq = 0; /* zero the allocation quantity */
4308 if (xabpro.xab$w_acllen > 0)
4309 {
4310 if (xabpro.xab$w_acllen > sizeof aclbuf)
4311 /* If the acl buffer was too short, redo open with longer one.
4312 Wouldn't need to do this if there were some system imposed
4313 limit on the size of an ACL, but I can't find any such. */
4314 {
4315 xabpro.xab$l_aclbuf = (char *) alloca (xabpro.xab$w_acllen);
4316 xabpro.xab$w_aclsiz = xabpro.xab$w_acllen;
4317 if (SYS$OPEN (&fab, 0, 0) & 1)
4318 SYS$CLOSE (&fab, 0, 0);
4319 else
4320 old = 0;
4321 }
4322 }
4323 else
4324 xabpro.xab$l_aclbuf = 0;
4325 }
4326 else
4327 old = 0;
4328 }
4329 fab.fab$l_fna = new;
4330 fab.fab$b_fns = strlen (new);
4331 if (!old)
4332 {
4333 fab.fab$l_xab = 0;
4334 fab.fab$b_rfm = vms_stmlf_recfm ? FAB$C_STMLF : FAB$C_VAR;
4335 fab.fab$b_rat = FAB$M_CR;
4336 }
4337
4338 /* Set the file protections such that we will be able to manipulate
4339 this file. Once we are done writing and renaming it, we will set
4340 the protections back. */
4341 if (old)
4342 fab_final_pro = xabpro.xab$w_pro;
4343 else
4344 SYS$SETDFPROT (0, &fab_final_pro);
4345 xabpro.xab$w_pro &= 0xff0f; /* set O:rewd for now. This is set back later. */
4346
4347 /* Create the new file with either default attrs or attrs copied
4348 from old file. */
4349 if (!(SYS$CREATE (&fab, 0, 0) & 1))
4350 return -1;
4351 SYS$CLOSE (&fab, 0, 0);
4352 /* As this is a "replacement" for creat, return a file descriptor
4353 opened for writing. */
4354 return open (new, O_WRONLY);
4355 }
4356
4357 #ifdef creat
4358 #undef creat
4359 #include <varargs.h>
4360 #ifdef __GNUC__
4361 #ifndef va_count
4362 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4363 #endif
4364 #endif
4365
4366 int
4367 sys_creat (va_alist)
4368 va_dcl
4369 {
4370 va_list list_incrementer;
4371 char *name;
4372 int mode;
4373 int rfd; /* related file descriptor */
4374 int fd; /* Our new file descriptor */
4375 int count;
4376 struct stat st_buf;
4377 char rfm[12];
4378 char rat[15];
4379 char mrs[13];
4380 char fsz[13];
4381 extern int vms_stmlf_recfm;
4382
4383 va_count (count);
4384 va_start (list_incrementer);
4385 name = va_arg (list_incrementer, char *);
4386 mode = va_arg (list_incrementer, int);
4387 if (count > 2)
4388 rfd = va_arg (list_incrementer, int);
4389 va_end (list_incrementer);
4390 if (count > 2)
4391 {
4392 /* Use information from the related file descriptor to set record
4393 format of the newly created file. */
4394 fstat (rfd, &st_buf);
4395 switch (st_buf.st_fab_rfm)
4396 {
4397 case FAB$C_FIX:
4398 strcpy (rfm, "rfm = fix");
4399 sprintf (mrs, "mrs = %d", st_buf.st_fab_mrs);
4400 strcpy (rat, "rat = ");
4401 if (st_buf.st_fab_rat & FAB$M_CR)
4402 strcat (rat, "cr");
4403 else if (st_buf.st_fab_rat & FAB$M_FTN)
4404 strcat (rat, "ftn");
4405 else if (st_buf.st_fab_rat & FAB$M_PRN)
4406 strcat (rat, "prn");
4407 if (st_buf.st_fab_rat & FAB$M_BLK)
4408 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4409 strcat (rat, ", blk");
4410 else
4411 strcat (rat, "blk");
4412 return creat (name, 0, rfm, rat, mrs);
4413
4414 case FAB$C_VFC:
4415 strcpy (rfm, "rfm = vfc");
4416 sprintf (fsz, "fsz = %d", st_buf.st_fab_fsz);
4417 strcpy (rat, "rat = ");
4418 if (st_buf.st_fab_rat & FAB$M_CR)
4419 strcat (rat, "cr");
4420 else if (st_buf.st_fab_rat & FAB$M_FTN)
4421 strcat (rat, "ftn");
4422 else if (st_buf.st_fab_rat & FAB$M_PRN)
4423 strcat (rat, "prn");
4424 if (st_buf.st_fab_rat & FAB$M_BLK)
4425 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4426 strcat (rat, ", blk");
4427 else
4428 strcat (rat, "blk");
4429 return creat (name, 0, rfm, rat, fsz);
4430
4431 case FAB$C_STM:
4432 strcpy (rfm, "rfm = stm");
4433 break;
4434
4435 case FAB$C_STMCR:
4436 strcpy (rfm, "rfm = stmcr");
4437 break;
4438
4439 case FAB$C_STMLF:
4440 strcpy (rfm, "rfm = stmlf");
4441 break;
4442
4443 case FAB$C_UDF:
4444 strcpy (rfm, "rfm = udf");
4445 break;
4446
4447 case FAB$C_VAR:
4448 strcpy (rfm, "rfm = var");
4449 break;
4450 }
4451 strcpy (rat, "rat = ");
4452 if (st_buf.st_fab_rat & FAB$M_CR)
4453 strcat (rat, "cr");
4454 else if (st_buf.st_fab_rat & FAB$M_FTN)
4455 strcat (rat, "ftn");
4456 else if (st_buf.st_fab_rat & FAB$M_PRN)
4457 strcat (rat, "prn");
4458 if (st_buf.st_fab_rat & FAB$M_BLK)
4459 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4460 strcat (rat, ", blk");
4461 else
4462 strcat (rat, "blk");
4463 }
4464 else
4465 {
4466 strcpy (rfm, vms_stmlf_recfm ? "rfm = stmlf" : "rfm=var");
4467 strcpy (rat, "rat=cr");
4468 }
4469 /* Until the VAX C RTL fixes the many bugs with modes, always use
4470 mode 0 to get the user's default protection. */
4471 fd = creat (name, 0, rfm, rat);
4472 if (fd < 0 && errno == EEXIST)
4473 {
4474 if (unlink (name) < 0)
4475 report_file_error ("delete", build_string (name));
4476 fd = creat (name, 0, rfm, rat);
4477 }
4478 return fd;
4479 }
4480 #endif /* creat */
4481
4482 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4483 int
4484 sys_fwrite (ptr, size, num, fp)
4485 register char * ptr;
4486 FILE * fp;
4487 {
4488 register int tot = num * size;
4489
4490 while (tot--)
4491 fputc (*ptr++, fp);
4492 return num;
4493 }
4494
4495 /*
4496 * The VMS C library routine creat actually creates a new version of an
4497 * existing file rather than truncating the old version. There are times
4498 * when this is not the desired behavior, for instance, when writing an
4499 * auto save file (you only want one version), or when you don't have
4500 * write permission in the directory containing the file (but the file
4501 * itself is writable). Hence this routine, which is equivalent to
4502 * "close (creat (fn, 0));" on Unix if fn already exists.
4503 */
4504 int
4505 vms_truncate (fn)
4506 char *fn;
4507 {
4508 struct FAB xfab = cc$rms_fab;
4509 struct RAB xrab = cc$rms_rab;
4510 int status;
4511
4512 xfab.fab$l_fop = FAB$M_TEF; /* free allocated but unused blocks on close */
4513 xfab.fab$b_fac = FAB$M_TRN | FAB$M_GET; /* allow truncate and get access */
4514 xfab.fab$b_shr = FAB$M_NIL; /* allow no sharing - file must be locked */
4515 xfab.fab$l_fna = fn;
4516 xfab.fab$b_fns = strlen (fn);
4517 xfab.fab$l_dna = ";0"; /* default to latest version of the file */
4518 xfab.fab$b_dns = 2;
4519 xrab.rab$l_fab = &xfab;
4520
4521 /* This gibberish opens the file, positions to the first record, and
4522 deletes all records from there until the end of file. */
4523 if ((SYS$OPEN (&xfab) & 01) == 01)
4524 {
4525 if ((SYS$CONNECT (&xrab) & 01) == 01 &&
4526 (SYS$FIND (&xrab) & 01) == 01 &&
4527 (SYS$TRUNCATE (&xrab) & 01) == 01)
4528 status = 0;
4529 else
4530 status = -1;
4531 }
4532 else
4533 status = -1;
4534 SYS$CLOSE (&xfab);
4535 return status;
4536 }
4537
4538 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4539 SYSPRV or a readable SYSUAF.DAT. */
4540
4541 #ifdef READ_SYSUAF
4542 /*
4543 * getuaf.c
4544 *
4545 * Routine to read the VMS User Authorization File and return
4546 * a specific user's record.
4547 */
4548
4549 static struct UAF retuaf;
4550
4551 struct UAF *
4552 get_uaf_name (uname)
4553 char * uname;
4554 {
4555 register status;
4556 struct FAB uaf_fab;
4557 struct RAB uaf_rab;
4558
4559 uaf_fab = cc$rms_fab;
4560 uaf_rab = cc$rms_rab;
4561 /* initialize fab fields */
4562 uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
4563 uaf_fab.fab$b_fns = 21;
4564 uaf_fab.fab$b_fac = FAB$M_GET;
4565 uaf_fab.fab$b_org = FAB$C_IDX;
4566 uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
4567 /* initialize rab fields */
4568 uaf_rab.rab$l_fab = &uaf_fab;
4569 /* open the User Authorization File */
4570 status = SYS$OPEN (&uaf_fab);
4571 if (!(status&1))
4572 {
4573 errno = EVMSERR;
4574 vaxc$errno = status;
4575 return 0;
4576 }
4577 status = SYS$CONNECT (&uaf_rab);
4578 if (!(status&1))
4579 {
4580 errno = EVMSERR;
4581 vaxc$errno = status;
4582 return 0;
4583 }
4584 /* read the requested record - index is in uname */
4585 uaf_rab.rab$l_kbf = uname;
4586 uaf_rab.rab$b_ksz = strlen (uname);
4587 uaf_rab.rab$b_rac = RAB$C_KEY;
4588 uaf_rab.rab$l_ubf = (char *)&retuaf;
4589 uaf_rab.rab$w_usz = sizeof retuaf;
4590 status = SYS$GET (&uaf_rab);
4591 if (!(status&1))
4592 {
4593 errno = EVMSERR;
4594 vaxc$errno = status;
4595 return 0;
4596 }
4597 /* close the User Authorization File */
4598 status = SYS$DISCONNECT (&uaf_rab);
4599 if (!(status&1))
4600 {
4601 errno = EVMSERR;
4602 vaxc$errno = status;
4603 return 0;
4604 }
4605 status = SYS$CLOSE (&uaf_fab);
4606 if (!(status&1))
4607 {
4608 errno = EVMSERR;
4609 vaxc$errno = status;
4610 return 0;
4611 }
4612 return &retuaf;
4613 }
4614
4615 struct UAF *
4616 get_uaf_uic (uic)
4617 unsigned long uic;
4618 {
4619 register status;
4620 struct FAB uaf_fab;
4621 struct RAB uaf_rab;
4622
4623 uaf_fab = cc$rms_fab;
4624 uaf_rab = cc$rms_rab;
4625 /* initialize fab fields */
4626 uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
4627 uaf_fab.fab$b_fns = 21;
4628 uaf_fab.fab$b_fac = FAB$M_GET;
4629 uaf_fab.fab$b_org = FAB$C_IDX;
4630 uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
4631 /* initialize rab fields */
4632 uaf_rab.rab$l_fab = &uaf_fab;
4633 /* open the User Authorization File */
4634 status = SYS$OPEN (&uaf_fab);
4635 if (!(status&1))
4636 {
4637 errno = EVMSERR;
4638 vaxc$errno = status;
4639 return 0;
4640 }
4641 status = SYS$CONNECT (&uaf_rab);
4642 if (!(status&1))
4643 {
4644 errno = EVMSERR;
4645 vaxc$errno = status;
4646 return 0;
4647 }
4648 /* read the requested record - index is in uic */
4649 uaf_rab.rab$b_krf = 1; /* 1st alternate key */
4650 uaf_rab.rab$l_kbf = (char *) &uic;
4651 uaf_rab.rab$b_ksz = sizeof uic;
4652 uaf_rab.rab$b_rac = RAB$C_KEY;
4653 uaf_rab.rab$l_ubf = (char *)&retuaf;
4654 uaf_rab.rab$w_usz = sizeof retuaf;
4655 status = SYS$GET (&uaf_rab);
4656 if (!(status&1))
4657 {
4658 errno = EVMSERR;
4659 vaxc$errno = status;
4660 return 0;
4661 }
4662 /* close the User Authorization File */
4663 status = SYS$DISCONNECT (&uaf_rab);
4664 if (!(status&1))
4665 {
4666 errno = EVMSERR;
4667 vaxc$errno = status;
4668 return 0;
4669 }
4670 status = SYS$CLOSE (&uaf_fab);
4671 if (!(status&1))
4672 {
4673 errno = EVMSERR;
4674 vaxc$errno = status;
4675 return 0;
4676 }
4677 return &retuaf;
4678 }
4679
4680 static struct passwd retpw;
4681
4682 struct passwd *
4683 cnv_uaf_pw (up)
4684 struct UAF * up;
4685 {
4686 char * ptr;
4687
4688 /* copy these out first because if the username is 32 chars, the next
4689 section will overwrite the first byte of the UIC */
4690 retpw.pw_uid = up->uaf$w_mem;
4691 retpw.pw_gid = up->uaf$w_grp;
4692
4693 /* I suppose this is not the best style, to possibly overwrite one
4694 byte beyond the end of the field, but what the heck... */
4695 ptr = &up->uaf$t_username[UAF$S_USERNAME];
4696 while (ptr[-1] == ' ')
4697 ptr--;
4698 *ptr = '\0';
4699 strcpy (retpw.pw_name, up->uaf$t_username);
4700
4701 /* the rest of these are counted ascii strings */
4702 strncpy (retpw.pw_gecos, &up->uaf$t_owner[1], up->uaf$t_owner[0]);
4703 retpw.pw_gecos[up->uaf$t_owner[0]] = '\0';
4704 strncpy (retpw.pw_dir, &up->uaf$t_defdev[1], up->uaf$t_defdev[0]);
4705 retpw.pw_dir[up->uaf$t_defdev[0]] = '\0';
4706 strncat (retpw.pw_dir, &up->uaf$t_defdir[1], up->uaf$t_defdir[0]);
4707 retpw.pw_dir[up->uaf$t_defdev[0] + up->uaf$t_defdir[0]] = '\0';
4708 strncpy (retpw.pw_shell, &up->uaf$t_defcli[1], up->uaf$t_defcli[0]);
4709 retpw.pw_shell[up->uaf$t_defcli[0]] = '\0';
4710
4711 return &retpw;
4712 }
4713 #else /* not READ_SYSUAF */
4714 static struct passwd retpw;
4715 #endif /* not READ_SYSUAF */
4716
4717 struct passwd *
4718 getpwnam (name)
4719 char * name;
4720 {
4721 #ifdef READ_SYSUAF
4722 struct UAF *up;
4723 #else
4724 char * user;
4725 char * dir;
4726 unsigned char * full;
4727 #endif /* READ_SYSUAF */
4728 char *ptr = name;
4729
4730 while (*ptr)
4731 {
4732 if ('a' <= *ptr && *ptr <= 'z')
4733 *ptr -= 040;
4734 ptr++;
4735 }
4736 #ifdef READ_SYSUAF
4737 if (!(up = get_uaf_name (name)))
4738 return 0;
4739 return cnv_uaf_pw (up);
4740 #else
4741 if (strcmp (name, getenv ("USER")) == 0)
4742 {
4743 retpw.pw_uid = getuid ();
4744 retpw.pw_gid = getgid ();
4745 strcpy (retpw.pw_name, name);
4746 if (full = egetenv ("FULLNAME"))
4747 strcpy (retpw.pw_gecos, full);
4748 else
4749 *retpw.pw_gecos = '\0';
4750 strcpy (retpw.pw_dir, egetenv ("HOME"));
4751 *retpw.pw_shell = '\0';
4752 return &retpw;
4753 }
4754 else
4755 return 0;
4756 #endif /* not READ_SYSUAF */
4757 }
4758
4759 struct passwd *
4760 getpwuid (uid)
4761 unsigned long uid;
4762 {
4763 #ifdef READ_SYSUAF
4764 struct UAF * up;
4765
4766 if (!(up = get_uaf_uic (uid)))
4767 return 0;
4768 return cnv_uaf_pw (up);
4769 #else
4770 if (uid == sys_getuid ())
4771 return getpwnam (egetenv ("USER"));
4772 else
4773 return 0;
4774 #endif /* not READ_SYSUAF */
4775 }
4776
4777 /* return total address space available to the current process. This is
4778 the sum of the current p0 size, p1 size and free page table entries
4779 available. */
4780 int
4781 vlimit ()
4782 {
4783 int item_code;
4784 unsigned long free_pages;
4785 unsigned long frep0va;
4786 unsigned long frep1va;
4787 register status;
4788
4789 item_code = JPI$_FREPTECNT;
4790 if (((status = LIB$GETJPI (&item_code, 0, 0, &free_pages)) & 1) == 0)
4791 {
4792 errno = EVMSERR;
4793 vaxc$errno = status;
4794 return -1;
4795 }
4796 free_pages *= 512;
4797
4798 item_code = JPI$_FREP0VA;
4799 if (((status = LIB$GETJPI (&item_code, 0, 0, &frep0va)) & 1) == 0)
4800 {
4801 errno = EVMSERR;
4802 vaxc$errno = status;
4803 return -1;
4804 }
4805 item_code = JPI$_FREP1VA;
4806 if (((status = LIB$GETJPI (&item_code, 0, 0, &frep1va)) & 1) == 0)
4807 {
4808 errno = EVMSERR;
4809 vaxc$errno = status;
4810 return -1;
4811 }
4812
4813 return free_pages + frep0va + (0x7fffffff - frep1va);
4814 }
4815
4816 int
4817 define_logical_name (varname, string)
4818 char *varname;
4819 char *string;
4820 {
4821 struct dsc$descriptor_s strdsc =
4822 {strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string};
4823 struct dsc$descriptor_s envdsc =
4824 {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
4825 struct dsc$descriptor_s lnmdsc =
4826 {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
4827
4828 return LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
4829 }
4830
4831 int
4832 delete_logical_name (varname)
4833 char *varname;
4834 {
4835 struct dsc$descriptor_s envdsc =
4836 {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
4837 struct dsc$descriptor_s lnmdsc =
4838 {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
4839
4840 return LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
4841 }
4842
4843 int
4844 ulimit ()
4845 {
4846 return 0;
4847 }
4848
4849 int
4850 setpgrp ()
4851 {
4852 return 0;
4853 }
4854
4855 int
4856 execvp ()
4857 {
4858 error ("execvp system call not implemented");
4859 return -1;
4860 }
4861
4862 int
4863 rename (from, to)
4864 char *from, *to;
4865 {
4866 int status;
4867 struct FAB from_fab = cc$rms_fab, to_fab = cc$rms_fab;
4868 struct NAM from_nam = cc$rms_nam, to_nam = cc$rms_nam;
4869 char from_esn[NAM$C_MAXRSS];
4870 char to_esn[NAM$C_MAXRSS];
4871
4872 from_fab.fab$l_fna = from;
4873 from_fab.fab$b_fns = strlen (from);
4874 from_fab.fab$l_nam = &from_nam;
4875 from_fab.fab$l_fop = FAB$M_NAM;
4876
4877 from_nam.nam$l_esa = from_esn;
4878 from_nam.nam$b_ess = sizeof from_esn;
4879
4880 to_fab.fab$l_fna = to;
4881 to_fab.fab$b_fns = strlen (to);
4882 to_fab.fab$l_nam = &to_nam;
4883 to_fab.fab$l_fop = FAB$M_NAM;
4884
4885 to_nam.nam$l_esa = to_esn;
4886 to_nam.nam$b_ess = sizeof to_esn;
4887
4888 status = SYS$RENAME (&from_fab, 0, 0, &to_fab);
4889
4890 if (status & 1)
4891 return 0;
4892 else
4893 {
4894 if (status == RMS$_DEV)
4895 errno = EXDEV;
4896 else
4897 errno = EVMSERR;
4898 vaxc$errno = status;
4899 return -1;
4900 }
4901 }
4902
4903 /* This function renames a file like `rename', but it strips
4904 the version number from the "to" filename, such that the "to" file is
4905 will always be a new version. It also sets the file protection once it is
4906 finished. The protection that we will use is stored in fab_final_pro,
4907 and was set when we did a creat_copy_attrs to create the file that we
4908 are renaming.
4909
4910 We could use the chmod function, but Eunichs uses 3 bits per user category
4911 to describe the protection, and VMS uses 4 (write and delete are separate
4912 bits). To maintain portability, the VMS implementation of `chmod' wires
4913 the W and D bits together. */
4914
4915
4916 static struct fibdef fib; /* We need this initialized to zero */
4917 char vms_file_written[NAM$C_MAXRSS];
4918
4919 int
4920 rename_sans_version (from,to)
4921 char *from, *to;
4922 {
4923 short int chan;
4924 int stat;
4925 short int iosb[4];
4926 int status;
4927 struct FAB to_fab = cc$rms_fab;
4928 struct NAM to_nam = cc$rms_nam;
4929 struct dsc$descriptor fib_d ={sizeof (fib),0,0,(char*) &fib};
4930 struct dsc$descriptor fib_attr[2]
4931 = {{sizeof (fab_final_pro),ATR$C_FPRO,0,(char*) &fab_final_pro},{0,0,0,0}};
4932 char to_esn[NAM$C_MAXRSS];
4933
4934 $DESCRIPTOR (disk,to_esn);
4935
4936 to_fab.fab$l_fna = to;
4937 to_fab.fab$b_fns = strlen (to);
4938 to_fab.fab$l_nam = &to_nam;
4939 to_fab.fab$l_fop = FAB$M_NAM;
4940
4941 to_nam.nam$l_esa = to_esn;
4942 to_nam.nam$b_ess = sizeof to_esn;
4943
4944 status = SYS$PARSE (&to_fab, 0, 0); /* figure out the full file name */
4945
4946 if (to_nam.nam$l_fnb && NAM$M_EXP_VER)
4947 *(to_nam.nam$l_ver) = '\0';
4948
4949 stat = rename (from, to_esn);
4950 if (stat < 0)
4951 return stat;
4952
4953 strcpy (vms_file_written, to_esn);
4954
4955 to_fab.fab$l_fna = vms_file_written; /* this points to the versionless name */
4956 to_fab.fab$b_fns = strlen (vms_file_written);
4957
4958 /* Now set the file protection to the correct value */
4959 SYS$OPEN (&to_fab, 0, 0); /* This fills in the nam$w_fid fields */
4960
4961 /* Copy these fields into the fib */
4962 fib.fib$r_fid_overlay.fib$w_fid[0] = to_nam.nam$w_fid[0];
4963 fib.fib$r_fid_overlay.fib$w_fid[1] = to_nam.nam$w_fid[1];
4964 fib.fib$r_fid_overlay.fib$w_fid[2] = to_nam.nam$w_fid[2];
4965
4966 SYS$CLOSE (&to_fab, 0, 0);
4967
4968 stat = SYS$ASSIGN (&disk, &chan, 0, 0); /* open a channel to the disk */
4969 if (!stat)
4970 LIB$SIGNAL (stat);
4971 stat = SYS$QIOW (0, chan, IO$_MODIFY, iosb, 0, 0, &fib_d,
4972 0, 0, 0, &fib_attr, 0);
4973 if (!stat)
4974 LIB$SIGNAL (stat);
4975 stat = SYS$DASSGN (chan);
4976 if (!stat)
4977 LIB$SIGNAL (stat);
4978 strcpy (vms_file_written, to_esn); /* We will write this to the terminal*/
4979 return 0;
4980 }
4981
4982 int
4983 link (file, new)
4984 char * file, * new;
4985 {
4986 register status;
4987 struct FAB fab;
4988 struct NAM nam;
4989 unsigned short fid[3];
4990 char esa[NAM$C_MAXRSS];
4991
4992 fab = cc$rms_fab;
4993 fab.fab$l_fop = FAB$M_OFP;
4994 fab.fab$l_fna = file;
4995 fab.fab$b_fns = strlen (file);
4996 fab.fab$l_nam = &nam;
4997
4998 nam = cc$rms_nam;
4999 nam.nam$l_esa = esa;
5000 nam.nam$b_ess = NAM$C_MAXRSS;
5001
5002 status = SYS$PARSE (&fab);
5003 if ((status & 1) == 0)
5004 {
5005 errno = EVMSERR;
5006 vaxc$errno = status;
5007 return -1;
5008 }
5009 status = SYS$SEARCH (&fab);
5010 if ((status & 1) == 0)
5011 {
5012 errno = EVMSERR;
5013 vaxc$errno = status;
5014 return -1;
5015 }
5016
5017 fid[0] = nam.nam$w_fid[0];
5018 fid[1] = nam.nam$w_fid[1];
5019 fid[2] = nam.nam$w_fid[2];
5020
5021 fab.fab$l_fna = new;
5022 fab.fab$b_fns = strlen (new);
5023
5024 status = SYS$PARSE (&fab);
5025 if ((status & 1) == 0)
5026 {
5027 errno = EVMSERR;
5028 vaxc$errno = status;
5029 return -1;
5030 }
5031
5032 nam.nam$w_fid[0] = fid[0];
5033 nam.nam$w_fid[1] = fid[1];
5034 nam.nam$w_fid[2] = fid[2];
5035
5036 nam.nam$l_esa = nam.nam$l_name;
5037 nam.nam$b_esl = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver;
5038
5039 status = SYS$ENTER (&fab);
5040 if ((status & 1) == 0)
5041 {
5042 errno = EVMSERR;
5043 vaxc$errno = status;
5044 return -1;
5045 }
5046
5047 return 0;
5048 }
5049
5050 void
5051 croak (badfunc)
5052 char *badfunc;
5053 {
5054 printf ("%s not yet implemented\r\n", badfunc);
5055 reset_sys_modes ();
5056 exit (1);
5057 }
5058
5059 long
5060 random ()
5061 {
5062 /* Arrange to return a range centered on zero. */
5063 return rand () - (1 << 30);
5064 }
5065
5066 void
5067 srandom (seed)
5068 {
5069 srand (seed);
5070 }
5071 #endif /* VMS */
5072 \f
5073 #ifdef AIXHFT
5074
5075 /* Called from init_sys_modes. */
5076 void
5077 hft_init ()
5078 {
5079 int junk;
5080
5081 /* If we're not on an HFT we shouldn't do any of this. We determine
5082 if we are on an HFT by trying to get an HFT error code. If this
5083 call fails, we're not on an HFT. */
5084 #ifdef IBMR2AIX
5085 if (ioctl (0, HFQERROR, &junk) < 0)
5086 return;
5087 #else /* not IBMR2AIX */
5088 if (ioctl (0, HFQEIO, 0) < 0)
5089 return;
5090 #endif /* not IBMR2AIX */
5091
5092 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5093 as the rubout key's ASCII code. Here this is changed. The bug is that
5094 there's no way to determine the old mapping, so in reset_sys_modes
5095 we need to assume that the normal map had been present. Of course, this
5096 code also doesn't help if on a terminal emulator which doesn't understand
5097 HFT VTD's. */
5098 {
5099 struct hfbuf buf;
5100 struct hfkeymap keymap;
5101
5102 buf.hf_bufp = (char *)&keymap;
5103 buf.hf_buflen = sizeof (keymap);
5104 keymap.hf_nkeys = 2;
5105 keymap.hfkey[0].hf_kpos = 15;
5106 keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
5107 #ifdef IBMR2AIX
5108 keymap.hfkey[0].hf_keyidh = '<';
5109 #else /* not IBMR2AIX */
5110 keymap.hfkey[0].hf_page = '<';
5111 #endif /* not IBMR2AIX */
5112 keymap.hfkey[0].hf_char = 127;
5113 keymap.hfkey[1].hf_kpos = 15;
5114 keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
5115 #ifdef IBMR2AIX
5116 keymap.hfkey[1].hf_keyidh = '<';
5117 #else /* not IBMR2AIX */
5118 keymap.hfkey[1].hf_page = '<';
5119 #endif /* not IBMR2AIX */
5120 keymap.hfkey[1].hf_char = 127;
5121 hftctl (0, HFSKBD, &buf);
5122 }
5123 /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
5124 at times. */
5125 line_ins_del_ok = char_ins_del_ok = 0;
5126 }
5127
5128 /* Reset the rubout key to backspace. */
5129
5130 void
5131 hft_reset ()
5132 {
5133 struct hfbuf buf;
5134 struct hfkeymap keymap;
5135 int junk;
5136
5137 #ifdef IBMR2AIX
5138 if (ioctl (0, HFQERROR, &junk) < 0)
5139 return;
5140 #else /* not IBMR2AIX */
5141 if (ioctl (0, HFQEIO, 0) < 0)
5142 return;
5143 #endif /* not IBMR2AIX */
5144
5145 buf.hf_bufp = (char *)&keymap;
5146 buf.hf_buflen = sizeof (keymap);
5147 keymap.hf_nkeys = 2;
5148 keymap.hfkey[0].hf_kpos = 15;
5149 keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
5150 #ifdef IBMR2AIX
5151 keymap.hfkey[0].hf_keyidh = '<';
5152 #else /* not IBMR2AIX */
5153 keymap.hfkey[0].hf_page = '<';
5154 #endif /* not IBMR2AIX */
5155 keymap.hfkey[0].hf_char = 8;
5156 keymap.hfkey[1].hf_kpos = 15;
5157 keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
5158 #ifdef IBMR2AIX
5159 keymap.hfkey[1].hf_keyidh = '<';
5160 #else /* not IBMR2AIX */
5161 keymap.hfkey[1].hf_page = '<';
5162 #endif /* not IBMR2AIX */
5163 keymap.hfkey[1].hf_char = 8;
5164 hftctl (0, HFSKBD, &buf);
5165 }
5166
5167 #endif /* AIXHFT */
5168
5169 #ifdef USE_DL_STUBS
5170
5171 /* These are included on Sunos 4.1 when we do not use shared libraries.
5172 X11 libraries may refer to these functions but (we hope) do not
5173 actually call them. */
5174
5175 void *
5176 dlopen ()
5177 {
5178 return 0;
5179 }
5180
5181 void *
5182 dlsym ()
5183 {
5184 return 0;
5185 }
5186
5187 int
5188 dlclose ()
5189 {
5190 return -1;
5191 }
5192
5193 #endif /* USE_DL_STUBS */
5194 \f
5195 #ifndef BSTRING
5196
5197 #ifndef bzero
5198
5199 void
5200 bzero (b, length)
5201 register char *b;
5202 register int length;
5203 {
5204 #ifdef VMS
5205 short zero = 0;
5206 long max_str = 65535;
5207
5208 while (length > max_str) {
5209 (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
5210 length -= max_str;
5211 b += max_str;
5212 }
5213 max_str = length;
5214 (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
5215 #else
5216 while (length-- > 0)
5217 *b++ = 0;
5218 #endif /* not VMS */
5219 }
5220
5221 #endif /* no bzero */
5222 #endif /* BSTRING */
5223
5224 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5225 #undef bcopy
5226
5227 /* Saying `void' requires a declaration, above, where bcopy is used
5228 and that declaration causes pain for systems where bcopy is a macro. */
5229 bcopy (b1, b2, length)
5230 register char *b1;
5231 register char *b2;
5232 register int length;
5233 {
5234 #ifdef VMS
5235 long max_str = 65535;
5236
5237 while (length > max_str) {
5238 (void) LIB$MOVC3 (&max_str, b1, b2);
5239 length -= max_str;
5240 b1 += max_str;
5241 b2 += max_str;
5242 }
5243 max_str = length;
5244 (void) LIB$MOVC3 (&length, b1, b2);
5245 #else
5246 while (length-- > 0)
5247 *b2++ = *b1++;
5248 #endif /* not VMS */
5249 }
5250 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5251
5252 #ifndef BSTRING
5253 #ifndef bcmp
5254 int
5255 bcmp (b1, b2, length) /* This could be a macro! */
5256 register char *b1;
5257 register char *b2;
5258 register int length;
5259 {
5260 #ifdef VMS
5261 struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
5262 struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
5263
5264 return STR$COMPARE (&src1, &src2);
5265 #else
5266 while (length-- > 0)
5267 if (*b1++ != *b2++)
5268 return 1;
5269
5270 return 0;
5271 #endif /* not VMS */
5272 }
5273 #endif /* no bcmp */
5274 #endif /* not BSTRING */