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