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