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