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