Add font logging to list and match functions.
[emacs.git] / src / sysdep.c
blob1ef5b512eea8747f2b5ecc7bcd6580332a19a985
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 of the License, or
11 (at your option) 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. If not, see <http://www.gnu.org/licenses/>. */
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include <signal.h>
26 #include <stdio.h>
27 #include <setjmp.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #include "lisp.h"
32 /* Including stdlib.h isn't necessarily enough to get srandom
33 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
34 #ifdef HAVE_RANDOM
35 #if 0 /* Don't prototype srandom; it takes an unsigned argument on
36 some systems, and an unsigned long on others, like FreeBSD
37 4.1. */
38 extern void srandom P_ ((unsigned int));
39 #endif
40 #endif
42 /* The w32 build defines select stuff in w32.h, which is included by
43 sys/select.h (included below). */
44 #ifndef WINDOWSNT
45 #include "sysselect.h"
46 #endif
48 #include "blockinput.h"
50 #ifdef WINDOWSNT
51 #define read sys_read
52 #define write sys_write
53 #include <windows.h>
54 #ifndef NULL
55 #define NULL 0
56 #endif
57 #endif /* not WINDOWSNT */
59 /* Does anyone other than VMS need this? */
60 #ifndef fwrite
61 #define sys_fwrite fwrite
62 #else
63 #undef fwrite
64 #endif
66 #include <sys/types.h>
67 #include <sys/stat.h>
68 #include <errno.h>
70 #ifdef HAVE_SETPGID
71 #if !defined (USG) || defined (BSD_PGRPS)
72 #undef setpgrp
73 #define setpgrp setpgid
74 #endif
75 #endif
77 /* Get SI_SRPC_DOMAIN, if it is available. */
78 #ifdef HAVE_SYS_SYSTEMINFO_H
79 #include <sys/systeminfo.h>
80 #endif
82 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
83 #include <dos.h>
84 #include "dosfns.h"
85 #include "msdos.h"
86 #include <sys/param.h>
88 #if __DJGPP__ > 1
89 extern int etext;
90 extern unsigned start __asm__ ("start");
91 #endif
92 #endif
94 #ifndef USE_CRT_DLL
95 #ifndef errno
96 extern int errno;
97 #endif
98 #endif
100 #ifdef VMS
101 #include <rms.h>
102 #include <ttdef.h>
103 #include <tt2def.h>
104 #include <iodef.h>
105 #include <ssdef.h>
106 #include <descrip.h>
107 #include <fibdef.h>
108 #include <atrdef.h>
109 #include <ctype.h>
110 #include <string.h>
111 #ifdef __GNUC__
112 #include <sys/file.h>
113 #else
114 #include <file.h>
115 #endif
116 #undef F_SETFL
117 #ifndef RAB$C_BID
118 #include <rab.h>
119 #endif
120 #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
121 #endif /* VMS */
123 #ifndef VMS
124 #include <sys/file.h>
125 #endif /* not VMS */
127 #ifdef HAVE_FCNTL_H
128 #include <fcntl.h>
129 #endif
131 #ifndef MSDOS
132 #include <sys/ioctl.h>
133 #endif
135 #include "systty.h"
136 #include "syswait.h"
138 #ifdef BROKEN_TIOCGWINSZ
139 #undef TIOCGWINSZ
140 #undef TIOCSWINSZ
141 #endif
143 #if defined (USG)
144 #include <sys/utsname.h>
145 #include <memory.h>
146 #if defined (TIOCGWINSZ)
147 #ifdef NEED_SIOCTL
148 #include <sys/sioctl.h>
149 #endif
150 #ifdef NEED_PTEM_H
151 #include <sys/stream.h>
152 #include <sys/ptem.h>
153 #endif
154 #endif /* TIOCGWINSZ */
155 #endif /* USG */
157 extern int quit_char;
159 #include "keyboard.h"
160 #include "frame.h"
161 #include "window.h"
162 #include "termhooks.h"
163 #include "termchar.h"
164 #include "termopts.h"
165 #include "dispextern.h"
166 #include "process.h"
167 #include "cm.h" /* for reset_sys_modes */
169 /* For serial_configure and serial_open. */
170 extern Lisp_Object QCport, QCspeed, QCprocess;
171 extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
172 extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
174 #ifdef WINDOWSNT
175 #include <direct.h>
176 /* In process.h which conflicts with the local copy. */
177 #define _P_WAIT 0
178 int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
179 int _CRTAPI1 _getpid (void);
180 extern char *getwd (char *);
181 #endif
183 #ifdef NONSYSTEM_DIR_LIBRARY
184 #include "ndir.h"
185 #endif /* NONSYSTEM_DIR_LIBRARY */
187 #include "syssignal.h"
188 #include "systime.h"
189 #ifdef HAVE_UTIME_H
190 #include <utime.h>
191 #endif
193 #ifndef HAVE_UTIMES
194 #ifndef HAVE_STRUCT_UTIMBUF
195 /* We want to use utime rather than utimes, but we couldn't find the
196 structure declaration. We'll use the traditional one. */
197 struct utimbuf {
198 long actime;
199 long modtime;
201 #endif
202 #endif
204 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
205 #ifndef LPASS8
206 #define LPASS8 0
207 #endif
209 #ifdef BSD4_1
210 #define LNOFLSH 0100000
211 #endif
213 static int baud_convert[] =
214 #ifdef BAUD_CONVERT
215 BAUD_CONVERT;
216 #else
218 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
219 1800, 2400, 4800, 9600, 19200, 38400
221 #endif
223 #ifdef HAVE_SPEED_T
224 #include <termios.h>
225 #else
226 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
227 #else
228 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
229 #include <termios.h>
230 #endif
231 #endif
232 #endif
234 int emacs_ospeed;
236 void croak P_ ((char *)) NO_RETURN;
238 #ifdef AIXHFT
239 void hft_init P_ ((struct tty_display_info *));
240 void hft_reset P_ ((struct tty_display_info *));
241 #endif
243 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
245 SIGMASKTYPE sigprocmask_set;
248 #if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
250 /* Return the current working directory. Returns NULL on errors.
251 Any other returned value must be freed with free. This is used
252 only when get_current_dir_name is not defined on the system. */
253 char*
254 get_current_dir_name ()
256 char *buf;
257 char *pwd;
258 struct stat dotstat, pwdstat;
259 /* If PWD is accurate, use it instead of calling getwd. PWD is
260 sometimes a nicer name, and using it may avoid a fatal error if a
261 parent directory is searchable but not readable. */
262 if ((pwd = getenv ("PWD")) != 0
263 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
264 && stat (pwd, &pwdstat) == 0
265 && stat (".", &dotstat) == 0
266 && dotstat.st_ino == pwdstat.st_ino
267 && dotstat.st_dev == pwdstat.st_dev
268 #ifdef MAXPATHLEN
269 && strlen (pwd) < MAXPATHLEN
270 #endif
273 buf = (char *) malloc (strlen (pwd) + 1);
274 if (!buf)
275 return NULL;
276 strcpy (buf, pwd);
278 #ifdef HAVE_GETCWD
279 else
281 size_t buf_size = 1024;
282 buf = (char *) malloc (buf_size);
283 if (!buf)
284 return NULL;
285 for (;;)
287 if (getcwd (buf, buf_size) == buf)
288 break;
289 if (errno != ERANGE)
291 int tmp_errno = errno;
292 free (buf);
293 errno = tmp_errno;
294 return NULL;
296 buf_size *= 2;
297 buf = (char *) realloc (buf, buf_size);
298 if (!buf)
299 return NULL;
302 #else
303 else
305 /* We need MAXPATHLEN here. */
306 buf = (char *) malloc (MAXPATHLEN + 1);
307 if (!buf)
308 return NULL;
309 if (getwd (buf) == NULL)
311 int tmp_errno = errno;
312 free (buf);
313 errno = tmp_errno;
314 return NULL;
317 #endif
318 return buf;
320 #endif
323 /* Discard pending input on all input descriptors. */
325 void
326 discard_tty_input ()
328 #ifndef WINDOWSNT
329 struct emacs_tty buf;
331 if (noninteractive)
332 return;
334 #ifdef VMS
335 end_kbd_input ();
336 SYS$QIOW (0, fileno (CURTTY()->input), IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
337 &buf.main, 0, 0, terminator_mask, 0, 0);
338 queue_kbd_input ();
339 #else /* not VMS */
340 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
341 while (dos_keyread () != -1)
343 #else /* not MSDOS */
345 struct tty_display_info *tty;
346 for (tty = tty_list; tty; tty = tty->next)
348 if (tty->input) /* Is the device suspended? */
350 EMACS_GET_TTY (fileno (tty->input), &buf);
351 EMACS_SET_TTY (fileno (tty->input), &buf, 0);
355 #endif /* not MSDOS */
356 #endif /* not VMS */
357 #endif /* not WINDOWSNT */
361 #ifdef SIGTSTP
363 /* Arrange for character C to be read as the next input from
364 the terminal.
365 XXX What if we have multiple ttys?
368 void
369 stuff_char (char c)
371 if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
372 return;
374 /* Should perhaps error if in batch mode */
375 #ifdef TIOCSTI
376 ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
377 #else /* no TIOCSTI */
378 error ("Cannot stuff terminal input characters in this version of Unix");
379 #endif /* no TIOCSTI */
382 #endif /* SIGTSTP */
384 void
385 init_baud_rate (int fd)
387 if (noninteractive)
388 emacs_ospeed = 0;
389 else
391 #ifdef DOS_NT
392 emacs_ospeed = 15;
393 #else /* not DOS_NT */
394 #ifdef VMS
395 struct sensemode sg;
397 SYS$QIOW (0, fd, IO$_SENSEMODE, &sg, 0, 0,
398 &sg.class, 12, 0, 0, 0, 0 );
399 emacs_ospeed = sg.xmit_baud;
400 #else /* not VMS */
401 #ifdef HAVE_TERMIOS
402 struct termios sg;
404 sg.c_cflag = B9600;
405 tcgetattr (fd, &sg);
406 emacs_ospeed = cfgetospeed (&sg);
407 #else /* neither VMS nor TERMIOS */
408 #ifdef HAVE_TERMIO
409 struct termio sg;
411 sg.c_cflag = B9600;
412 #ifdef HAVE_TCATTR
413 tcgetattr (fd, &sg);
414 #else
415 ioctl (fd, TCGETA, &sg);
416 #endif
417 emacs_ospeed = sg.c_cflag & CBAUD;
418 #else /* neither VMS nor TERMIOS nor TERMIO */
419 struct sgttyb sg;
421 sg.sg_ospeed = B9600;
422 if (ioctl (fd, TIOCGETP, &sg) < 0)
423 abort ();
424 emacs_ospeed = sg.sg_ospeed;
425 #endif /* not HAVE_TERMIO */
426 #endif /* not HAVE_TERMIOS */
427 #endif /* not VMS */
428 #endif /* not DOS_NT */
431 baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
432 ? baud_convert[emacs_ospeed] : 9600);
433 if (baud_rate == 0)
434 baud_rate = 1200;
438 /*ARGSUSED*/
439 void
440 set_exclusive_use (fd)
441 int fd;
443 #ifdef FIOCLEX
444 ioctl (fd, FIOCLEX, 0);
445 #endif
446 /* Ok to do nothing if this feature does not exist */
449 #ifndef subprocesses
451 wait_without_blocking ()
453 #ifdef BSD_SYSTEM
454 wait3 (0, WNOHANG | WUNTRACED, 0);
455 #else
456 croak ("wait_without_blocking");
457 #endif
458 synch_process_alive = 0;
461 #endif /* not subprocesses */
463 int wait_debugging; /* Set nonzero to make following function work under dbx
464 (at least for bsd). */
466 SIGTYPE
467 wait_for_termination_signal ()
470 /* Wait for subprocess with process id `pid' to terminate and
471 make sure it will get eliminated (not remain forever as a zombie) */
473 void
474 wait_for_termination (pid)
475 int pid;
477 while (1)
479 #ifdef subprocesses
480 #ifdef VMS
481 int status;
483 status = SYS$FORCEX (&pid, 0, 0);
484 break;
485 #else /* not VMS */
486 #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
487 /* Note that kill returns -1 even if the process is just a zombie now.
488 But inevitably a SIGCHLD interrupt should be generated
489 and child_sig will do wait3 and make the process go away. */
490 /* There is some indication that there is a bug involved with
491 termination of subprocesses, perhaps involving a kernel bug too,
492 but no idea what it is. Just as a hunch we signal SIGCHLD to see
493 if that causes the problem to go away or get worse. */
494 sigsetmask (sigmask (SIGCHLD));
495 if (0 > kill (pid, 0))
497 sigsetmask (SIGEMPTYMASK);
498 kill (getpid (), SIGCHLD);
499 break;
501 if (wait_debugging)
502 sleep (1);
503 else
504 sigpause (SIGEMPTYMASK);
505 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
506 #ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */
507 sigblock (sigmask (SIGCHLD));
508 errno = 0;
509 if (kill (pid, 0) == -1 && errno == ESRCH)
511 sigunblock (sigmask (SIGCHLD));
512 break;
515 sigsuspend (&empty_mask);
516 #else /* not POSIX_SIGNALS */
517 #ifdef HAVE_SYSV_SIGPAUSE
518 sighold (SIGCHLD);
519 if (0 > kill (pid, 0))
521 sigrelse (SIGCHLD);
522 break;
524 sigpause (SIGCHLD);
525 #else /* not HAVE_SYSV_SIGPAUSE */
526 #ifdef WINDOWSNT
527 wait (0);
528 break;
529 #else /* not WINDOWSNT */
530 if (0 > kill (pid, 0))
531 break;
532 /* Using sleep instead of pause avoids timing error.
533 If the inferior dies just before the sleep,
534 we lose just one second. */
535 sleep (1);
536 #endif /* not WINDOWSNT */
537 #endif /* not HAVE_SYSV_SIGPAUSE */
538 #endif /* not POSIX_SIGNALS */
539 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
540 #endif /* not VMS */
541 #else /* not subprocesses */
542 #if __DJGPP__ > 1
543 break;
544 #else /* not __DJGPP__ > 1 */
545 #ifndef BSD4_1
546 if (kill (pid, 0) < 0)
547 break;
548 wait (0);
549 #else /* BSD4_1 */
550 int status;
551 status = wait (0);
552 if (status == pid || status == -1)
553 break;
554 #endif /* BSD4_1 */
555 #endif /* not __DJGPP__ > 1*/
556 #endif /* not subprocesses */
560 #ifdef subprocesses
563 * flush any pending output
564 * (may flush input as well; it does not matter the way we use it)
567 void
568 flush_pending_output (channel)
569 int channel;
571 #ifdef HAVE_TERMIOS
572 /* If we try this, we get hit with SIGTTIN, because
573 the child's tty belongs to the child's pgrp. */
574 #else
575 #ifdef TCFLSH
576 ioctl (channel, TCFLSH, 1);
577 #else
578 #ifdef TIOCFLUSH
579 int zero = 0;
580 /* 3rd arg should be ignored
581 but some 4.2 kernels actually want the address of an int
582 and nonzero means something different. */
583 ioctl (channel, TIOCFLUSH, &zero);
584 #endif
585 #endif
586 #endif
589 #ifndef VMS
590 /* Set up the terminal at the other end of a pseudo-terminal that
591 we will be controlling an inferior through.
592 It should not echo or do line-editing, since that is done
593 in Emacs. No padding needed for insertion into an Emacs buffer. */
595 void
596 child_setup_tty (out)
597 int out;
599 #ifndef DOS_NT
600 struct emacs_tty s;
602 EMACS_GET_TTY (out, &s);
604 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
605 s.main.c_oflag |= OPOST; /* Enable output postprocessing */
606 s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */
607 #ifdef NLDLY
608 /* http://lists.gnu.org/archive/html/emacs-devel/2008-05/msg00406.html
609 Some versions of GNU Hurd do not have FFDLY? */
610 #ifdef FFDLY
611 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
612 /* No output delays */
613 #else
614 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY);
615 /* No output delays */
616 #endif
617 #endif
618 s.main.c_lflag &= ~ECHO; /* Disable echo */
619 s.main.c_lflag |= ISIG; /* Enable signals */
620 #if 0 /* This causes bugs in (for instance) telnet to certain sites. */
621 s.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
622 #ifdef INLCR /* Just being cautious, since I can't check how
623 widespread INLCR is--rms. */
624 s.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
625 #endif
626 #endif
627 #ifdef IUCLC
628 s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */
629 #endif
630 #ifdef ISTRIP
631 s.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
632 #endif
633 #ifdef OLCUC
634 s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */
635 #endif
636 s.main.c_oflag &= ~TAB3; /* Disable tab expansion */
637 s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
638 #if 0
639 /* Said to be unnecessary: */
640 s.main.c_cc[VMIN] = 1; /* minimum number of characters to accept */
641 s.main.c_cc[VTIME] = 0; /* wait forever for at least 1 character */
642 #endif
644 s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */
645 s.main.c_cc[VEOF] = 04; /* insure that EOF is Control-D */
646 s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
647 s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
649 #ifdef HPUX
650 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
651 #endif /* HPUX */
653 #ifdef SIGNALS_VIA_CHARACTERS
654 /* the QUIT and INTR character are used in process_send_signal
655 so set them here to something useful. */
656 if (s.main.c_cc[VQUIT] == CDISABLE)
657 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
658 if (s.main.c_cc[VINTR] == CDISABLE)
659 s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
660 #endif /* not SIGNALS_VIA_CHARACTERS */
662 #ifdef AIX
663 /* AIX enhanced edit loses NULs, so disable it */
664 #ifndef IBMR2AIX
665 s.main.c_line = 0;
666 s.main.c_iflag &= ~ASCEDIT;
667 #endif
668 /* Also, PTY overloads NUL and BREAK.
669 don't ignore break, but don't signal either, so it looks like NUL. */
670 s.main.c_iflag &= ~IGNBRK;
671 s.main.c_iflag &= ~BRKINT;
672 /* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
673 unconditionally. Then a SIGNALS_VIA_CHARACTERS conditional
674 would force it to 0377. That looks like duplicated code. */
675 #ifndef SIGNALS_VIA_CHARACTERS
676 /* QUIT and INTR work better as signals, so disable character forms */
677 s.main.c_cc[VQUIT] = CDISABLE;
678 s.main.c_cc[VINTR] = CDISABLE;
679 s.main.c_lflag &= ~ISIG;
680 #endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
681 s.main.c_cc[VEOL] = CDISABLE;
682 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
683 #endif /* AIX */
685 #else /* not HAVE_TERMIO */
687 s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
688 | CBREAK | TANDEM);
689 s.main.sg_flags |= LPASS8;
690 s.main.sg_erase = 0377;
691 s.main.sg_kill = 0377;
692 s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */
694 #endif /* not HAVE_TERMIO */
696 EMACS_SET_TTY (out, &s, 0);
698 #ifdef BSD4_1
699 if (interrupt_input)
700 reset_sigio (0);
701 #endif /* BSD4_1 */
702 #endif /* not DOS_NT */
704 #endif /* not VMS */
706 #endif /* subprocesses */
708 /* Record a signal code and the handler for it. */
709 struct save_signal
711 int code;
712 SIGTYPE (*handler) P_ ((int));
715 static void save_signal_handlers P_ ((struct save_signal *));
716 static void restore_signal_handlers P_ ((struct save_signal *));
718 /* Suspend the Emacs process; give terminal to its superior. */
720 void
721 sys_suspend ()
723 #ifdef VMS
724 /* "Foster" parentage allows emacs to return to a subprocess that attached
725 to the current emacs as a cheaper than starting a whole new process. This
726 is set up by KEPTEDITOR.COM. */
727 unsigned long parent_id, foster_parent_id;
728 char *fpid_string;
730 fpid_string = getenv ("EMACS_PARENT_PID");
731 if (fpid_string != NULL)
733 sscanf (fpid_string, "%x", &foster_parent_id);
734 if (foster_parent_id != 0)
735 parent_id = foster_parent_id;
736 else
737 parent_id = getppid ();
739 else
740 parent_id = getppid ();
742 xfree (fpid_string); /* On VMS, this was malloc'd */
744 if (parent_id && parent_id != 0xffffffff)
746 SIGTYPE (*oldsig)() = (int) signal (SIGINT, SIG_IGN);
747 int status = LIB$ATTACH (&parent_id) & 1;
748 signal (SIGINT, oldsig);
749 return status;
751 else
753 struct {
754 int l;
755 char *a;
756 } d_prompt;
757 d_prompt.l = sizeof ("Emacs: "); /* Our special prompt */
758 d_prompt.a = "Emacs: "; /* Just a reminder */
759 LIB$SPAWN (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &d_prompt, 0);
760 return 1;
762 return -1;
763 #else
764 #if defined (SIGTSTP) && !defined (MSDOS)
767 int pgrp = EMACS_GETPGRP (0);
768 EMACS_KILLPG (pgrp, SIGTSTP);
771 #else /* No SIGTSTP */
772 #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
773 ptrace (0, 0, 0, 0); /* set for ptrace - caught by csh */
774 kill (getpid (), SIGQUIT);
776 #else /* No SIGTSTP or USG_JOBCTRL */
778 /* On a system where suspending is not implemented,
779 instead fork a subshell and let it talk directly to the terminal
780 while we wait. */
781 sys_subshell ();
783 #endif /* no USG_JOBCTRL */
784 #endif /* no SIGTSTP */
785 #endif /* not VMS */
788 /* Fork a subshell. */
790 void
791 sys_subshell ()
793 #ifndef VMS
794 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
795 int st;
796 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
797 #endif
798 int pid;
799 struct save_signal saved_handlers[5];
800 Lisp_Object dir;
801 unsigned char *str = 0;
802 int len;
804 saved_handlers[0].code = SIGINT;
805 saved_handlers[1].code = SIGQUIT;
806 saved_handlers[2].code = SIGTERM;
807 #ifdef SIGIO
808 saved_handlers[3].code = SIGIO;
809 saved_handlers[4].code = 0;
810 #else
811 saved_handlers[3].code = 0;
812 #endif
814 /* Mentioning current_buffer->buffer would mean including buffer.h,
815 which somehow wedges the hp compiler. So instead... */
817 dir = intern ("default-directory");
818 if (NILP (Fboundp (dir)))
819 goto xyzzy;
820 dir = Fsymbol_value (dir);
821 if (!STRINGP (dir))
822 goto xyzzy;
824 dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
825 str = (unsigned char *) alloca (SCHARS (dir) + 2);
826 len = SCHARS (dir);
827 bcopy (SDATA (dir), str, len);
828 if (str[len - 1] != '/') str[len++] = '/';
829 str[len] = 0;
830 xyzzy:
832 #ifdef DOS_NT
833 pid = 0;
834 #if __DJGPP__ > 1
835 save_signal_handlers (saved_handlers);
836 synch_process_alive = 1;
837 #endif /* __DJGPP__ > 1 */
838 #else
839 pid = vfork ();
840 if (pid == -1)
841 error ("Can't spawn subshell");
842 #endif
844 if (pid == 0)
846 char *sh = 0;
848 #ifdef DOS_NT /* MW, Aug 1993 */
849 getwd (oldwd);
850 if (sh == 0)
851 sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
852 #endif
853 if (sh == 0)
854 sh = (char *) egetenv ("SHELL");
855 if (sh == 0)
856 sh = "sh";
858 /* Use our buffer's default directory for the subshell. */
859 if (str)
860 chdir ((char *) str);
862 #ifdef subprocesses
863 close_process_descs (); /* Close Emacs's pipes/ptys */
864 #endif
866 #ifdef SET_EMACS_PRIORITY
868 extern EMACS_INT emacs_priority;
870 if (emacs_priority < 0)
871 nice (-emacs_priority);
873 #endif
875 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
877 char *epwd = getenv ("PWD");
878 char old_pwd[MAXPATHLEN+1+4];
880 /* If PWD is set, pass it with corrected value. */
881 if (epwd)
883 strcpy (old_pwd, epwd);
884 if (str[len - 1] == '/')
885 str[len - 1] = '\0';
886 setenv ("PWD", str, 1);
888 st = system (sh);
889 chdir (oldwd);
890 if (epwd)
891 putenv (old_pwd); /* restore previous value */
893 #if 0 /* This is also reported if last command executed in subshell failed, KFS */
894 if (st)
895 report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil));
896 #endif
897 #else /* not MSDOS */
898 #ifdef WINDOWSNT
899 /* Waits for process completion */
900 pid = _spawnlp (_P_WAIT, sh, sh, NULL);
901 chdir (oldwd);
902 if (pid == -1)
903 write (1, "Can't execute subshell", 22);
904 #else /* not WINDOWSNT */
905 execlp (sh, sh, (char *) 0);
906 write (1, "Can't execute subshell", 22);
907 _exit (1);
908 #endif /* not WINDOWSNT */
909 #endif /* not MSDOS */
912 /* Do this now if we did not do it before. */
913 #if !defined (MSDOS) || __DJGPP__ == 1
914 save_signal_handlers (saved_handlers);
915 synch_process_alive = 1;
916 #endif
918 #ifndef DOS_NT
919 wait_for_termination (pid);
920 #endif
921 restore_signal_handlers (saved_handlers);
922 synch_process_alive = 0;
923 #endif /* !VMS */
926 static void
927 save_signal_handlers (saved_handlers)
928 struct save_signal *saved_handlers;
930 while (saved_handlers->code)
932 saved_handlers->handler
933 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
934 saved_handlers++;
938 static void
939 restore_signal_handlers (saved_handlers)
940 struct save_signal *saved_handlers;
942 while (saved_handlers->code)
944 signal (saved_handlers->code, saved_handlers->handler);
945 saved_handlers++;
949 #ifndef SIGIO
950 /* If SIGIO is broken, don't do anything. */
951 void
952 init_sigio (int fd)
956 void
957 reset_sigio (int fd)
961 void
962 request_sigio (void)
966 void
967 unrequest_sigio (void)
971 #else
972 #ifdef F_SETFL
974 int old_fcntl_flags[MAXDESC];
976 void
977 init_sigio (fd)
978 int fd;
980 #ifdef FASYNC
981 old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
982 fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC);
983 #endif
984 interrupts_deferred = 0;
987 void
988 reset_sigio (fd)
989 int fd;
991 #ifdef FASYNC
992 fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
993 #endif
996 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
997 /* XXX Uhm, FASYNC is not used anymore here. */
998 /* XXX Yeah, but you need it for SIGIO, don't you? */
1000 void
1001 request_sigio ()
1003 if (noninteractive)
1004 return;
1006 #ifdef SIGWINCH
1007 sigunblock (sigmask (SIGWINCH));
1008 #endif
1009 sigunblock (sigmask (SIGIO));
1011 interrupts_deferred = 0;
1014 void
1015 unrequest_sigio (void)
1017 if (noninteractive)
1018 return;
1020 #if 0 /* XXX What's wrong with blocking SIGIO under X? */
1021 if (x_display_list)
1022 return;
1023 #endif
1025 #ifdef SIGWINCH
1026 sigblock (sigmask (SIGWINCH));
1027 #endif
1028 sigblock (sigmask (SIGIO));
1029 interrupts_deferred = 1;
1032 #else /* no FASYNC */
1033 #ifndef MSDOS
1035 void
1036 request_sigio ()
1038 if (noninteractive || read_socket_hook)
1039 return;
1041 croak ("request_sigio");
1044 void
1045 unrequest_sigio ()
1047 if (noninteractive || read_socket_hook)
1048 return;
1050 croak ("unrequest_sigio");
1053 #endif /* MSDOS */
1054 #endif /* FASYNC */
1055 #endif /* F_SETFL */
1056 #endif /* SIGIO */
1058 /* Saving and restoring the process group of Emacs's terminal. */
1060 #ifdef BSD_PGRPS
1062 /* The process group of which Emacs was a member when it initially
1063 started.
1065 If Emacs was in its own process group (i.e. inherited_pgroup ==
1066 getpid ()), then we know we're running under a shell with job
1067 control (Emacs would never be run as part of a pipeline).
1068 Everything is fine.
1070 If Emacs was not in its own process group, then we know we're
1071 running under a shell (or a caller) that doesn't know how to
1072 separate itself from Emacs (like sh). Emacs must be in its own
1073 process group in order to receive SIGIO correctly. In this
1074 situation, we put ourselves in our own pgroup, forcibly set the
1075 tty's pgroup to our pgroup, and make sure to restore and reinstate
1076 the tty's pgroup just like any other terminal setting. If
1077 inherited_group was not the tty's pgroup, then we'll get a
1078 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
1079 it goes foreground in the future, which is what should happen.
1081 This variable is initialized in emacs.c. */
1082 int inherited_pgroup;
1084 /* Split off the foreground process group to Emacs alone. When we are
1085 in the foreground, but not started in our own process group,
1086 redirect the tty device handle FD to point to our own process
1087 group. We need to be in our own process group to receive SIGIO
1088 properly. */
1089 static void
1090 narrow_foreground_group (int fd)
1092 int me = getpid ();
1094 setpgrp (0, inherited_pgroup);
1095 #if 0
1096 /* XXX inherited_pgroup should not be zero here, but GTK seems to
1097 mess this up. */
1098 if (! inherited_pgroup)
1099 abort (); /* Should not happen. */
1100 #endif
1101 if (inherited_pgroup != me)
1102 EMACS_SET_TTY_PGRP (fd, &me); /* XXX This only works on the controlling tty. */
1103 setpgrp (0, me);
1106 /* Set the tty to our original foreground group. */
1107 static void
1108 widen_foreground_group (int fd)
1110 if (inherited_pgroup != getpid ())
1111 EMACS_SET_TTY_PGRP (fd, &inherited_pgroup);
1112 setpgrp (0, inherited_pgroup);
1115 #endif /* BSD_PGRPS */
1117 /* Getting and setting emacs_tty structures. */
1119 /* Set *TC to the parameters associated with the terminal FD.
1120 Return zero if all's well, or -1 if we ran into an error we
1121 couldn't deal with. */
1123 emacs_get_tty (fd, settings)
1124 int fd;
1125 struct emacs_tty *settings;
1127 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
1128 #ifdef HAVE_TCATTR
1129 /* We have those nifty POSIX tcmumbleattr functions. */
1130 bzero (&settings->main, sizeof (settings->main));
1131 if (tcgetattr (fd, &settings->main) < 0)
1132 return -1;
1134 #else
1135 #ifdef HAVE_TERMIO
1136 /* The SYSV-style interface? */
1137 if (ioctl (fd, TCGETA, &settings->main) < 0)
1138 return -1;
1140 #else
1141 #ifdef VMS
1142 /* Vehemently Monstrous System? :-) */
1143 if (! (SYS$QIOW (0, fd, IO$_SENSEMODE, settings, 0, 0,
1144 &settings->main.class, 12, 0, 0, 0, 0)
1145 & 1))
1146 return -1;
1148 #else
1149 #ifndef DOS_NT
1150 /* I give up - I hope you have the BSD ioctls. */
1151 if (ioctl (fd, TIOCGETP, &settings->main) < 0)
1152 return -1;
1153 #endif /* not DOS_NT */
1154 #endif
1155 #endif
1156 #endif
1158 /* Suivant - Do we have to get struct ltchars data? */
1159 #ifdef HAVE_LTCHARS
1160 if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
1161 return -1;
1162 #endif
1164 /* How about a struct tchars and a wordful of lmode bits? */
1165 #ifdef HAVE_TCHARS
1166 if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
1167 || ioctl (fd, TIOCLGET, &settings->lmode) < 0)
1168 return -1;
1169 #endif
1171 /* We have survived the tempest. */
1172 return 0;
1176 /* Set the parameters of the tty on FD according to the contents of
1177 *SETTINGS. If FLUSHP is non-zero, we discard input.
1178 Return 0 if all went well, and -1 if anything failed. */
1181 emacs_set_tty (fd, settings, flushp)
1182 int fd;
1183 struct emacs_tty *settings;
1184 int flushp;
1186 /* Set the primary parameters - baud rate, character size, etcetera. */
1187 #ifdef HAVE_TCATTR
1188 int i;
1189 /* We have those nifty POSIX tcmumbleattr functions.
1190 William J. Smith <wjs@wiis.wang.com> writes:
1191 "POSIX 1003.1 defines tcsetattr to return success if it was
1192 able to perform any of the requested actions, even if some
1193 of the requested actions could not be performed.
1194 We must read settings back to ensure tty setup properly.
1195 AIX requires this to keep tty from hanging occasionally." */
1196 /* This make sure that we don't loop indefinitely in here. */
1197 for (i = 0 ; i < 10 ; i++)
1198 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
1200 if (errno == EINTR)
1201 continue;
1202 else
1203 return -1;
1205 else
1207 struct termios new;
1209 bzero (&new, sizeof (new));
1210 /* Get the current settings, and see if they're what we asked for. */
1211 tcgetattr (fd, &new);
1212 /* We cannot use memcmp on the whole structure here because under
1213 * aix386 the termios structure has some reserved field that may
1214 * not be filled in.
1216 if ( new.c_iflag == settings->main.c_iflag
1217 && new.c_oflag == settings->main.c_oflag
1218 && new.c_cflag == settings->main.c_cflag
1219 && new.c_lflag == settings->main.c_lflag
1220 && memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
1221 break;
1222 else
1223 continue;
1226 #else
1227 #ifdef HAVE_TERMIO
1228 /* The SYSV-style interface? */
1229 if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
1230 return -1;
1232 #else
1233 #ifdef VMS
1234 /* Vehemently Monstrous System? :-) */
1235 if (! (SYS$QIOW (0, fd, IO$_SETMODE, &input_iosb, 0, 0,
1236 &settings->main.class, 12, 0, 0, 0, 0)
1237 & 1))
1238 return -1;
1240 #else
1241 #ifndef DOS_NT
1242 /* I give up - I hope you have the BSD ioctls. */
1243 if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
1244 return -1;
1245 #endif /* not DOS_NT */
1247 #endif
1248 #endif
1249 #endif
1251 /* Suivant - Do we have to get struct ltchars data? */
1252 #ifdef HAVE_LTCHARS
1253 if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
1254 return -1;
1255 #endif
1257 /* How about a struct tchars and a wordful of lmode bits? */
1258 #ifdef HAVE_TCHARS
1259 if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
1260 || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
1261 return -1;
1262 #endif
1264 /* We have survived the tempest. */
1265 return 0;
1270 #ifdef BSD4_1
1271 /* BSD 4.1 needs to keep track of the lmode bits in order to start
1272 sigio. */
1273 int lmode;
1274 #endif
1276 #ifdef F_SETOWN
1277 int old_fcntl_owner[MAXDESC];
1278 #endif /* F_SETOWN */
1280 /* This may also be defined in stdio,
1281 but if so, this does no harm,
1282 and using the same name avoids wasting the other one's space. */
1284 #ifdef nec_ews_svr4
1285 extern char *_sobuf ;
1286 #else
1287 #if defined (USG) || defined (DGUX)
1288 unsigned char _sobuf[BUFSIZ+8];
1289 #else
1290 char _sobuf[BUFSIZ];
1291 #endif
1292 #endif
1294 #ifdef HAVE_LTCHARS
1295 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
1296 #endif
1297 #ifdef HAVE_TCHARS
1298 static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
1299 #endif
1301 /* Initialize the terminal mode on all tty devices that are currently
1302 open. */
1304 void
1305 init_all_sys_modes (void)
1307 struct tty_display_info *tty;
1308 for (tty = tty_list; tty; tty = tty->next)
1309 init_sys_modes (tty);
1312 /* Initialize the terminal mode on the given tty device. */
1314 void
1315 init_sys_modes (tty_out)
1316 struct tty_display_info *tty_out;
1318 struct emacs_tty tty;
1320 #ifdef VMS
1321 #if 0
1322 static int oob_chars[2] = {0, 1 << 7}; /* catch C-g's */
1323 extern int (*interrupt_signal) ();
1324 #endif
1325 #endif
1327 Vtty_erase_char = Qnil;
1329 if (noninteractive)
1330 return;
1332 if (!tty_out->output)
1333 return; /* The tty is suspended. */
1335 #ifdef VMS
1336 if (!input_ef)
1337 input_ef = get_kbd_event_flag ();
1338 /* LIB$GET_EF (&input_ef); */
1339 SYS$CLREF (input_ef);
1340 waiting_for_ast = 0;
1341 if (!timer_ef)
1342 timer_ef = get_timer_event_flag ();
1343 /* LIB$GET_EF (&timer_ef); */
1344 SYS$CLREF (timer_ef);
1345 #if 0
1346 if (!process_ef)
1348 LIB$GET_EF (&process_ef);
1349 SYS$CLREF (process_ef);
1351 if (input_ef / 32 != process_ef / 32)
1352 croak ("Input and process event flags in different clusters.");
1353 #endif
1354 if (input_ef / 32 != timer_ef / 32)
1355 croak ("Input and timer event flags in different clusters.");
1356 #if 0
1357 input_eflist = ((unsigned) 1 << (input_ef % 32)) |
1358 ((unsigned) 1 << (process_ef % 32));
1359 #endif
1360 timer_eflist = ((unsigned) 1 << (input_ef % 32)) |
1361 ((unsigned) 1 << (timer_ef % 32));
1362 #ifndef VMS4_4
1363 sys_access_reinit ();
1364 #endif
1365 #endif /* VMS */
1367 #ifdef BSD_PGRPS
1368 #if 0
1369 /* read_socket_hook is not global anymore. I think doing this
1370 unconditionally will not cause any problems. */
1371 if (! read_socket_hook && EQ (Vinitial_window_system, Qnil))
1372 #endif
1373 narrow_foreground_group (fileno (tty_out->input));
1374 #endif
1376 if (! tty_out->old_tty)
1377 tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
1379 EMACS_GET_TTY (fileno (tty_out->input), tty_out->old_tty);
1381 tty = *tty_out->old_tty;
1383 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1384 XSETINT (Vtty_erase_char, tty.main.c_cc[VERASE]);
1386 tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
1387 tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
1388 #ifdef INLCR /* I'm just being cautious,
1389 since I can't check how widespread INLCR is--rms. */
1390 tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
1391 #endif
1392 #ifdef ISTRIP
1393 tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
1394 #endif
1395 tty.main.c_lflag &= ~ECHO; /* Disable echo */
1396 tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */
1397 #ifdef IEXTEN
1398 tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
1399 #endif
1400 tty.main.c_lflag |= ISIG; /* Enable signals */
1401 if (tty_out->flow_control)
1403 tty.main.c_iflag |= IXON; /* Enable start/stop output control */
1404 #ifdef IXANY
1405 tty.main.c_iflag &= ~IXANY;
1406 #endif /* IXANY */
1408 else
1409 tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
1410 tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
1411 on output */
1412 tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */
1413 #ifdef CS8
1414 if (tty_out->meta_key)
1416 tty.main.c_cflag |= CS8; /* allow 8th bit on input */
1417 tty.main.c_cflag &= ~PARENB;/* Don't check parity */
1419 #endif
1420 if (tty_out->input == stdin)
1422 tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
1423 /* Set up C-g for both SIGQUIT and SIGINT.
1424 We don't know which we will get, but we handle both alike
1425 so which one it really gives us does not matter. */
1426 tty.main.c_cc[VQUIT] = quit_char;
1428 else
1430 /* We normally don't get interrupt or quit signals from tty
1431 devices other than our controlling terminal; therefore,
1432 we must handle C-g as normal input. Unfortunately, this
1433 means that the interrupt and quit feature must be
1434 disabled on secondary ttys, or we would not even see the
1435 keypress.
1437 Note that even though emacsclient could have special code
1438 to pass SIGINT to Emacs, we should _not_ enable
1439 interrupt/quit keys for emacsclient frames. This means
1440 that we can't break out of loops in C code from a
1441 secondary tty frame, but we can always decide what
1442 display the C-g came from, which is more important from a
1443 usability point of view. (Consider the case when two
1444 people work together using the same Emacs instance.) */
1445 tty.main.c_cc[VINTR] = CDISABLE;
1446 tty.main.c_cc[VQUIT] = CDISABLE;
1448 tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
1449 tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
1450 #ifdef VSWTCH
1451 tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
1452 of C-z */
1453 #endif /* VSWTCH */
1455 #if defined (mips) || defined (HAVE_TCATTR)
1456 #ifdef VSUSP
1457 tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
1458 #endif /* VSUSP */
1459 #ifdef V_DSUSP
1460 tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
1461 #endif /* V_DSUSP */
1462 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1463 tty.main.c_cc[VDSUSP] = CDISABLE;
1464 #endif /* VDSUSP */
1465 #ifdef VLNEXT
1466 tty.main.c_cc[VLNEXT] = CDISABLE;
1467 #endif /* VLNEXT */
1468 #ifdef VREPRINT
1469 tty.main.c_cc[VREPRINT] = CDISABLE;
1470 #endif /* VREPRINT */
1471 #ifdef VWERASE
1472 tty.main.c_cc[VWERASE] = CDISABLE;
1473 #endif /* VWERASE */
1474 #ifdef VDISCARD
1475 tty.main.c_cc[VDISCARD] = CDISABLE;
1476 #endif /* VDISCARD */
1478 if (tty_out->flow_control)
1480 #ifdef VSTART
1481 tty.main.c_cc[VSTART] = '\021';
1482 #endif /* VSTART */
1483 #ifdef VSTOP
1484 tty.main.c_cc[VSTOP] = '\023';
1485 #endif /* VSTOP */
1487 else
1489 #ifdef VSTART
1490 tty.main.c_cc[VSTART] = CDISABLE;
1491 #endif /* VSTART */
1492 #ifdef VSTOP
1493 tty.main.c_cc[VSTOP] = CDISABLE;
1494 #endif /* VSTOP */
1496 #endif /* mips or HAVE_TCATTR */
1498 #ifdef SET_LINE_DISCIPLINE
1499 /* Need to explicitly request TERMIODISC line discipline or
1500 Ultrix's termios does not work correctly. */
1501 tty.main.c_line = SET_LINE_DISCIPLINE;
1502 #endif
1503 #ifdef AIX
1504 #ifndef IBMR2AIX
1505 /* AIX enhanced edit loses NULs, so disable it. */
1506 tty.main.c_line = 0;
1507 tty.main.c_iflag &= ~ASCEDIT;
1508 #else
1509 tty.main.c_cc[VSTRT] = CDISABLE;
1510 tty.main.c_cc[VSTOP] = CDISABLE;
1511 tty.main.c_cc[VSUSP] = CDISABLE;
1512 tty.main.c_cc[VDSUSP] = CDISABLE;
1513 #endif /* IBMR2AIX */
1514 if (tty_out->flow_control)
1516 #ifdef VSTART
1517 tty.main.c_cc[VSTART] = '\021';
1518 #endif /* VSTART */
1519 #ifdef VSTOP
1520 tty.main.c_cc[VSTOP] = '\023';
1521 #endif /* VSTOP */
1523 /* Also, PTY overloads NUL and BREAK.
1524 don't ignore break, but don't signal either, so it looks like NUL.
1525 This really serves a purpose only if running in an XTERM window
1526 or via TELNET or the like, but does no harm elsewhere. */
1527 tty.main.c_iflag &= ~IGNBRK;
1528 tty.main.c_iflag &= ~BRKINT;
1529 #endif
1530 #else /* if not HAVE_TERMIO */
1531 #ifdef VMS
1532 tty.main.tt_char |= TT$M_NOECHO;
1533 if (meta_key)
1534 tty.main.tt_char |= TT$M_EIGHTBIT;
1535 if (tty_out->flow_control)
1536 tty.main.tt_char |= TT$M_TTSYNC;
1537 else
1538 tty.main.tt_char &= ~TT$M_TTSYNC;
1539 tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
1540 #else /* not VMS (BSD, that is) */
1541 #ifndef DOS_NT
1542 XSETINT (Vtty_erase_char, tty.main.sg_erase);
1543 tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1544 if (meta_key)
1545 tty.main.sg_flags |= ANYP;
1546 tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
1547 #endif /* not DOS_NT */
1548 #endif /* not VMS (BSD, that is) */
1549 #endif /* not HAVE_TERMIO */
1551 /* If going to use CBREAK mode, we must request C-g to interrupt
1552 and turn off start and stop chars, etc. If not going to use
1553 CBREAK mode, do this anyway so as to turn off local flow
1554 control for user coming over network on 4.2; in this case,
1555 only t_stopc and t_startc really matter. */
1556 #ifndef HAVE_TERMIO
1557 #ifdef HAVE_TCHARS
1558 /* Note: if not using CBREAK mode, it makes no difference how we
1559 set this */
1560 tty.tchars = new_tchars;
1561 tty.tchars.t_intrc = quit_char;
1562 if (tty_out->flow_control)
1564 tty.tchars.t_startc = '\021';
1565 tty.tchars.t_stopc = '\023';
1568 tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | tty_out->old_tty.lmode;
1569 #ifdef ultrix
1570 /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt
1571 anything, and leaving it in breaks the meta key. Go figure. */
1572 tty.lmode &= ~LLITOUT;
1573 #endif
1575 #ifdef BSD4_1
1576 lmode = tty.lmode;
1577 #endif
1579 #endif /* HAVE_TCHARS */
1580 #endif /* not HAVE_TERMIO */
1582 #ifdef HAVE_LTCHARS
1583 tty.ltchars = new_ltchars;
1584 #endif /* HAVE_LTCHARS */
1585 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1586 if (!tty_out->term_initted)
1587 internal_terminal_init ();
1588 dos_ttraw ();
1589 #endif
1591 EMACS_SET_TTY (fileno (tty_out->input), &tty, 0);
1593 /* This code added to insure that, if flow-control is not to be used,
1594 we have an unlocked terminal at the start. */
1596 #ifdef TCXONC
1597 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
1598 #endif
1599 #ifdef TIOCSTART
1600 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
1601 #endif
1603 #if defined (HAVE_TERMIOS) || defined (HPUX9)
1604 #ifdef TCOON
1605 if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
1606 #endif
1607 #endif
1609 #ifdef AIXHFT
1610 hft_init (tty_out);
1611 #ifdef IBMR2AIX
1613 /* IBM's HFT device usually thinks a ^J should be LF/CR. We need it
1614 to be only LF. This is the way that is done. */
1615 struct termio tty;
1617 if (ioctl (1, HFTGETID, &tty) != -1)
1618 write (1, "\033[20l", 5);
1620 #endif
1621 #endif /* AIXHFT */
1623 #ifdef VMS
1624 /* Appears to do nothing when in PASTHRU mode.
1625 SYS$QIOW (0, fileno (tty_out->input), IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
1626 interrupt_signal, oob_chars, 0, 0, 0, 0);
1628 queue_kbd_input (0);
1629 #endif /* VMS */
1631 #ifdef F_SETFL
1632 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1633 if (interrupt_input)
1635 old_fcntl_owner[fileno (tty_out->input)] =
1636 fcntl (fileno (tty_out->input), F_GETOWN, 0);
1637 fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
1638 init_sigio (fileno (tty_out->input));
1639 #ifdef HAVE_GPM
1640 if (gpm_tty == tty_out)
1642 /* Arrange for mouse events to give us SIGIO signals. */
1643 fcntl (gpm_fd, F_SETOWN, getpid ());
1644 fcntl (gpm_fd, F_SETFL, fcntl (gpm_fd, F_GETFL, 0) | O_NONBLOCK);
1645 init_sigio (gpm_fd);
1647 #endif /* HAVE_GPM */
1649 #endif /* F_GETOWN */
1650 #endif /* F_SETFL */
1652 #ifdef BSD4_1
1653 if (interrupt_input)
1654 init_sigio (fileno (tty_out->input));
1655 #endif
1657 #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */
1658 #undef _IOFBF
1659 #endif
1660 #ifdef _IOFBF
1661 /* This symbol is defined on recent USG systems.
1662 Someone says without this call USG won't really buffer the file
1663 even with a call to setbuf. */
1664 setvbuf (tty_out->output, (char *) _sobuf, _IOFBF, sizeof _sobuf);
1665 #else
1666 setbuf (tty_out->output, (char *) _sobuf);
1667 #endif
1669 if (tty_out->terminal->set_terminal_modes_hook)
1670 tty_out->terminal->set_terminal_modes_hook (tty_out->terminal);
1672 if (!tty_out->term_initted)
1674 Lisp_Object tail, frame;
1675 FOR_EACH_FRAME (tail, frame)
1677 /* XXX This needs to be revised. */
1678 if (FRAME_TERMCAP_P (XFRAME (frame))
1679 && FRAME_TTY (XFRAME (frame)) == tty_out)
1680 init_frame_faces (XFRAME (frame));
1684 if (tty_out->term_initted && no_redraw_on_reenter)
1686 /* XXX This seems wrong on multi-tty. */
1687 if (display_completed)
1688 direct_output_forward_char (0);
1690 else
1692 Lisp_Object tail, frame;
1693 frame_garbaged = 1;
1694 FOR_EACH_FRAME (tail, frame)
1696 if (FRAME_TERMCAP_P (XFRAME (frame))
1697 && FRAME_TTY (XFRAME (frame)) == tty_out)
1698 FRAME_GARBAGED_P (XFRAME (frame)) = 1;
1702 tty_out->term_initted = 1;
1705 /* Return nonzero if safe to use tabs in output.
1706 At the time this is called, init_sys_modes has not been done yet. */
1709 tabs_safe_p (int fd)
1711 struct emacs_tty etty;
1713 EMACS_GET_TTY (fd, &etty);
1714 return EMACS_TTY_TABS_OK (&etty);
1717 /* Get terminal size from system.
1718 Store number of lines into *HEIGHTP and width into *WIDTHP.
1719 We store 0 if there's no valid information. */
1721 void
1722 get_tty_size (int fd, int *widthp, int *heightp)
1725 #ifdef TIOCGWINSZ
1727 /* BSD-style. */
1728 struct winsize size;
1730 if (ioctl (fd, TIOCGWINSZ, &size) == -1)
1731 *widthp = *heightp = 0;
1732 else
1734 *widthp = size.ws_col;
1735 *heightp = size.ws_row;
1738 #else
1739 #ifdef TIOCGSIZE
1741 /* SunOS - style. */
1742 struct ttysize size;
1744 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1745 *widthp = *heightp = 0;
1746 else
1748 *widthp = size.ts_cols;
1749 *heightp = size.ts_lines;
1752 #else
1753 #ifdef VMS
1755 /* Use a fresh channel since the current one may have stale info
1756 (for example, from prior to a suspend); and to avoid a dependency
1757 in the init sequence. */
1758 int chan;
1759 struct sensemode tty;
1761 SYS$ASSIGN (&input_dsc, &chan, 0, 0);
1762 SYS$QIOW (0, chan, IO$_SENSEMODE, &tty, 0, 0,
1763 &tty.class, 12, 0, 0, 0, 0);
1764 SYS$DASSGN (chan);
1765 *widthp = tty.scr_wid;
1766 *heightp = tty.scr_len;
1768 #else
1769 #ifdef MSDOS
1770 *widthp = ScreenCols ();
1771 *heightp = ScreenRows ();
1772 #else /* system doesn't know size */
1773 *widthp = 0;
1774 *heightp = 0;
1775 #endif
1776 #endif /* not VMS */
1777 #endif /* not SunOS-style */
1778 #endif /* not BSD-style */
1781 /* Set the logical window size associated with descriptor FD
1782 to HEIGHT and WIDTH. This is used mainly with ptys. */
1785 set_window_size (fd, height, width)
1786 int fd, height, width;
1788 #ifdef TIOCSWINSZ
1790 /* BSD-style. */
1791 struct winsize size;
1792 size.ws_row = height;
1793 size.ws_col = width;
1795 if (ioctl (fd, TIOCSWINSZ, &size) == -1)
1796 return 0; /* error */
1797 else
1798 return 1;
1800 #else
1801 #ifdef TIOCSSIZE
1803 /* SunOS - style. */
1804 struct ttysize size;
1805 size.ts_lines = height;
1806 size.ts_cols = width;
1808 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1809 return 0;
1810 else
1811 return 1;
1812 #else
1813 return -1;
1814 #endif /* not SunOS-style */
1815 #endif /* not BSD-style */
1820 /* Prepare all terminal devices for exiting Emacs. */
1822 void
1823 reset_all_sys_modes (void)
1825 struct tty_display_info *tty;
1826 for (tty = tty_list; tty; tty = tty->next)
1827 reset_sys_modes (tty);
1830 /* Prepare the terminal for closing it; move the cursor to the
1831 bottom of the frame, turn off interrupt-driven I/O, etc. */
1833 void
1834 reset_sys_modes (tty_out)
1835 struct tty_display_info *tty_out;
1837 if (noninteractive)
1839 fflush (stdout);
1840 return;
1842 if (!tty_out->term_initted)
1843 return;
1845 if (!tty_out->output)
1846 return; /* The tty is suspended. */
1848 /* Go to and clear the last line of the terminal. */
1850 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1852 /* Code adapted from tty_clear_end_of_line. */
1853 if (tty_out->TS_clr_line)
1855 emacs_tputs (tty_out, tty_out->TS_clr_line, 1, cmputc);
1857 else
1858 { /* have to do it the hard way */
1859 int i;
1860 tty_turn_off_insert (tty_out);
1862 for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
1864 fputc (' ', tty_out->output);
1868 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1869 fflush (tty_out->output);
1871 #if defined (IBMR2AIX) && defined (AIXHFT)
1873 /* HFT devices normally use ^J as a LF/CR. We forced it to
1874 do the LF only. Now, we need to reset it. */
1875 struct termio tty;
1877 if (ioctl (1, HFTGETID, &tty) != -1)
1878 write (1, "\033[20h", 5);
1880 #endif
1882 if (tty_out->terminal->reset_terminal_modes_hook)
1883 tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
1885 #ifdef BSD_SYSTEM
1886 #ifndef BSD4_1
1887 /* Avoid possible loss of output when changing terminal modes. */
1888 fsync (fileno (tty_out->output));
1889 #endif
1890 #endif
1892 #ifdef F_SETFL
1893 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1894 if (interrupt_input)
1896 reset_sigio (fileno (tty_out->input));
1897 fcntl (fileno (tty_out->input), F_SETOWN,
1898 old_fcntl_owner[fileno (tty_out->input)]);
1900 #endif /* F_SETOWN */
1901 #ifdef O_NDELAY
1902 fcntl (fileno (tty_out->input), F_SETFL,
1903 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY);
1904 #endif
1905 #endif /* F_SETFL */
1906 #ifdef BSD4_1
1907 if (interrupt_input)
1908 reset_sigio (fileno (tty_out->input));
1909 #endif /* BSD4_1 */
1911 if (tty_out->old_tty)
1912 while (EMACS_SET_TTY (fileno (tty_out->input),
1913 tty_out->old_tty, 0) < 0 && errno == EINTR)
1916 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1917 dos_ttcooked ();
1918 #endif
1920 #ifdef SET_LINE_DISCIPLINE
1921 /* Ultrix's termios *ignores* any line discipline except TERMIODISC.
1922 A different old line discipline is therefore not restored, yet.
1923 Restore the old line discipline by hand. */
1924 ioctl (0, TIOCSETD, &tty_out->old_tty.main.c_line);
1925 #endif
1927 #ifdef AIXHFT
1928 hft_reset ();
1929 #endif
1931 #ifdef BSD_PGRPS
1932 widen_foreground_group (fileno (tty_out->input));
1933 #endif
1936 #ifdef HAVE_PTYS
1938 /* Set up the proper status flags for use of a pty. */
1940 void
1941 setup_pty (fd)
1942 int fd;
1944 /* I'm told that TOICREMOTE does not mean control chars
1945 "can't be sent" but rather that they don't have
1946 input-editing or signaling effects.
1947 That should be good, because we have other ways
1948 to do those things in Emacs.
1949 However, telnet mode seems not to work on 4.2.
1950 So TIOCREMOTE is turned off now. */
1952 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1953 will hang. In particular, the "timeout" feature (which
1954 causes a read to return if there is no data available)
1955 does this. Also it is known that telnet mode will hang
1956 in such a way that Emacs must be stopped (perhaps this
1957 is the same problem).
1959 If TIOCREMOTE is turned off, then there is a bug in
1960 hp-ux which sometimes loses data. Apparently the
1961 code which blocks the master process when the internal
1962 buffer fills up does not work. Other than this,
1963 though, everything else seems to work fine.
1965 Since the latter lossage is more benign, we may as well
1966 lose that way. -- cph */
1967 #ifdef FIONBIO
1968 #if defined(SYSV_PTYS) || defined(UNIX98_PTYS)
1970 int on = 1;
1971 ioctl (fd, FIONBIO, &on);
1973 #endif
1974 #endif
1976 #endif /* HAVE_PTYS */
1978 #ifdef VMS
1980 /* Assigning an input channel is done at the start of Emacs execution.
1981 This is called each time Emacs is resumed, also, but does nothing
1982 because input_chain is no longer zero. */
1984 void
1985 init_vms_input ()
1987 int status;
1989 if (fileno (CURTTY ()->input)) == 0)
1991 status = SYS$ASSIGN (&input_dsc, &fileno (CURTTY ()->input)), 0, 0);
1992 if (! (status & 1))
1993 LIB$STOP (status);
1997 /* Deassigning the input channel is done before exiting. */
1999 void
2000 stop_vms_input ()
2002 return SYS$DASSGN (fileno (CURTTY ()->input)));
2005 short input_buffer;
2007 /* Request reading one character into the keyboard buffer.
2008 This is done as soon as the buffer becomes empty. */
2010 void
2011 queue_kbd_input ()
2013 int status;
2014 extern kbd_input_ast ();
2016 waiting_for_ast = 0;
2017 stop_input = 0;
2018 status = SYS$QIO (0, fileno (CURTTY()->input), IO$_READVBLK,
2019 &input_iosb, kbd_input_ast, 1,
2020 &input_buffer, 1, 0, terminator_mask, 0, 0);
2023 int input_count;
2025 /* Ast routine that is called when keyboard input comes in
2026 in accord with the SYS$QIO above. */
2028 void
2029 kbd_input_ast ()
2031 register int c = -1;
2032 int old_errno = errno;
2033 extern EMACS_TIME *input_available_clear_time;
2035 if (waiting_for_ast)
2036 SYS$SETEF (input_ef);
2037 waiting_for_ast = 0;
2038 input_count++;
2039 #ifdef ASTDEBUG
2040 if (input_count == 25)
2041 exit (1);
2042 printf ("Ast # %d,", input_count);
2043 printf (" iosb = %x, %x, %x, %x",
2044 input_iosb.offset, input_iosb.status, input_iosb.termlen,
2045 input_iosb.term);
2046 #endif
2047 if (input_iosb.offset)
2049 c = input_buffer;
2050 #ifdef ASTDEBUG
2051 printf (", char = 0%o", c);
2052 #endif
2054 #ifdef ASTDEBUG
2055 printf ("\n");
2056 fflush (stdout);
2057 sleep (1);
2058 #endif
2059 if (! stop_input)
2060 queue_kbd_input ();
2061 if (c >= 0)
2063 struct input_event e;
2064 EVENT_INIT (e);
2066 e.kind = ASCII_KEYSTROKE_EVENT;
2067 XSETINT (e.code, c);
2068 e.frame_or_window = selected_frame;
2069 kbd_buffer_store_event (&e);
2071 if (input_available_clear_time)
2072 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
2073 errno = old_errno;
2076 /* Wait until there is something in kbd_buffer. */
2078 void
2079 wait_for_kbd_input ()
2081 extern int have_process_input, process_exited;
2083 /* If already something, avoid doing system calls. */
2084 if (detect_input_pending ())
2086 return;
2088 /* Clear a flag, and tell ast routine above to set it. */
2089 SYS$CLREF (input_ef);
2090 waiting_for_ast = 1;
2091 /* Check for timing error: ast happened while we were doing that. */
2092 if (!detect_input_pending ())
2094 /* No timing error: wait for flag to be set. */
2095 set_waiting_for_input (0);
2096 SYS$WFLOR (input_ef, input_eflist);
2097 clear_waiting_for_input ();
2098 if (!detect_input_pending ())
2099 /* Check for subprocess input availability */
2101 int dsp = have_process_input || process_exited;
2103 SYS$CLREF (process_ef);
2104 if (have_process_input)
2105 process_command_input ();
2106 if (process_exited)
2107 process_exit ();
2108 if (dsp)
2110 update_mode_lines++;
2111 prepare_menu_bars ();
2112 redisplay_preserve_echo_area (18);
2116 waiting_for_ast = 0;
2119 /* Get rid of any pending QIO, when we are about to suspend
2120 or when we want to throw away pending input.
2121 We wait for a positive sign that the AST routine has run
2122 and therefore there is no I/O request queued when we return.
2123 SYS$SETAST is used to avoid a timing error. */
2125 void
2126 end_kbd_input ()
2128 #ifdef ASTDEBUG
2129 printf ("At end_kbd_input.\n");
2130 fflush (stdout);
2131 sleep (1);
2132 #endif
2133 if (LIB$AST_IN_PROG ()) /* Don't wait if suspending from kbd_buffer_store_event! */
2135 SYS$CANCEL (fileno (CURTTY()->input));
2136 return;
2139 SYS$SETAST (0);
2140 /* Clear a flag, and tell ast routine above to set it. */
2141 SYS$CLREF (input_ef);
2142 waiting_for_ast = 1;
2143 stop_input = 1;
2144 SYS$CANCEL (fileno (CURTTY()->input));
2145 SYS$SETAST (1);
2146 SYS$WAITFR (input_ef);
2147 waiting_for_ast = 0;
2150 /* Wait for either input available or time interval expiry. */
2152 void
2153 input_wait_timeout (timeval)
2154 int timeval; /* Time to wait, in seconds */
2156 int time [2];
2157 static int zero = 0;
2158 static int large = -10000000;
2160 LIB$EMUL (&timeval, &large, &zero, time); /* Convert to VMS format */
2162 /* If already something, avoid doing system calls. */
2163 if (detect_input_pending ())
2165 return;
2167 /* Clear a flag, and tell ast routine above to set it. */
2168 SYS$CLREF (input_ef);
2169 waiting_for_ast = 1;
2170 /* Check for timing error: ast happened while we were doing that. */
2171 if (!detect_input_pending ())
2173 /* No timing error: wait for flag to be set. */
2174 SYS$CANTIM (1, 0);
2175 if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
2176 SYS$WFLOR (timer_ef, timer_eflist); /* Wait for timer expiry or input */
2178 waiting_for_ast = 0;
2181 /* The standard `sleep' routine works some other way
2182 and it stops working if you have ever quit out of it.
2183 This one continues to work. */
2185 sys_sleep (timeval)
2186 int timeval;
2188 int time [2];
2189 static int zero = 0;
2190 static int large = -10000000;
2192 LIB$EMUL (&timeval, &large, &zero, time); /* Convert to VMS format */
2194 SYS$CANTIM (1, 0);
2195 if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
2196 SYS$WAITFR (timer_ef); /* Wait for timer expiry only */
2199 void
2200 init_sigio (fd)
2201 int fd;
2203 request_sigio ();
2206 reset_sigio (fd)
2207 int fd;
2209 unrequest_sigio ();
2212 void
2213 request_sigio ()
2215 if (noninteractive)
2216 return;
2217 croak ("request sigio");
2220 void
2221 unrequest_sigio ()
2223 if (noninteractive)
2224 return;
2225 croak ("unrequest sigio");
2228 #endif /* VMS */
2230 /* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
2231 #ifndef CANNOT_DUMP
2232 #define NEED_STARTS
2233 #endif
2235 #ifndef SYSTEM_MALLOC
2236 #ifndef NEED_STARTS
2237 #define NEED_STARTS
2238 #endif
2239 #endif
2241 #ifdef NEED_STARTS
2242 /* Some systems that cannot dump also cannot implement these. */
2245 * Return the address of the start of the text segment prior to
2246 * doing an unexec. After unexec the return value is undefined.
2247 * See crt0.c for further explanation and _start.
2251 #if !(defined (__NetBSD__) && defined (__ELF__))
2252 #ifndef HAVE_TEXT_START
2253 char *
2254 start_of_text ()
2256 #ifdef TEXT_START
2257 return ((char *) TEXT_START);
2258 #else
2259 extern int _start ();
2260 return ((char *) _start);
2261 #endif /* TEXT_START */
2263 #endif /* not HAVE_TEXT_START */
2264 #endif
2267 * Return the address of the start of the data segment prior to
2268 * doing an unexec. After unexec the return value is undefined.
2269 * See crt0.c for further information and definition of data_start.
2271 * Apparently, on BSD systems this is etext at startup. On
2272 * USG systems (swapping) this is highly mmu dependent and
2273 * is also dependent on whether or not the program is running
2274 * with shared text. Generally there is a (possibly large)
2275 * gap between end of text and start of data with shared text.
2277 * On Uniplus+ systems with shared text, data starts at a
2278 * fixed address. Each port (from a given oem) is generally
2279 * different, and the specific value of the start of data can
2280 * be obtained via the UniPlus+ specific "uvar" system call,
2281 * however the method outlined in crt0.c seems to be more portable.
2283 * Probably what will have to happen when a USG unexec is available,
2284 * at least on UniPlus, is temacs will have to be made unshared so
2285 * that text and data are contiguous. Then once loadup is complete,
2286 * unexec will produce a shared executable where the data can be
2287 * at the normal shared text boundary and the startofdata variable
2288 * will be patched by unexec to the correct value.
2292 #ifndef start_of_data
2293 char *
2294 start_of_data ()
2296 #ifdef DATA_START
2297 return ((char *) DATA_START);
2298 #else
2299 #ifdef ORDINARY_LINK
2301 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
2302 * data_start isn't defined. We take the address of environ, which
2303 * is known to live at or near the start of the system crt0.c, and
2304 * we don't sweat the handful of bytes that might lose.
2306 extern char **environ;
2308 return ((char *) &environ);
2309 #else
2310 extern int data_start;
2311 return ((char *) &data_start);
2312 #endif /* ORDINARY_LINK */
2313 #endif /* DATA_START */
2315 #endif /* start_of_data */
2316 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
2318 /* init_system_name sets up the string for the Lisp function
2319 system-name to return. */
2321 #ifdef BSD4_1
2322 #include <whoami.h>
2323 #endif
2325 extern Lisp_Object Vsystem_name;
2327 #ifndef BSD4_1
2328 #ifndef VMS
2329 #ifdef HAVE_SOCKETS
2330 #include <sys/socket.h>
2331 #include <netdb.h>
2332 #endif /* HAVE_SOCKETS */
2333 #endif /* not VMS */
2334 #endif /* not BSD4_1 */
2336 #ifdef TRY_AGAIN
2337 #ifndef HAVE_H_ERRNO
2338 extern int h_errno;
2339 #endif
2340 #endif /* TRY_AGAIN */
2342 void
2343 init_system_name ()
2345 #ifdef BSD4_1
2346 Vsystem_name = build_string (sysname);
2347 #else
2348 #ifdef VMS
2349 char *sp, *end;
2350 if ((sp = egetenv ("SYS$NODE")) == 0)
2351 Vsystem_name = build_string ("vax-vms");
2352 else if ((end = index (sp, ':')) == 0)
2353 Vsystem_name = build_string (sp);
2354 else
2355 Vsystem_name = make_string (sp, end - sp);
2356 #else
2357 #ifndef HAVE_GETHOSTNAME
2358 struct utsname uts;
2359 uname (&uts);
2360 Vsystem_name = build_string (uts.nodename);
2361 #else /* HAVE_GETHOSTNAME */
2362 unsigned int hostname_size = 256;
2363 char *hostname = (char *) alloca (hostname_size);
2365 /* Try to get the host name; if the buffer is too short, try
2366 again. Apparently, the only indication gethostname gives of
2367 whether the buffer was large enough is the presence or absence
2368 of a '\0' in the string. Eech. */
2369 for (;;)
2371 gethostname (hostname, hostname_size - 1);
2372 hostname[hostname_size - 1] = '\0';
2374 /* Was the buffer large enough for the '\0'? */
2375 if (strlen (hostname) < hostname_size - 1)
2376 break;
2378 hostname_size <<= 1;
2379 hostname = (char *) alloca (hostname_size);
2381 #ifdef HAVE_SOCKETS
2382 /* Turn the hostname into the official, fully-qualified hostname.
2383 Don't do this if we're going to dump; this can confuse system
2384 libraries on some machines and make the dumped emacs core dump. */
2385 #ifndef CANNOT_DUMP
2386 if (initialized)
2387 #endif /* not CANNOT_DUMP */
2388 if (! index (hostname, '.'))
2390 int count;
2391 #ifdef HAVE_GETADDRINFO
2392 struct addrinfo *res;
2393 struct addrinfo hints;
2394 int ret;
2396 memset (&hints, 0, sizeof(hints));
2397 hints.ai_socktype = SOCK_STREAM;
2398 hints.ai_flags = AI_CANONNAME;
2400 for (count = 0;; count++)
2402 if ((ret = getaddrinfo (hostname, NULL, &hints, &res)) == 0
2403 || ret != EAI_AGAIN)
2404 break;
2406 if (count >= 5)
2407 break;
2408 Fsleep_for (make_number (1), Qnil);
2411 if (ret == 0)
2413 struct addrinfo *it = res;
2414 while (it)
2416 char *fqdn = it->ai_canonname;
2417 if (fqdn && index (fqdn, '.')
2418 && strcmp (fqdn, "localhost.localdomain") != 0)
2419 break;
2420 it = it->ai_next;
2422 if (it)
2424 hostname = alloca (strlen (it->ai_canonname) + 1);
2425 strcpy (hostname, it->ai_canonname);
2427 freeaddrinfo (res);
2429 #else /* !HAVE_GETADDRINFO */
2430 struct hostent *hp;
2431 for (count = 0;; count++)
2434 #ifdef TRY_AGAIN
2435 h_errno = 0;
2436 #endif
2437 hp = gethostbyname (hostname);
2438 #ifdef TRY_AGAIN
2439 if (! (hp == 0 && h_errno == TRY_AGAIN))
2440 #endif
2442 break;
2444 if (count >= 5)
2445 break;
2446 Fsleep_for (make_number (1), Qnil);
2449 if (hp)
2451 char *fqdn = (char *) hp->h_name;
2452 #if 0
2453 char *p;
2454 #endif
2456 if (!index (fqdn, '.'))
2458 /* We still don't have a fully qualified domain name.
2459 Try to find one in the list of alternate names */
2460 char **alias = hp->h_aliases;
2461 while (*alias
2462 && (!index (*alias, '.')
2463 || !strcmp (*alias, "localhost.localdomain")))
2464 alias++;
2465 if (*alias)
2466 fqdn = *alias;
2468 hostname = fqdn;
2469 #if 0
2470 /* Convert the host name to lower case. */
2471 /* Using ctype.h here would introduce a possible locale
2472 dependence that is probably wrong for hostnames. */
2473 p = hostname;
2474 while (*p)
2476 if (*p >= 'A' && *p <= 'Z')
2477 *p += 'a' - 'A';
2478 p++;
2480 #endif
2482 #endif /* !HAVE_GETADDRINFO */
2484 #endif /* HAVE_SOCKETS */
2485 /* We used to try using getdomainname here,
2486 but NIIBE Yutaka <gniibe@etl.go.jp> says that
2487 getdomainname gets the NIS/YP domain which often is not the same
2488 as in Internet domain name. */
2489 #if 0 /* Turned off because sysinfo is not really likely to return the
2490 correct Internet domain. */
2491 #if (HAVE_SYSINFO && defined (SI_SRPC_DOMAIN))
2492 if (! index (hostname, '.'))
2494 /* The hostname is not fully qualified. Append the domain name. */
2496 int hostlen = strlen (hostname);
2497 int domain_size = 256;
2499 for (;;)
2501 char *domain = (char *) alloca (domain_size + 1);
2502 char *fqdn = (char *) alloca (hostlen + 1 + domain_size + 1);
2503 int sys_domain_size = sysinfo (SI_SRPC_DOMAIN, domain, domain_size);
2504 if (sys_domain_size <= 0)
2505 break;
2506 if (domain_size < sys_domain_size)
2508 domain_size = sys_domain_size;
2509 continue;
2511 strcpy (fqdn, hostname);
2512 if (domain[0] == '.')
2513 strcpy (fqdn + hostlen, domain);
2514 else if (domain[0] != 0)
2516 fqdn[hostlen] = '.';
2517 strcpy (fqdn + hostlen + 1, domain);
2519 hostname = fqdn;
2520 break;
2523 #endif /* HAVE_SYSINFO && defined (SI_SRPC_DOMAIN) */
2524 #endif /* 0 */
2525 Vsystem_name = build_string (hostname);
2526 #endif /* HAVE_GETHOSTNAME */
2527 #endif /* VMS */
2528 #endif /* BSD4_1 */
2530 unsigned char *p;
2531 for (p = SDATA (Vsystem_name); *p; p++)
2532 if (*p == ' ' || *p == '\t')
2533 *p = '-';
2537 #ifndef MSDOS
2538 #ifndef VMS
2539 #if !defined (HAVE_SELECT)
2541 #include "sysselect.h"
2542 #undef select
2544 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
2545 /* Cause explanatory error message at compile time,
2546 since the select emulation is not good enough for X. */
2547 int *x = &x_windows_lose_if_no_select_system_call;
2548 #endif
2550 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
2551 * Only checks read descriptors.
2553 /* How long to wait between checking fds in select */
2554 #define SELECT_PAUSE 1
2555 int select_alarmed;
2557 /* For longjmp'ing back to read_input_waiting. */
2559 jmp_buf read_alarm_throw;
2561 /* Nonzero if the alarm signal should throw back to read_input_waiting.
2562 The read_socket_hook function sets this to 1 while it is waiting. */
2564 int read_alarm_should_throw;
2566 SIGTYPE
2567 select_alarm ()
2569 select_alarmed = 1;
2570 #ifdef BSD4_1
2571 sigrelse (SIGALRM);
2572 #else /* not BSD4_1 */
2573 signal (SIGALRM, SIG_IGN);
2574 #endif /* not BSD4_1 */
2575 SIGNAL_THREAD_CHECK (SIGALRM);
2576 if (read_alarm_should_throw)
2577 longjmp (read_alarm_throw, 1);
2580 #ifndef WINDOWSNT
2581 /* Only rfds are checked. */
2583 sys_select (nfds, rfds, wfds, efds, timeout)
2584 int nfds;
2585 SELECT_TYPE *rfds, *wfds, *efds;
2586 EMACS_TIME *timeout;
2588 /* XXX This needs to be updated for multi-tty support. Is there
2589 anybody who needs to emulate select these days? */
2590 int ravail = 0;
2591 SELECT_TYPE orfds;
2592 int timeoutval;
2593 int *local_timeout;
2594 extern int proc_buffered_char[];
2595 #ifndef subprocesses
2596 int process_tick = 0, update_tick = 0;
2597 #else
2598 extern int process_tick, update_tick;
2599 #endif
2600 unsigned char buf;
2602 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
2603 /* If we're using X, then the native select will work; we only need the
2604 emulation for non-X usage. */
2605 if (!NILP (Vinitial_window_system))
2606 return select (nfds, rfds, wfds, efds, timeout);
2607 #endif
2608 timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
2609 local_timeout = &timeoutval;
2610 FD_ZERO (&orfds);
2611 if (rfds)
2613 orfds = *rfds;
2614 FD_ZERO (rfds);
2616 if (wfds)
2617 FD_ZERO (wfds);
2618 if (efds)
2619 FD_ZERO (efds);
2621 /* If we are looking only for the terminal, with no timeout,
2622 just read it and wait -- that's more efficient. */
2623 if (*local_timeout == 100000 && process_tick == update_tick
2624 && FD_ISSET (0, &orfds))
2626 int fd;
2627 for (fd = 1; fd < nfds; ++fd)
2628 if (FD_ISSET (fd, &orfds))
2629 goto hardway;
2630 if (! detect_input_pending ())
2631 read_input_waiting ();
2632 FD_SET (0, rfds);
2633 return 1;
2636 hardway:
2637 /* Once a second, till the timer expires, check all the flagged read
2638 * descriptors to see if any input is available. If there is some then
2639 * set the corresponding bit in the return copy of rfds.
2641 while (1)
2643 register int to_check, fd;
2645 if (rfds)
2647 for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
2649 if (FD_ISSET (fd, &orfds))
2651 int avail = 0, status = 0;
2653 if (fd == 0)
2654 avail = detect_input_pending (); /* Special keyboard handler */
2655 else
2657 #ifdef FIONREAD
2658 status = ioctl (fd, FIONREAD, &avail);
2659 #else /* no FIONREAD */
2660 /* Hoping it will return -1 if nothing available
2661 or 0 if all 0 chars requested are read. */
2662 if (proc_buffered_char[fd] >= 0)
2663 avail = 1;
2664 else
2666 avail = read (fd, &buf, 1);
2667 if (avail > 0)
2668 proc_buffered_char[fd] = buf;
2670 #endif /* no FIONREAD */
2672 if (status >= 0 && avail > 0)
2674 FD_SET (fd, rfds);
2675 ravail++;
2680 if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
2681 break;
2683 turn_on_atimers (0);
2684 signal (SIGALRM, select_alarm);
2685 select_alarmed = 0;
2686 alarm (SELECT_PAUSE);
2688 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2689 while (select_alarmed == 0 && *local_timeout != 0
2690 && process_tick == update_tick)
2692 /* If we are interested in terminal input,
2693 wait by reading the terminal.
2694 That makes instant wakeup for terminal input at least. */
2695 if (FD_ISSET (0, &orfds))
2697 read_input_waiting ();
2698 if (detect_input_pending ())
2699 select_alarmed = 1;
2701 else
2702 pause ();
2704 (*local_timeout) -= SELECT_PAUSE;
2706 /* Reset the old alarm if there was one. */
2707 turn_on_atimers (1);
2709 if (*local_timeout == 0) /* Stop on timer being cleared */
2710 break;
2712 return ravail;
2714 #endif /* not WINDOWSNT */
2716 /* Read keyboard input into the standard buffer,
2717 waiting for at least one character. */
2719 void
2720 read_input_waiting ()
2722 /* XXX This needs to be updated for multi-tty support. Is there
2723 anybody who needs to emulate select these days? */
2724 int nread, i;
2725 extern int quit_char;
2727 if (read_socket_hook)
2729 struct input_event hold_quit;
2731 EVENT_INIT (hold_quit);
2732 hold_quit.kind = NO_EVENT;
2734 read_alarm_should_throw = 0;
2735 if (! setjmp (read_alarm_throw))
2736 nread = (*read_socket_hook) (0, 1, &hold_quit);
2737 else
2738 nread = -1;
2740 if (hold_quit.kind != NO_EVENT)
2741 kbd_buffer_store_event (&hold_quit);
2743 else
2745 struct input_event e;
2746 char buf[3];
2747 nread = read (fileno (stdin), buf, 1);
2748 EVENT_INIT (e);
2750 /* Scan the chars for C-g and store them in kbd_buffer. */
2751 e.kind = ASCII_KEYSTROKE_EVENT;
2752 e.frame_or_window = selected_frame;
2753 e.modifiers = 0;
2754 for (i = 0; i < nread; i++)
2756 /* Convert chars > 0177 to meta events if desired.
2757 We do this under the same conditions that read_avail_input does. */
2758 if (read_socket_hook == 0)
2760 /* If the user says she has a meta key, then believe her. */
2761 if (meta_key == 1 && (buf[i] & 0x80))
2762 e.modifiers = meta_modifier;
2763 if (meta_key != 2)
2764 buf[i] &= ~0x80;
2767 XSETINT (e.code, buf[i]);
2768 kbd_buffer_store_event (&e);
2769 /* Don't look at input that follows a C-g too closely.
2770 This reduces lossage due to autorepeat on C-g. */
2771 if (buf[i] == quit_char)
2772 break;
2777 #if !defined (HAVE_SELECT)
2778 #define select sys_select
2779 #endif
2781 #endif /* not HAVE_SELECT */
2782 #endif /* not VMS */
2783 #endif /* not MSDOS */
2785 #ifdef BSD4_1
2786 void
2787 init_sigio (fd)
2788 int fd;
2790 if (noninteractive)
2791 return;
2792 lmode = LINTRUP | lmode;
2793 ioctl (fd, TIOCLSET, &lmode);
2796 void
2797 reset_sigio (fd)
2798 int fd;
2800 if (noninteractive)
2801 return;
2802 lmode = ~LINTRUP & lmode;
2803 ioctl (fd, TIOCLSET, &lmode);
2806 void
2807 request_sigio ()
2809 if (noninteractive)
2810 return;
2811 sigrelse (SIGTINT);
2813 interrupts_deferred = 0;
2816 void
2817 unrequest_sigio ()
2819 if (noninteractive)
2820 return;
2821 sighold (SIGTINT);
2823 interrupts_deferred = 1;
2826 /* still inside #ifdef BSD4_1 */
2827 #ifdef subprocesses
2829 int sigheld; /* Mask of held signals */
2831 void
2832 sigholdx (signum)
2833 int signum;
2835 sigheld |= sigbit (signum);
2836 sighold (signum);
2839 void
2840 sigisheld (signum)
2841 int signum;
2843 sigheld |= sigbit (signum);
2846 void
2847 sigunhold (signum)
2848 int signum;
2850 sigheld &= ~sigbit (signum);
2851 sigrelse (signum);
2854 void
2855 sigfree () /* Free all held signals */
2857 int i;
2858 for (i = 0; i < NSIG; i++)
2859 if (sigheld & sigbit (i))
2860 sigrelse (i);
2861 sigheld = 0;
2865 sigbit (i)
2867 return 1 << (i - 1);
2869 #endif /* subprocesses */
2870 #endif /* BSD4_1 */
2872 /* POSIX signals support - DJB */
2873 /* Anyone with POSIX signals should have ANSI C declarations */
2875 #ifdef POSIX_SIGNALS
2877 sigset_t empty_mask, full_mask;
2879 signal_handler_t
2880 sys_signal (int signal_number, signal_handler_t action)
2882 struct sigaction new_action, old_action;
2883 sigemptyset (&new_action.sa_mask);
2884 new_action.sa_handler = action;
2885 #if defined (SA_RESTART) && ! defined (BROKEN_SA_RESTART) && !defined(SYNC_INPUT)
2886 /* Emacs mostly works better with restartable system services. If this
2887 flag exists, we probably want to turn it on here.
2888 However, on some systems this resets the timeout of `select'
2889 which means that `select' never finishes if it keeps getting signals.
2890 BROKEN_SA_RESTART is defined on those systems. */
2891 /* It's not clear why the comment above says "mostly works better". --Stef
2892 When SYNC_INPUT is set, we don't want SA_RESTART because we need to poll
2893 for pending input so we need long-running syscalls to be interrupted
2894 after a signal that sets the interrupt_input_pending flag. */
2895 new_action.sa_flags = SA_RESTART;
2896 #else
2897 new_action.sa_flags = 0;
2898 #endif
2899 sigaction (signal_number, &new_action, &old_action);
2900 return (old_action.sa_handler);
2903 #ifndef __GNUC__
2904 /* If we're compiling with GCC, we don't need this function, since it
2905 can be written as a macro. */
2906 sigset_t
2907 sys_sigmask (int sig)
2909 sigset_t mask;
2910 sigemptyset (&mask);
2911 sigaddset (&mask, sig);
2912 return mask;
2914 #endif
2916 /* I'd like to have these guys return pointers to the mask storage in here,
2917 but there'd be trouble if the code was saving multiple masks. I'll be
2918 safe and pass the structure. It normally won't be more than 2 bytes
2919 anyhow. - DJB */
2921 sigset_t
2922 sys_sigblock (sigset_t new_mask)
2924 sigset_t old_mask;
2925 sigprocmask (SIG_BLOCK, &new_mask, &old_mask);
2926 return (old_mask);
2929 sigset_t
2930 sys_sigunblock (sigset_t new_mask)
2932 sigset_t old_mask;
2933 sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask);
2934 return (old_mask);
2937 sigset_t
2938 sys_sigsetmask (sigset_t new_mask)
2940 sigset_t old_mask;
2941 sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
2942 return (old_mask);
2945 #endif /* POSIX_SIGNALS */
2947 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2948 static char *my_sys_siglist[NSIG];
2949 # ifdef sys_siglist
2950 # undef sys_siglist
2951 # endif
2952 # define sys_siglist my_sys_siglist
2953 #endif
2955 void
2956 init_signals ()
2958 #ifdef POSIX_SIGNALS
2959 sigemptyset (&empty_mask);
2960 sigfillset (&full_mask);
2961 #endif
2963 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2964 if (! initialized)
2966 # ifdef SIGABRT
2967 sys_siglist[SIGABRT] = "Aborted";
2968 # endif
2969 # ifdef SIGAIO
2970 sys_siglist[SIGAIO] = "LAN I/O interrupt";
2971 # endif
2972 # ifdef SIGALRM
2973 sys_siglist[SIGALRM] = "Alarm clock";
2974 # endif
2975 # ifdef SIGBUS
2976 sys_siglist[SIGBUS] = "Bus error";
2977 # endif
2978 # ifdef SIGCLD
2979 sys_siglist[SIGCLD] = "Child status changed";
2980 # endif
2981 # ifdef SIGCHLD
2982 sys_siglist[SIGCHLD] = "Child status changed";
2983 # endif
2984 # ifdef SIGCONT
2985 sys_siglist[SIGCONT] = "Continued";
2986 # endif
2987 # ifdef SIGDANGER
2988 sys_siglist[SIGDANGER] = "Swap space dangerously low";
2989 # endif
2990 # ifdef SIGDGNOTIFY
2991 sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
2992 # endif
2993 # ifdef SIGEMT
2994 sys_siglist[SIGEMT] = "Emulation trap";
2995 # endif
2996 # ifdef SIGFPE
2997 sys_siglist[SIGFPE] = "Arithmetic exception";
2998 # endif
2999 # ifdef SIGFREEZE
3000 sys_siglist[SIGFREEZE] = "SIGFREEZE";
3001 # endif
3002 # ifdef SIGGRANT
3003 sys_siglist[SIGGRANT] = "Monitor mode granted";
3004 # endif
3005 # ifdef SIGHUP
3006 sys_siglist[SIGHUP] = "Hangup";
3007 # endif
3008 # ifdef SIGILL
3009 sys_siglist[SIGILL] = "Illegal instruction";
3010 # endif
3011 # ifdef SIGINT
3012 sys_siglist[SIGINT] = "Interrupt";
3013 # endif
3014 # ifdef SIGIO
3015 sys_siglist[SIGIO] = "I/O possible";
3016 # endif
3017 # ifdef SIGIOINT
3018 sys_siglist[SIGIOINT] = "I/O intervention required";
3019 # endif
3020 # ifdef SIGIOT
3021 sys_siglist[SIGIOT] = "IOT trap";
3022 # endif
3023 # ifdef SIGKILL
3024 sys_siglist[SIGKILL] = "Killed";
3025 # endif
3026 # ifdef SIGLOST
3027 sys_siglist[SIGLOST] = "Resource lost";
3028 # endif
3029 # ifdef SIGLWP
3030 sys_siglist[SIGLWP] = "SIGLWP";
3031 # endif
3032 # ifdef SIGMSG
3033 sys_siglist[SIGMSG] = "Monitor mode data available";
3034 # endif
3035 # ifdef SIGPHONE
3036 sys_siglist[SIGWIND] = "SIGPHONE";
3037 # endif
3038 # ifdef SIGPIPE
3039 sys_siglist[SIGPIPE] = "Broken pipe";
3040 # endif
3041 # ifdef SIGPOLL
3042 sys_siglist[SIGPOLL] = "Pollable event occurred";
3043 # endif
3044 # ifdef SIGPROF
3045 sys_siglist[SIGPROF] = "Profiling timer expired";
3046 # endif
3047 # ifdef SIGPTY
3048 sys_siglist[SIGPTY] = "PTY I/O interrupt";
3049 # endif
3050 # ifdef SIGPWR
3051 sys_siglist[SIGPWR] = "Power-fail restart";
3052 # endif
3053 # ifdef SIGQUIT
3054 sys_siglist[SIGQUIT] = "Quit";
3055 # endif
3056 # ifdef SIGRETRACT
3057 sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode";
3058 # endif
3059 # ifdef SIGSAK
3060 sys_siglist[SIGSAK] = "Secure attention";
3061 # endif
3062 # ifdef SIGSEGV
3063 sys_siglist[SIGSEGV] = "Segmentation violation";
3064 # endif
3065 # ifdef SIGSOUND
3066 sys_siglist[SIGSOUND] = "Sound completed";
3067 # endif
3068 # ifdef SIGSTOP
3069 sys_siglist[SIGSTOP] = "Stopped (signal)";
3070 # endif
3071 # ifdef SIGSTP
3072 sys_siglist[SIGSTP] = "Stopped (user)";
3073 # endif
3074 # ifdef SIGSYS
3075 sys_siglist[SIGSYS] = "Bad argument to system call";
3076 # endif
3077 # ifdef SIGTERM
3078 sys_siglist[SIGTERM] = "Terminated";
3079 # endif
3080 # ifdef SIGTHAW
3081 sys_siglist[SIGTHAW] = "SIGTHAW";
3082 # endif
3083 # ifdef SIGTRAP
3084 sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
3085 # endif
3086 # ifdef SIGTSTP
3087 sys_siglist[SIGTSTP] = "Stopped (user)";
3088 # endif
3089 # ifdef SIGTTIN
3090 sys_siglist[SIGTTIN] = "Stopped (tty input)";
3091 # endif
3092 # ifdef SIGTTOU
3093 sys_siglist[SIGTTOU] = "Stopped (tty output)";
3094 # endif
3095 # ifdef SIGURG
3096 sys_siglist[SIGURG] = "Urgent I/O condition";
3097 # endif
3098 # ifdef SIGUSR1
3099 sys_siglist[SIGUSR1] = "User defined signal 1";
3100 # endif
3101 # ifdef SIGUSR2
3102 sys_siglist[SIGUSR2] = "User defined signal 2";
3103 # endif
3104 # ifdef SIGVTALRM
3105 sys_siglist[SIGVTALRM] = "Virtual timer expired";
3106 # endif
3107 # ifdef SIGWAITING
3108 sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
3109 # endif
3110 # ifdef SIGWINCH
3111 sys_siglist[SIGWINCH] = "Window size changed";
3112 # endif
3113 # ifdef SIGWIND
3114 sys_siglist[SIGWIND] = "SIGWIND";
3115 # endif
3116 # ifdef SIGXCPU
3117 sys_siglist[SIGXCPU] = "CPU time limit exceeded";
3118 # endif
3119 # ifdef SIGXFSZ
3120 sys_siglist[SIGXFSZ] = "File size limit exceeded";
3121 # endif
3123 #endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
3126 #ifndef HAVE_RANDOM
3127 #ifdef random
3128 #define HAVE_RANDOM
3129 #endif
3130 #endif
3132 /* Figure out how many bits the system's random number generator uses.
3133 `random' and `lrand48' are assumed to return 31 usable bits.
3134 BSD `rand' returns a 31 bit value but the low order bits are unusable;
3135 so we'll shift it and treat it like the 15-bit USG `rand'. */
3137 #ifndef RAND_BITS
3138 # ifdef HAVE_RANDOM
3139 # define RAND_BITS 31
3140 # else /* !HAVE_RANDOM */
3141 # ifdef HAVE_LRAND48
3142 # define RAND_BITS 31
3143 # define random lrand48
3144 # else /* !HAVE_LRAND48 */
3145 # define RAND_BITS 15
3146 # if RAND_MAX == 32767
3147 # define random rand
3148 # else /* RAND_MAX != 32767 */
3149 # if RAND_MAX == 2147483647
3150 # define random() (rand () >> 16)
3151 # else /* RAND_MAX != 2147483647 */
3152 # ifdef USG
3153 # define random rand
3154 # else
3155 # define random() (rand () >> 16)
3156 # endif /* !USG */
3157 # endif /* RAND_MAX != 2147483647 */
3158 # endif /* RAND_MAX != 32767 */
3159 # endif /* !HAVE_LRAND48 */
3160 # endif /* !HAVE_RANDOM */
3161 #endif /* !RAND_BITS */
3163 void
3164 seed_random (arg)
3165 long arg;
3167 #ifdef HAVE_RANDOM
3168 srandom ((unsigned int)arg);
3169 #else
3170 # ifdef HAVE_LRAND48
3171 srand48 (arg);
3172 # else
3173 srand ((unsigned int)arg);
3174 # endif
3175 #endif
3179 * Build a full Emacs-sized word out of whatever we've got.
3180 * This suffices even for a 64-bit architecture with a 15-bit rand.
3182 long
3183 get_random ()
3185 long val = random ();
3186 #if VALBITS > RAND_BITS
3187 val = (val << RAND_BITS) ^ random ();
3188 #if VALBITS > 2*RAND_BITS
3189 val = (val << RAND_BITS) ^ random ();
3190 #if VALBITS > 3*RAND_BITS
3191 val = (val << RAND_BITS) ^ random ();
3192 #if VALBITS > 4*RAND_BITS
3193 val = (val << RAND_BITS) ^ random ();
3194 #endif /* need at least 5 */
3195 #endif /* need at least 4 */
3196 #endif /* need at least 3 */
3197 #endif /* need at least 2 */
3198 return val & ((1L << VALBITS) - 1);
3201 #ifdef VMS
3203 #ifdef getenv
3204 /* If any place else asks for the TERM variable,
3205 allow it to be overridden with the EMACS_TERM variable
3206 before attempting to translate the logical name TERM. As a last
3207 resort, ask for VAX C's special idea of the TERM variable. */
3208 #undef getenv
3209 char *
3210 sys_getenv (name)
3211 char *name;
3213 register char *val;
3214 static char buf[256];
3215 static struct dsc$descriptor_s equiv
3216 = {sizeof (buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf};
3217 static struct dsc$descriptor_s d_name
3218 = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
3219 short eqlen;
3221 if (!strcmp (name, "TERM"))
3223 val = (char *) getenv ("EMACS_TERM");
3224 if (val)
3225 return val;
3228 d_name.dsc$w_length = strlen (name);
3229 d_name.dsc$a_pointer = name;
3230 if (LIB$SYS_TRNLOG (&d_name, &eqlen, &equiv) == 1)
3232 char *str = (char *) xmalloc (eqlen + 1);
3233 bcopy (buf, str, eqlen);
3234 str[eqlen] = '\0';
3235 /* This is a storage leak, but a pain to fix. With luck,
3236 no one will ever notice. */
3237 return str;
3239 return (char *) getenv (name);
3241 #endif /* getenv */
3243 #ifdef abort
3244 /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
3245 to force a call on the debugger from within the image. */
3246 #undef abort
3247 sys_abort ()
3249 reset_all_sys_modes ();
3250 LIB$SIGNAL (SS$_DEBUG);
3252 #endif /* abort */
3253 #endif /* VMS */
3255 #ifdef VMS
3256 #ifdef LINK_CRTL_SHARE
3257 #ifdef SHARABLE_LIB_BUG
3258 /* Variables declared noshare and initialized in sharable libraries
3259 cannot be shared. The VMS linker incorrectly forces you to use a private
3260 version which is uninitialized... If not for this "feature", we
3261 could use the C library definition of sys_nerr and sys_errlist. */
3262 int sys_nerr = 35;
3263 char *sys_errlist[] =
3265 "error 0",
3266 "not owner",
3267 "no such file or directory",
3268 "no such process",
3269 "interrupted system call",
3270 "i/o error",
3271 "no such device or address",
3272 "argument list too long",
3273 "exec format error",
3274 "bad file number",
3275 "no child process",
3276 "no more processes",
3277 "not enough memory",
3278 "permission denied",
3279 "bad address",
3280 "block device required",
3281 "mount devices busy",
3282 "file exists",
3283 "cross-device link",
3284 "no such device",
3285 "not a directory",
3286 "is a directory",
3287 "invalid argument",
3288 "file table overflow",
3289 "too many open files",
3290 "not a typewriter",
3291 "text file busy",
3292 "file too big",
3293 "no space left on device",
3294 "illegal seek",
3295 "read-only file system",
3296 "too many links",
3297 "broken pipe",
3298 "math argument",
3299 "result too large",
3300 "I/O stream empty",
3301 "vax/vms specific error code nontranslatable error"
3303 #endif /* SHARABLE_LIB_BUG */
3304 #endif /* LINK_CRTL_SHARE */
3305 #endif /* VMS */
3307 #ifndef HAVE_STRERROR
3308 #ifndef WINDOWSNT
3309 char *
3310 strerror (errnum)
3311 int errnum;
3313 extern char *sys_errlist[];
3314 extern int sys_nerr;
3316 if (errnum >= 0 && errnum < sys_nerr)
3317 return sys_errlist[errnum];
3318 return (char *) "Unknown error";
3320 #endif /* not WINDOWSNT */
3321 #endif /* ! HAVE_STRERROR */
3324 emacs_open (path, oflag, mode)
3325 const char *path;
3326 int oflag, mode;
3328 register int rtnval;
3330 #ifdef BSD4_1
3331 if (oflag & O_CREAT)
3332 return creat (path, mode);
3333 #endif
3335 while ((rtnval = open (path, oflag, mode)) == -1
3336 && (errno == EINTR))
3337 QUIT;
3338 return (rtnval);
3342 emacs_close (fd)
3343 int fd;
3345 int did_retry = 0;
3346 register int rtnval;
3348 #if defined (MAC_OSX) && defined (HAVE_CARBON)
3350 extern int mac_try_close_socket P_ ((int));
3352 if (mac_try_close_socket (fd))
3353 return 0;
3355 #endif
3357 while ((rtnval = close (fd)) == -1
3358 && (errno == EINTR))
3359 did_retry = 1;
3361 /* If close is interrupted SunOS 4.1 may or may not have closed the
3362 file descriptor. If it did the second close will fail with
3363 errno = EBADF. That means we have succeeded. */
3364 if (rtnval == -1 && did_retry && errno == EBADF)
3365 return 0;
3367 return rtnval;
3371 emacs_read (fildes, buf, nbyte)
3372 int fildes;
3373 char *buf;
3374 unsigned int nbyte;
3376 register int rtnval;
3378 while ((rtnval = read (fildes, buf, nbyte)) == -1
3379 && (errno == EINTR))
3380 QUIT;
3381 return (rtnval);
3385 emacs_write (fildes, buf, nbyte)
3386 int fildes;
3387 const char *buf;
3388 unsigned int nbyte;
3390 register int rtnval, bytes_written;
3392 bytes_written = 0;
3394 while (nbyte > 0)
3396 rtnval = write (fildes, buf, nbyte);
3398 if (rtnval == -1)
3400 if (errno == EINTR)
3402 #ifdef SYNC_INPUT
3403 /* I originally used `QUIT' but that might causes files to
3404 be truncated if you hit C-g in the middle of it. --Stef */
3405 if (interrupt_input_pending)
3406 handle_async_input ();
3407 if (pending_atimers)
3408 do_pending_atimers ();
3409 #endif
3410 continue;
3412 else
3413 return (bytes_written ? bytes_written : -1);
3416 buf += rtnval;
3417 nbyte -= rtnval;
3418 bytes_written += rtnval;
3420 return (bytes_written);
3423 #ifdef USG
3425 * All of the following are for USG.
3427 * On USG systems the system calls are INTERRUPTIBLE by signals
3428 * that the user program has elected to catch. Thus the system call
3429 * must be retried in these cases. To handle this without massive
3430 * changes in the source code, we remap the standard system call names
3431 * to names for our own functions in sysdep.c that do the system call
3432 * with retries. Actually, for portability reasons, it is good
3433 * programming practice, as this example shows, to limit all actual
3434 * system calls to a single occurrence in the source. Sure, this
3435 * adds an extra level of function call overhead but it is almost
3436 * always negligible. Fred Fish, Unisoft Systems Inc.
3440 * Warning, this function may not duplicate 4.2 action properly
3441 * under error conditions.
3444 #ifndef MAXPATHLEN
3445 /* In 4.1, param.h fails to define this. */
3446 #define MAXPATHLEN 1024
3447 #endif
3449 #ifndef HAVE_GETWD
3451 char *
3452 getwd (pathname)
3453 char *pathname;
3455 char *npath, *spath;
3456 extern char *getcwd ();
3458 BLOCK_INPUT; /* getcwd uses malloc */
3459 spath = npath = getcwd ((char *) 0, MAXPATHLEN);
3460 if (spath == 0)
3462 UNBLOCK_INPUT;
3463 return spath;
3465 /* On Altos 3068, getcwd can return @hostname/dir, so discard
3466 up to first slash. Should be harmless on other systems. */
3467 while (*npath && *npath != '/')
3468 npath++;
3469 strcpy (pathname, npath);
3470 free (spath); /* getcwd uses malloc */
3471 UNBLOCK_INPUT;
3472 return pathname;
3475 #endif /* HAVE_GETWD */
3478 * Emulate rename using unlink/link. Note that this is
3479 * only partially correct. Also, doesn't enforce restriction
3480 * that files be of same type (regular->regular, dir->dir, etc).
3483 #ifndef HAVE_RENAME
3485 rename (from, to)
3486 const char *from;
3487 const char *to;
3489 if (access (from, 0) == 0)
3491 unlink (to);
3492 if (link (from, to) == 0)
3493 if (unlink (from) == 0)
3494 return (0);
3496 return (-1);
3499 #endif
3502 #ifdef HPUX
3503 #ifndef HAVE_PERROR
3505 /* HPUX curses library references perror, but as far as we know
3506 it won't be called. Anyway this definition will do for now. */
3508 perror ()
3512 #endif /* not HAVE_PERROR */
3513 #endif /* HPUX */
3515 #ifndef HAVE_DUP2
3518 * Emulate BSD dup2. First close newd if it already exists.
3519 * Then, attempt to dup oldd. If not successful, call dup2 recursively
3520 * until we are, then close the unsuccessful ones.
3523 dup2 (oldd, newd)
3524 int oldd;
3525 int newd;
3527 register int fd, ret;
3529 emacs_close (newd);
3531 #ifdef F_DUPFD
3532 return fcntl (oldd, F_DUPFD, newd);
3533 #else
3534 fd = dup (old);
3535 if (fd == -1)
3536 return -1;
3537 if (fd == new)
3538 return new;
3539 ret = dup2 (old,new);
3540 emacs_close (fd);
3541 return ret;
3542 #endif
3545 #endif /* not HAVE_DUP2 */
3548 * Gettimeofday. Simulate as much as possible. Only accurate
3549 * to nearest second. Emacs doesn't use tzp so ignore it for now.
3550 * Only needed when subprocesses are defined.
3553 #ifdef subprocesses
3554 #ifndef VMS
3555 #ifndef HAVE_GETTIMEOFDAY
3556 #ifdef HAVE_TIMEVAL
3558 /* ARGSUSED */
3560 gettimeofday (tp, tzp)
3561 struct timeval *tp;
3562 struct timezone *tzp;
3564 extern long time ();
3566 tp->tv_sec = time ((long *)0);
3567 tp->tv_usec = 0;
3568 if (tzp != 0)
3569 tzp->tz_minuteswest = -1;
3570 return 0;
3573 #endif
3574 #endif
3575 #endif
3576 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL && !VMS */
3579 * This function will go away as soon as all the stubs fixed. (fnf)
3582 void
3583 croak (badfunc)
3584 char *badfunc;
3586 printf ("%s not yet implemented\r\n", badfunc);
3587 reset_all_sys_modes ();
3588 exit (1);
3591 #endif /* USG */
3593 /* Directory routines for systems that don't have them. */
3595 #ifdef SYSV_SYSTEM_DIR
3597 #include <dirent.h>
3599 #if defined (BROKEN_CLOSEDIR) || !defined (HAVE_CLOSEDIR)
3602 closedir (dirp)
3603 register DIR *dirp; /* stream from opendir */
3605 int rtnval;
3607 rtnval = emacs_close (dirp->dd_fd);
3609 /* Some systems (like Solaris) allocate the buffer and the DIR all
3610 in one block. Why in the world are we freeing this ourselves
3611 anyway? */
3612 #if ! (defined (sun) && defined (USG5_4))
3613 xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
3614 #endif
3615 xfree ((char *) dirp);
3617 return rtnval;
3619 #endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */
3620 #endif /* SYSV_SYSTEM_DIR */
3622 #ifdef NONSYSTEM_DIR_LIBRARY
3624 DIR *
3625 opendir (filename)
3626 char *filename; /* name of directory */
3628 register DIR *dirp; /* -> malloc'ed storage */
3629 register int fd; /* file descriptor for read */
3630 struct stat sbuf; /* result of fstat */
3632 fd = emacs_open (filename, O_RDONLY, 0);
3633 if (fd < 0)
3634 return 0;
3636 BLOCK_INPUT;
3637 if (fstat (fd, &sbuf) < 0
3638 || (sbuf.st_mode & S_IFMT) != S_IFDIR
3639 || (dirp = (DIR *) xmalloc (sizeof (DIR))) == 0)
3641 emacs_close (fd);
3642 UNBLOCK_INPUT;
3643 return 0; /* bad luck today */
3645 UNBLOCK_INPUT;
3647 dirp->dd_fd = fd;
3648 dirp->dd_loc = dirp->dd_size = 0; /* refill needed */
3650 return dirp;
3653 void
3654 closedir (dirp)
3655 register DIR *dirp; /* stream from opendir */
3657 emacs_close (dirp->dd_fd);
3658 xfree ((char *) dirp);
3662 #ifndef VMS
3663 #define DIRSIZ 14
3664 struct olddir
3666 ino_t od_ino; /* inode */
3667 char od_name[DIRSIZ]; /* filename */
3669 #endif /* not VMS */
3671 struct direct dir_static; /* simulated directory contents */
3673 /* ARGUSED */
3674 struct direct *
3675 readdir (dirp)
3676 register DIR *dirp; /* stream from opendir */
3678 #ifndef VMS
3679 register struct olddir *dp; /* -> directory data */
3680 #else /* VMS */
3681 register struct dir$_name *dp; /* -> directory data */
3682 register struct dir$_version *dv; /* -> version data */
3683 #endif /* VMS */
3685 for (; ;)
3687 if (dirp->dd_loc >= dirp->dd_size)
3688 dirp->dd_loc = dirp->dd_size = 0;
3690 if (dirp->dd_size == 0 /* refill buffer */
3691 && (dirp->dd_size = emacs_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3692 return 0;
3694 #ifndef VMS
3695 dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
3696 dirp->dd_loc += sizeof (struct olddir);
3698 if (dp->od_ino != 0) /* not deleted entry */
3700 dir_static.d_ino = dp->od_ino;
3701 strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
3702 dir_static.d_name[DIRSIZ] = '\0';
3703 dir_static.d_namlen = strlen (dir_static.d_name);
3704 dir_static.d_reclen = sizeof (struct direct)
3705 - MAXNAMLEN + 3
3706 + dir_static.d_namlen - dir_static.d_namlen % 4;
3707 return &dir_static; /* -> simulated structure */
3709 #else /* VMS */
3710 dp = (struct dir$_name *) dirp->dd_buf;
3711 if (dirp->dd_loc == 0)
3712 dirp->dd_loc = (dp->dir$b_namecount&1) ? dp->dir$b_namecount + 1
3713 : dp->dir$b_namecount;
3714 dv = (struct dir$_version *)&dp->dir$t_name[dirp->dd_loc];
3715 dir_static.d_ino = dv->dir$w_fid_num;
3716 dir_static.d_namlen = dp->dir$b_namecount;
3717 dir_static.d_reclen = sizeof (struct direct)
3718 - MAXNAMLEN + 3
3719 + dir_static.d_namlen - dir_static.d_namlen % 4;
3720 strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
3721 dir_static.d_name[dir_static.d_namlen] = '\0';
3722 dirp->dd_loc = dirp->dd_size; /* only one record at a time */
3723 return &dir_static;
3724 #endif /* VMS */
3728 #ifdef VMS
3729 /* readdirver is just like readdir except it returns all versions of a file
3730 as separate entries. */
3732 /* ARGUSED */
3733 struct direct *
3734 readdirver (dirp)
3735 register DIR *dirp; /* stream from opendir */
3737 register struct dir$_name *dp; /* -> directory data */
3738 register struct dir$_version *dv; /* -> version data */
3740 if (dirp->dd_loc >= dirp->dd_size - sizeof (struct dir$_name))
3741 dirp->dd_loc = dirp->dd_size = 0;
3743 if (dirp->dd_size == 0 /* refill buffer */
3744 && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
3745 return 0;
3747 dp = (struct dir$_name *) dirp->dd_buf;
3748 if (dirp->dd_loc == 0)
3749 dirp->dd_loc = (dp->dir$b_namecount & 1) ? dp->dir$b_namecount + 1
3750 : dp->dir$b_namecount;
3751 dv = (struct dir$_version *) &dp->dir$t_name[dirp->dd_loc];
3752 strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
3753 sprintf (&dir_static.d_name[dp->dir$b_namecount], ";%d", dv->dir$w_version);
3754 dir_static.d_namlen = strlen (dir_static.d_name);
3755 dir_static.d_ino = dv->dir$w_fid_num;
3756 dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3
3757 + dir_static.d_namlen - dir_static.d_namlen % 4;
3758 dirp->dd_loc = ((char *) (++dv) - dp->dir$t_name);
3759 return &dir_static;
3762 #endif /* VMS */
3764 #endif /* NONSYSTEM_DIR_LIBRARY */
3768 set_file_times (filename, atime, mtime)
3769 const char *filename;
3770 EMACS_TIME atime, mtime;
3772 #ifdef HAVE_UTIMES
3773 struct timeval tv[2];
3774 tv[0] = atime;
3775 tv[1] = mtime;
3776 return utimes (filename, tv);
3777 #else /* not HAVE_UTIMES */
3778 struct utimbuf utb;
3779 utb.actime = EMACS_SECS (atime);
3780 utb.modtime = EMACS_SECS (mtime);
3781 return utime (filename, &utb);
3782 #endif /* not HAVE_UTIMES */
3785 /* mkdir and rmdir functions, for systems which don't have them. */
3787 #ifndef HAVE_MKDIR
3789 * Written by Robert Rother, Mariah Corporation, August 1985.
3791 * If you want it, it's yours. All I ask in return is that if you
3792 * figure out how to do this in a Bourne Shell script you send me
3793 * a copy.
3794 * sdcsvax!rmr or rmr@uscd
3796 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
3797 * subroutine. 11Mar86; hoptoad!gnu
3799 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
3800 * subroutine didn't return EEXIST. It does now.
3804 * Make a directory.
3806 #ifdef MKDIR_PROTOTYPE
3807 MKDIR_PROTOTYPE
3808 #else
3810 mkdir (dpath, dmode)
3811 char *dpath;
3812 int dmode;
3813 #endif
3815 int cpid, status, fd;
3816 struct stat statbuf;
3818 if (stat (dpath, &statbuf) == 0)
3820 errno = EEXIST; /* Stat worked, so it already exists */
3821 return -1;
3824 /* If stat fails for a reason other than non-existence, return error */
3825 if (errno != ENOENT)
3826 return -1;
3828 synch_process_alive = 1;
3829 switch (cpid = fork ())
3832 case -1: /* Error in fork */
3833 return (-1); /* Errno is set already */
3835 case 0: /* Child process */
3837 * Cheap hack to set mode of new directory. Since this
3838 * child process is going away anyway, we zap its umask.
3839 * FIXME, this won't suffice to set SUID, SGID, etc. on this
3840 * directory. Does anybody care?
3842 status = umask (0); /* Get current umask */
3843 status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
3844 fd = emacs_open ("/dev/null", O_RDWR, 0);
3845 if (fd >= 0)
3847 dup2 (fd, 0);
3848 dup2 (fd, 1);
3849 dup2 (fd, 2);
3851 execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
3852 _exit (-1); /* Can't exec /bin/mkdir */
3854 default: /* Parent process */
3855 wait_for_termination (cpid);
3858 if (synch_process_death != 0 || synch_process_retcode != 0
3859 || synch_process_termsig != 0)
3861 errno = EIO; /* We don't know why, but */
3862 return -1; /* /bin/mkdir failed */
3865 return 0;
3867 #endif /* not HAVE_MKDIR */
3869 #ifndef HAVE_RMDIR
3871 rmdir (dpath)
3872 char *dpath;
3874 int cpid, status, fd;
3875 struct stat statbuf;
3877 if (stat (dpath, &statbuf) != 0)
3879 /* Stat just set errno. We don't have to */
3880 return -1;
3883 synch_process_alive = 1;
3884 switch (cpid = fork ())
3887 case -1: /* Error in fork */
3888 return (-1); /* Errno is set already */
3890 case 0: /* Child process */
3891 fd = emacs_open ("/dev/null", O_RDWR, 0);
3892 if (fd >= 0)
3894 dup2 (fd, 0);
3895 dup2 (fd, 1);
3896 dup2 (fd, 2);
3898 execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
3899 _exit (-1); /* Can't exec /bin/rmdir */
3901 default: /* Parent process */
3902 wait_for_termination (cpid);
3905 if (synch_process_death != 0 || synch_process_retcode != 0
3906 || synch_process_termsig != 0)
3908 errno = EIO; /* We don't know why, but */
3909 return -1; /* /bin/rmdir failed */
3912 return 0;
3914 #endif /* !HAVE_RMDIR */
3918 /* Functions for VMS */
3919 #ifdef VMS
3920 #include <acldef.h>
3921 #include <chpdef.h>
3922 #include <jpidef.h>
3924 /* Return as a string the VMS error string pertaining to STATUS.
3925 Reuses the same static buffer each time it is called. */
3927 char *
3928 vmserrstr (status)
3929 int status; /* VMS status code */
3931 int bufadr[2];
3932 short len;
3933 static char buf[257];
3935 bufadr[0] = sizeof buf - 1;
3936 bufadr[1] = (int) buf;
3937 if (! (SYS$GETMSG (status, &len, bufadr, 0x1, 0) & 1))
3938 return "untranslatable VMS error status";
3939 buf[len] = '\0';
3940 return buf;
3943 #ifdef access
3944 #undef access
3946 /* The following is necessary because 'access' emulation by VMS C (2.0) does
3947 * not work correctly. (It also doesn't work well in version 2.3.)
3950 #ifdef VMS4_4
3952 #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
3953 { strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
3955 typedef union {
3956 struct {
3957 unsigned short s_buflen;
3958 unsigned short s_code;
3959 char *s_bufadr;
3960 unsigned short *s_retlenadr;
3961 } s;
3962 int end;
3963 } item;
3964 #define buflen s.s_buflen
3965 #define code s.s_code
3966 #define bufadr s.s_bufadr
3967 #define retlenadr s.s_retlenadr
3969 #define R_OK 4 /* test for read permission */
3970 #define W_OK 2 /* test for write permission */
3971 #define X_OK 1 /* test for execute (search) permission */
3972 #define F_OK 0 /* test for presence of file */
3975 sys_access (path, mode)
3976 char *path;
3977 int mode;
3979 static char *user = NULL;
3980 char dir_fn[512];
3982 /* translate possible directory spec into .DIR file name, so brain-dead
3983 * access can treat the directory like a file. */
3984 if (directory_file_name (path, dir_fn))
3985 path = dir_fn;
3987 if (mode == F_OK)
3988 return access (path, mode);
3989 if (user == NULL && (user = (char *) getenv ("USER")) == NULL)
3990 return -1;
3992 int stat;
3993 int flags;
3994 int acces;
3995 unsigned short int dummy;
3996 item itemlst[3];
3997 static int constant = ACL$C_FILE;
3998 DESCRIPTOR (path_desc, path);
3999 DESCRIPTOR (user_desc, user);
4001 flags = 0;
4002 acces = 0;
4003 if ((mode & X_OK) && ((stat = access (path, mode)) < 0 || mode == X_OK))
4004 return stat;
4005 if (mode & R_OK)
4006 acces |= CHP$M_READ;
4007 if (mode & W_OK)
4008 acces |= CHP$M_WRITE;
4009 itemlst[0].buflen = sizeof (int);
4010 itemlst[0].code = CHP$_FLAGS;
4011 itemlst[0].bufadr = (char *) &flags;
4012 itemlst[0].retlenadr = &dummy;
4013 itemlst[1].buflen = sizeof (int);
4014 itemlst[1].code = CHP$_ACCESS;
4015 itemlst[1].bufadr = (char *) &acces;
4016 itemlst[1].retlenadr = &dummy;
4017 itemlst[2].end = CHP$_END;
4018 stat = SYS$CHECK_ACCESS (&constant, &path_desc, &user_desc, itemlst);
4019 return stat == SS$_NORMAL ? 0 : -1;
4023 #else /* not VMS4_4 */
4025 #include <prvdef.h>
4026 #define ACE$M_WRITE 2
4027 #define ACE$C_KEYID 1
4029 static unsigned short memid, grpid;
4030 static unsigned int uic;
4032 /* Called from init_sys_modes, so it happens not very often
4033 but at least each time Emacs is loaded. */
4034 void
4035 sys_access_reinit ()
4037 uic = 0;
4041 sys_access (filename, type)
4042 char * filename;
4043 int type;
4045 struct FAB fab;
4046 struct XABPRO xab;
4047 int status, size, i, typecode, acl_controlled;
4048 unsigned int *aclptr, *aclend, aclbuf[60];
4049 union prvdef prvmask;
4051 /* Get UIC and GRP values for protection checking. */
4052 if (uic == 0)
4054 status = LIB$GETJPI (&JPI$_UIC, 0, 0, &uic, 0, 0);
4055 if (! (status & 1))
4056 return -1;
4057 memid = uic & 0xFFFF;
4058 grpid = uic >> 16;
4061 if (type != 2) /* not checking write access */
4062 return access (filename, type);
4064 /* Check write protection. */
4066 #define CHECKPRIV(bit) (prvmask.bit)
4067 #define WRITABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
4069 /* Find privilege bits */
4070 status = SYS$SETPRV (0, 0, 0, prvmask);
4071 if (! (status & 1))
4072 error ("Unable to find privileges: %s", vmserrstr (status));
4073 if (CHECKPRIV (PRV$V_BYPASS))
4074 return 0; /* BYPASS enabled */
4075 fab = cc$rms_fab;
4076 fab.fab$b_fac = FAB$M_GET;
4077 fab.fab$l_fna = filename;
4078 fab.fab$b_fns = strlen (filename);
4079 fab.fab$l_xab = &xab;
4080 xab = cc$rms_xabpro;
4081 xab.xab$l_aclbuf = aclbuf;
4082 xab.xab$w_aclsiz = sizeof (aclbuf);
4083 status = SYS$OPEN (&fab, 0, 0);
4084 if (! (status & 1))
4085 return -1;
4086 SYS$CLOSE (&fab, 0, 0);
4087 /* Check system access */
4088 if (CHECKPRIV (PRV$V_SYSPRV) && WRITABLE (XAB$V_SYS))
4089 return 0;
4090 /* Check ACL entries, if any */
4091 acl_controlled = 0;
4092 if (xab.xab$w_acllen > 0)
4094 aclptr = aclbuf;
4095 aclend = &aclbuf[xab.xab$w_acllen / 4];
4096 while (*aclptr && aclptr < aclend)
4098 size = (*aclptr & 0xff) / 4;
4099 typecode = (*aclptr >> 8) & 0xff;
4100 if (typecode == ACE$C_KEYID)
4101 for (i = size - 1; i > 1; i--)
4102 if (aclptr[i] == uic)
4104 acl_controlled = 1;
4105 if (aclptr[1] & ACE$M_WRITE)
4106 return 0; /* Write access through ACL */
4108 aclptr = &aclptr[size];
4110 if (acl_controlled) /* ACL specified, prohibits write access */
4111 return -1;
4113 /* No ACL entries specified, check normal protection */
4114 if (WRITABLE (XAB$V_WLD)) /* World writable */
4115 return 0;
4116 if (WRITABLE (XAB$V_GRP) &&
4117 (unsigned short) (xab.xab$l_uic >> 16) == grpid)
4118 return 0; /* Group writable */
4119 if (WRITABLE (XAB$V_OWN) &&
4120 (xab.xab$l_uic & 0xFFFF) == memid)
4121 return 0; /* Owner writable */
4123 return -1; /* Not writable */
4125 #endif /* not VMS4_4 */
4126 #endif /* access */
4128 static char vtbuf[NAM$C_MAXRSS+1];
4130 /* translate a vms file spec to a unix path */
4131 char *
4132 sys_translate_vms (vfile)
4133 char * vfile;
4135 char * p;
4136 char * targ;
4138 if (!vfile)
4139 return 0;
4141 targ = vtbuf;
4143 /* leading device or logical name is a root directory */
4144 if (p = strchr (vfile, ':'))
4146 *targ++ = '/';
4147 while (vfile < p)
4148 *targ++ = *vfile++;
4149 vfile++;
4150 *targ++ = '/';
4152 p = vfile;
4153 if (*p == '[' || *p == '<')
4155 while (*++vfile != *p + 2)
4156 switch (*vfile)
4158 case '.':
4159 if (vfile[-1] == *p)
4160 *targ++ = '.';
4161 *targ++ = '/';
4162 break;
4164 case '-':
4165 *targ++ = '.';
4166 *targ++ = '.';
4167 break;
4169 default:
4170 *targ++ = *vfile;
4171 break;
4173 vfile++;
4174 *targ++ = '/';
4176 while (*vfile)
4177 *targ++ = *vfile++;
4179 return vtbuf;
4182 static char utbuf[NAM$C_MAXRSS+1];
4184 /* translate a unix path to a VMS file spec */
4185 char *
4186 sys_translate_unix (ufile)
4187 char * ufile;
4189 int slash_seen = 0;
4190 char *p;
4191 char * targ;
4193 if (!ufile)
4194 return 0;
4196 targ = utbuf;
4198 if (*ufile == '/')
4200 ufile++;
4203 while (*ufile)
4205 switch (*ufile)
4207 case '/':
4208 if (slash_seen)
4209 if (index (&ufile[1], '/'))
4210 *targ++ = '.';
4211 else
4212 *targ++ = ']';
4213 else
4215 *targ++ = ':';
4216 if (index (&ufile[1], '/'))
4217 *targ++ = '[';
4218 slash_seen = 1;
4220 break;
4222 case '.':
4223 if (strncmp (ufile, "./", 2) == 0)
4225 if (!slash_seen)
4227 *targ++ = '[';
4228 slash_seen = 1;
4230 ufile++; /* skip the dot */
4231 if (index (&ufile[1], '/'))
4232 *targ++ = '.';
4233 else
4234 *targ++ = ']';
4236 else if (strncmp (ufile, "../", 3) == 0)
4238 if (!slash_seen)
4240 *targ++ = '[';
4241 slash_seen = 1;
4243 *targ++ = '-';
4244 ufile += 2; /* skip the dots */
4245 if (index (&ufile[1], '/'))
4246 *targ++ = '.';
4247 else
4248 *targ++ = ']';
4250 else
4251 *targ++ = *ufile;
4252 break;
4254 default:
4255 *targ++ = *ufile;
4256 break;
4258 ufile++;
4260 *targ = '\0';
4262 return utbuf;
4265 char *
4266 getwd (pathname)
4267 char *pathname;
4269 char *ptr, *val;
4270 extern char *getcwd ();
4272 #define MAXPATHLEN 1024
4274 ptr = xmalloc (MAXPATHLEN);
4275 val = getcwd (ptr, MAXPATHLEN);
4276 if (val == 0)
4278 xfree (ptr);
4279 return val;
4281 strcpy (pathname, ptr);
4282 xfree (ptr);
4284 return pathname;
4288 getppid ()
4290 long item_code = JPI$_OWNER;
4291 unsigned long parent_id;
4292 int status;
4294 if (((status = LIB$GETJPI (&item_code, 0, 0, &parent_id)) & 1) == 0)
4296 errno = EVMSERR;
4297 vaxc$errno = status;
4298 return -1;
4300 return parent_id;
4303 #undef getuid
4304 unsigned
4305 sys_getuid ()
4307 return (getgid () << 16) | getuid ();
4310 #undef read
4312 sys_read (fildes, buf, nbyte)
4313 int fildes;
4314 char *buf;
4315 unsigned int nbyte;
4317 return read (fildes, buf, (nbyte < MAXIOSIZE ? nbyte : MAXIOSIZE));
4320 #if 0
4322 sys_write (fildes, buf, nbyte)
4323 int fildes;
4324 char *buf;
4325 unsigned int nbyte;
4327 register int nwrote, rtnval = 0;
4329 while (nbyte > MAXIOSIZE && (nwrote = write (fildes, buf, MAXIOSIZE)) > 0) {
4330 nbyte -= nwrote;
4331 buf += nwrote;
4332 rtnval += nwrote;
4334 if (nwrote < 0)
4335 return rtnval ? rtnval : -1;
4336 if ((nwrote = write (fildes, buf, nbyte)) < 0)
4337 return rtnval ? rtnval : -1;
4338 return (rtnval + nwrote);
4340 #endif /* 0 */
4343 * VAX/VMS VAX C RTL really loses. It insists that records
4344 * end with a newline (carriage return) character, and if they
4345 * don't it adds one (nice of it isn't it!)
4347 * Thus we do this stupidity below.
4350 #undef write
4352 sys_write (fildes, buf, nbytes)
4353 int fildes;
4354 char *buf;
4355 unsigned int nbytes;
4357 register char *p;
4358 register char *e;
4359 int sum = 0;
4360 struct stat st;
4362 fstat (fildes, &st);
4363 p = buf;
4364 while (nbytes > 0)
4366 int len, retval;
4368 /* Handle fixed-length files with carriage control. */
4369 if (st.st_fab_rfm == FAB$C_FIX
4370 && ((st.st_fab_rat & (FAB$M_FTN | FAB$M_CR)) != 0))
4372 len = st.st_fab_mrs;
4373 retval = write (fildes, p, min (len, nbytes));
4374 if (retval != len)
4375 return -1;
4376 retval++; /* This skips the implied carriage control */
4378 else
4380 e = p + min (MAXIOSIZE, nbytes) - 1;
4381 while (*e != '\n' && e > p) e--;
4382 if (p == e) /* Ok.. so here we add a newline... sigh. */
4383 e = p + min (MAXIOSIZE, nbytes) - 1;
4384 len = e + 1 - p;
4385 retval = write (fildes, p, len);
4386 if (retval != len)
4387 return -1;
4389 p += retval;
4390 sum += retval;
4391 nbytes -= retval;
4393 return sum;
4396 /* Create file NEW copying its attributes from file OLD. If
4397 OLD is 0 or does not exist, create based on the value of
4398 vms_stmlf_recfm. */
4400 /* Protection value the file should ultimately have.
4401 Set by create_copy_attrs, and use by rename_sansversions. */
4402 static unsigned short int fab_final_pro;
4405 creat_copy_attrs (old, new)
4406 char *old, *new;
4408 struct FAB fab = cc$rms_fab;
4409 struct XABPRO xabpro;
4410 char aclbuf[256]; /* Choice of size is arbitrary. See below. */
4411 extern int vms_stmlf_recfm;
4413 if (old)
4415 fab.fab$b_fac = FAB$M_GET;
4416 fab.fab$l_fna = old;
4417 fab.fab$b_fns = strlen (old);
4418 fab.fab$l_xab = (char *) &xabpro;
4419 xabpro = cc$rms_xabpro;
4420 xabpro.xab$l_aclbuf = aclbuf;
4421 xabpro.xab$w_aclsiz = sizeof aclbuf;
4422 /* Call $OPEN to fill in the fab & xabpro fields. */
4423 if (SYS$OPEN (&fab, 0, 0) & 1)
4425 SYS$CLOSE (&fab, 0, 0);
4426 fab.fab$l_alq = 0; /* zero the allocation quantity */
4427 if (xabpro.xab$w_acllen > 0)
4429 if (xabpro.xab$w_acllen > sizeof aclbuf)
4430 /* If the acl buffer was too short, redo open with longer one.
4431 Wouldn't need to do this if there were some system imposed
4432 limit on the size of an ACL, but I can't find any such. */
4434 xabpro.xab$l_aclbuf = (char *) alloca (xabpro.xab$w_acllen);
4435 xabpro.xab$w_aclsiz = xabpro.xab$w_acllen;
4436 if (SYS$OPEN (&fab, 0, 0) & 1)
4437 SYS$CLOSE (&fab, 0, 0);
4438 else
4439 old = 0;
4442 else
4443 xabpro.xab$l_aclbuf = 0;
4445 else
4446 old = 0;
4448 fab.fab$l_fna = new;
4449 fab.fab$b_fns = strlen (new);
4450 if (!old)
4452 fab.fab$l_xab = 0;
4453 fab.fab$b_rfm = vms_stmlf_recfm ? FAB$C_STMLF : FAB$C_VAR;
4454 fab.fab$b_rat = FAB$M_CR;
4457 /* Set the file protections such that we will be able to manipulate
4458 this file. Once we are done writing and renaming it, we will set
4459 the protections back. */
4460 if (old)
4461 fab_final_pro = xabpro.xab$w_pro;
4462 else
4463 SYS$SETDFPROT (0, &fab_final_pro);
4464 xabpro.xab$w_pro &= 0xff0f; /* set O:rewd for now. This is set back later. */
4466 /* Create the new file with either default attrs or attrs copied
4467 from old file. */
4468 if (!(SYS$CREATE (&fab, 0, 0) & 1))
4469 return -1;
4470 SYS$CLOSE (&fab, 0, 0);
4471 /* As this is a "replacement" for creat, return a file descriptor
4472 opened for writing. */
4473 return open (new, O_WRONLY);
4476 #ifdef creat
4477 #undef creat
4478 #include <varargs.h>
4479 #ifdef __GNUC__
4480 #ifndef va_count
4481 #define va_count(X) ((X) = *(((int *) &(va_alist)) - 1))
4482 #endif
4483 #endif
4486 sys_creat (va_alist)
4487 va_dcl
4489 va_list list_incrementer;
4490 char *name;
4491 int mode;
4492 int rfd; /* related file descriptor */
4493 int fd; /* Our new file descriptor */
4494 int count;
4495 struct stat st_buf;
4496 char rfm[12];
4497 char rat[15];
4498 char mrs[13];
4499 char fsz[13];
4500 extern int vms_stmlf_recfm;
4502 va_count (count);
4503 va_start (list_incrementer);
4504 name = va_arg (list_incrementer, char *);
4505 mode = va_arg (list_incrementer, int);
4506 if (count > 2)
4507 rfd = va_arg (list_incrementer, int);
4508 va_end (list_incrementer);
4509 if (count > 2)
4511 /* Use information from the related file descriptor to set record
4512 format of the newly created file. */
4513 fstat (rfd, &st_buf);
4514 switch (st_buf.st_fab_rfm)
4516 case FAB$C_FIX:
4517 strcpy (rfm, "rfm = fix");
4518 sprintf (mrs, "mrs = %d", st_buf.st_fab_mrs);
4519 strcpy (rat, "rat = ");
4520 if (st_buf.st_fab_rat & FAB$M_CR)
4521 strcat (rat, "cr");
4522 else if (st_buf.st_fab_rat & FAB$M_FTN)
4523 strcat (rat, "ftn");
4524 else if (st_buf.st_fab_rat & FAB$M_PRN)
4525 strcat (rat, "prn");
4526 if (st_buf.st_fab_rat & FAB$M_BLK)
4527 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4528 strcat (rat, ", blk");
4529 else
4530 strcat (rat, "blk");
4531 return creat (name, 0, rfm, rat, mrs);
4533 case FAB$C_VFC:
4534 strcpy (rfm, "rfm = vfc");
4535 sprintf (fsz, "fsz = %d", st_buf.st_fab_fsz);
4536 strcpy (rat, "rat = ");
4537 if (st_buf.st_fab_rat & FAB$M_CR)
4538 strcat (rat, "cr");
4539 else if (st_buf.st_fab_rat & FAB$M_FTN)
4540 strcat (rat, "ftn");
4541 else if (st_buf.st_fab_rat & FAB$M_PRN)
4542 strcat (rat, "prn");
4543 if (st_buf.st_fab_rat & FAB$M_BLK)
4544 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4545 strcat (rat, ", blk");
4546 else
4547 strcat (rat, "blk");
4548 return creat (name, 0, rfm, rat, fsz);
4550 case FAB$C_STM:
4551 strcpy (rfm, "rfm = stm");
4552 break;
4554 case FAB$C_STMCR:
4555 strcpy (rfm, "rfm = stmcr");
4556 break;
4558 case FAB$C_STMLF:
4559 strcpy (rfm, "rfm = stmlf");
4560 break;
4562 case FAB$C_UDF:
4563 strcpy (rfm, "rfm = udf");
4564 break;
4566 case FAB$C_VAR:
4567 strcpy (rfm, "rfm = var");
4568 break;
4570 strcpy (rat, "rat = ");
4571 if (st_buf.st_fab_rat & FAB$M_CR)
4572 strcat (rat, "cr");
4573 else if (st_buf.st_fab_rat & FAB$M_FTN)
4574 strcat (rat, "ftn");
4575 else if (st_buf.st_fab_rat & FAB$M_PRN)
4576 strcat (rat, "prn");
4577 if (st_buf.st_fab_rat & FAB$M_BLK)
4578 if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
4579 strcat (rat, ", blk");
4580 else
4581 strcat (rat, "blk");
4583 else
4585 strcpy (rfm, vms_stmlf_recfm ? "rfm = stmlf" : "rfm=var");
4586 strcpy (rat, "rat=cr");
4588 /* Until the VAX C RTL fixes the many bugs with modes, always use
4589 mode 0 to get the user's default protection. */
4590 fd = creat (name, 0, rfm, rat);
4591 if (fd < 0 && errno == EEXIST)
4593 if (unlink (name) < 0)
4594 report_file_error ("delete", build_string (name));
4595 fd = creat (name, 0, rfm, rat);
4597 return fd;
4599 #endif /* creat */
4601 /* fwrite to stdout is S L O W. Speed it up by using fputc...*/
4603 sys_fwrite (ptr, size, num, fp)
4604 register char * ptr;
4605 FILE * fp;
4607 register int tot = num * size;
4609 while (tot--)
4610 fputc (*ptr++, fp);
4611 return num;
4615 * The VMS C library routine creat actually creates a new version of an
4616 * existing file rather than truncating the old version. There are times
4617 * when this is not the desired behavior, for instance, when writing an
4618 * auto save file (you only want one version), or when you don't have
4619 * write permission in the directory containing the file (but the file
4620 * itself is writable). Hence this routine, which is equivalent to
4621 * "close (creat (fn, 0));" on Unix if fn already exists.
4624 vms_truncate (fn)
4625 char *fn;
4627 struct FAB xfab = cc$rms_fab;
4628 struct RAB xrab = cc$rms_rab;
4629 int status;
4631 xfab.fab$l_fop = FAB$M_TEF; /* free allocated but unused blocks on close */
4632 xfab.fab$b_fac = FAB$M_TRN | FAB$M_GET; /* allow truncate and get access */
4633 xfab.fab$b_shr = FAB$M_NIL; /* allow no sharing - file must be locked */
4634 xfab.fab$l_fna = fn;
4635 xfab.fab$b_fns = strlen (fn);
4636 xfab.fab$l_dna = ";0"; /* default to latest version of the file */
4637 xfab.fab$b_dns = 2;
4638 xrab.rab$l_fab = &xfab;
4640 /* This gibberish opens the file, positions to the first record, and
4641 deletes all records from there until the end of file. */
4642 if ((SYS$OPEN (&xfab) & 01) == 01)
4644 if ((SYS$CONNECT (&xrab) & 01) == 01 &&
4645 (SYS$FIND (&xrab) & 01) == 01 &&
4646 (SYS$TRUNCATE (&xrab) & 01) == 01)
4647 status = 0;
4648 else
4649 status = -1;
4651 else
4652 status = -1;
4653 SYS$CLOSE (&xfab);
4654 return status;
4657 /* Define this symbol to actually read SYSUAF.DAT. This requires either
4658 SYSPRV or a readable SYSUAF.DAT. */
4660 #ifdef READ_SYSUAF
4662 * getuaf.c
4664 * Routine to read the VMS User Authorization File and return
4665 * a specific user's record.
4668 static struct UAF retuaf;
4670 struct UAF *
4671 get_uaf_name (uname)
4672 char * uname;
4674 register status;
4675 struct FAB uaf_fab;
4676 struct RAB uaf_rab;
4678 uaf_fab = cc$rms_fab;
4679 uaf_rab = cc$rms_rab;
4680 /* initialize fab fields */
4681 uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
4682 uaf_fab.fab$b_fns = 21;
4683 uaf_fab.fab$b_fac = FAB$M_GET;
4684 uaf_fab.fab$b_org = FAB$C_IDX;
4685 uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
4686 /* initialize rab fields */
4687 uaf_rab.rab$l_fab = &uaf_fab;
4688 /* open the User Authorization File */
4689 status = SYS$OPEN (&uaf_fab);
4690 if (!(status&1))
4692 errno = EVMSERR;
4693 vaxc$errno = status;
4694 return 0;
4696 status = SYS$CONNECT (&uaf_rab);
4697 if (!(status&1))
4699 errno = EVMSERR;
4700 vaxc$errno = status;
4701 return 0;
4703 /* read the requested record - index is in uname */
4704 uaf_rab.rab$l_kbf = uname;
4705 uaf_rab.rab$b_ksz = strlen (uname);
4706 uaf_rab.rab$b_rac = RAB$C_KEY;
4707 uaf_rab.rab$l_ubf = (char *)&retuaf;
4708 uaf_rab.rab$w_usz = sizeof retuaf;
4709 status = SYS$GET (&uaf_rab);
4710 if (!(status&1))
4712 errno = EVMSERR;
4713 vaxc$errno = status;
4714 return 0;
4716 /* close the User Authorization File */
4717 status = SYS$DISCONNECT (&uaf_rab);
4718 if (!(status&1))
4720 errno = EVMSERR;
4721 vaxc$errno = status;
4722 return 0;
4724 status = SYS$CLOSE (&uaf_fab);
4725 if (!(status&1))
4727 errno = EVMSERR;
4728 vaxc$errno = status;
4729 return 0;
4731 return &retuaf;
4734 struct UAF *
4735 get_uaf_uic (uic)
4736 unsigned long uic;
4738 register status;
4739 struct FAB uaf_fab;
4740 struct RAB uaf_rab;
4742 uaf_fab = cc$rms_fab;
4743 uaf_rab = cc$rms_rab;
4744 /* initialize fab fields */
4745 uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
4746 uaf_fab.fab$b_fns = 21;
4747 uaf_fab.fab$b_fac = FAB$M_GET;
4748 uaf_fab.fab$b_org = FAB$C_IDX;
4749 uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
4750 /* initialize rab fields */
4751 uaf_rab.rab$l_fab = &uaf_fab;
4752 /* open the User Authorization File */
4753 status = SYS$OPEN (&uaf_fab);
4754 if (!(status&1))
4756 errno = EVMSERR;
4757 vaxc$errno = status;
4758 return 0;
4760 status = SYS$CONNECT (&uaf_rab);
4761 if (!(status&1))
4763 errno = EVMSERR;
4764 vaxc$errno = status;
4765 return 0;
4767 /* read the requested record - index is in uic */
4768 uaf_rab.rab$b_krf = 1; /* 1st alternate key */
4769 uaf_rab.rab$l_kbf = (char *) &uic;
4770 uaf_rab.rab$b_ksz = sizeof uic;
4771 uaf_rab.rab$b_rac = RAB$C_KEY;
4772 uaf_rab.rab$l_ubf = (char *)&retuaf;
4773 uaf_rab.rab$w_usz = sizeof retuaf;
4774 status = SYS$GET (&uaf_rab);
4775 if (!(status&1))
4777 errno = EVMSERR;
4778 vaxc$errno = status;
4779 return 0;
4781 /* close the User Authorization File */
4782 status = SYS$DISCONNECT (&uaf_rab);
4783 if (!(status&1))
4785 errno = EVMSERR;
4786 vaxc$errno = status;
4787 return 0;
4789 status = SYS$CLOSE (&uaf_fab);
4790 if (!(status&1))
4792 errno = EVMSERR;
4793 vaxc$errno = status;
4794 return 0;
4796 return &retuaf;
4799 static struct passwd retpw;
4801 struct passwd *
4802 cnv_uaf_pw (up)
4803 struct UAF * up;
4805 char * ptr;
4807 /* copy these out first because if the username is 32 chars, the next
4808 section will overwrite the first byte of the UIC */
4809 retpw.pw_uid = up->uaf$w_mem;
4810 retpw.pw_gid = up->uaf$w_grp;
4812 /* I suppose this is not the best style, to possibly overwrite one
4813 byte beyond the end of the field, but what the heck... */
4814 ptr = &up->uaf$t_username[UAF$S_USERNAME];
4815 while (ptr[-1] == ' ')
4816 ptr--;
4817 *ptr = '\0';
4818 strcpy (retpw.pw_name, up->uaf$t_username);
4820 /* the rest of these are counted ascii strings */
4821 strncpy (retpw.pw_gecos, &up->uaf$t_owner[1], up->uaf$t_owner[0]);
4822 retpw.pw_gecos[up->uaf$t_owner[0]] = '\0';
4823 strncpy (retpw.pw_dir, &up->uaf$t_defdev[1], up->uaf$t_defdev[0]);
4824 retpw.pw_dir[up->uaf$t_defdev[0]] = '\0';
4825 strncat (retpw.pw_dir, &up->uaf$t_defdir[1], up->uaf$t_defdir[0]);
4826 retpw.pw_dir[up->uaf$t_defdev[0] + up->uaf$t_defdir[0]] = '\0';
4827 strncpy (retpw.pw_shell, &up->uaf$t_defcli[1], up->uaf$t_defcli[0]);
4828 retpw.pw_shell[up->uaf$t_defcli[0]] = '\0';
4830 return &retpw;
4832 #else /* not READ_SYSUAF */
4833 static struct passwd retpw;
4834 #endif /* not READ_SYSUAF */
4836 struct passwd *
4837 getpwnam (name)
4838 char * name;
4840 #ifdef READ_SYSUAF
4841 struct UAF *up;
4842 #else
4843 char * user;
4844 char * dir;
4845 unsigned char * full;
4846 #endif /* READ_SYSUAF */
4847 char *ptr = name;
4849 while (*ptr)
4851 if ('a' <= *ptr && *ptr <= 'z')
4852 *ptr -= 040;
4853 ptr++;
4855 #ifdef READ_SYSUAF
4856 if (!(up = get_uaf_name (name)))
4857 return 0;
4858 return cnv_uaf_pw (up);
4859 #else
4860 if (strcmp (name, getenv ("USER")) == 0)
4862 retpw.pw_uid = getuid ();
4863 retpw.pw_gid = getgid ();
4864 strcpy (retpw.pw_name, name);
4865 if (full = egetenv ("FULLNAME"))
4866 strcpy (retpw.pw_gecos, full);
4867 else
4868 *retpw.pw_gecos = '\0';
4869 strcpy (retpw.pw_dir, egetenv ("HOME"));
4870 *retpw.pw_shell = '\0';
4871 return &retpw;
4873 else
4874 return 0;
4875 #endif /* not READ_SYSUAF */
4878 struct passwd *
4879 getpwuid (uid)
4880 unsigned long uid;
4882 #ifdef READ_SYSUAF
4883 struct UAF * up;
4885 if (!(up = get_uaf_uic (uid)))
4886 return 0;
4887 return cnv_uaf_pw (up);
4888 #else
4889 if (uid == sys_getuid ())
4890 return getpwnam (egetenv ("USER"));
4891 else
4892 return 0;
4893 #endif /* not READ_SYSUAF */
4896 /* return total address space available to the current process. This is
4897 the sum of the current p0 size, p1 size and free page table entries
4898 available. */
4900 vlimit ()
4902 int item_code;
4903 unsigned long free_pages;
4904 unsigned long frep0va;
4905 unsigned long frep1va;
4906 register status;
4908 item_code = JPI$_FREPTECNT;
4909 if (((status = LIB$GETJPI (&item_code, 0, 0, &free_pages)) & 1) == 0)
4911 errno = EVMSERR;
4912 vaxc$errno = status;
4913 return -1;
4915 free_pages *= 512;
4917 item_code = JPI$_FREP0VA;
4918 if (((status = LIB$GETJPI (&item_code, 0, 0, &frep0va)) & 1) == 0)
4920 errno = EVMSERR;
4921 vaxc$errno = status;
4922 return -1;
4924 item_code = JPI$_FREP1VA;
4925 if (((status = LIB$GETJPI (&item_code, 0, 0, &frep1va)) & 1) == 0)
4927 errno = EVMSERR;
4928 vaxc$errno = status;
4929 return -1;
4932 return free_pages + frep0va + (0x7fffffff - frep1va);
4936 define_logical_name (varname, string)
4937 char *varname;
4938 char *string;
4940 struct dsc$descriptor_s strdsc =
4941 {strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string};
4942 struct dsc$descriptor_s envdsc =
4943 {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
4944 struct dsc$descriptor_s lnmdsc =
4945 {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
4947 return LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
4951 delete_logical_name (varname)
4952 char *varname;
4954 struct dsc$descriptor_s envdsc =
4955 {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
4956 struct dsc$descriptor_s lnmdsc =
4957 {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
4959 return LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
4963 ulimit ()
4965 return 0;
4969 setpgrp ()
4971 return 0;
4975 execvp ()
4977 error ("execvp system call not implemented");
4978 return -1;
4982 rename (from, to)
4983 char *from, *to;
4985 int status;
4986 struct FAB from_fab = cc$rms_fab, to_fab = cc$rms_fab;
4987 struct NAM from_nam = cc$rms_nam, to_nam = cc$rms_nam;
4988 char from_esn[NAM$C_MAXRSS];
4989 char to_esn[NAM$C_MAXRSS];
4991 from_fab.fab$l_fna = from;
4992 from_fab.fab$b_fns = strlen (from);
4993 from_fab.fab$l_nam = &from_nam;
4994 from_fab.fab$l_fop = FAB$M_NAM;
4996 from_nam.nam$l_esa = from_esn;
4997 from_nam.nam$b_ess = sizeof from_esn;
4999 to_fab.fab$l_fna = to;
5000 to_fab.fab$b_fns = strlen (to);
5001 to_fab.fab$l_nam = &to_nam;
5002 to_fab.fab$l_fop = FAB$M_NAM;
5004 to_nam.nam$l_esa = to_esn;
5005 to_nam.nam$b_ess = sizeof to_esn;
5007 status = SYS$RENAME (&from_fab, 0, 0, &to_fab);
5009 if (status & 1)
5010 return 0;
5011 else
5013 if (status == RMS$_DEV)
5014 errno = EXDEV;
5015 else
5016 errno = EVMSERR;
5017 vaxc$errno = status;
5018 return -1;
5022 /* This function renames a file like `rename', but it strips
5023 the version number from the "to" filename, such that the "to" file is
5024 will always be a new version. It also sets the file protection once it is
5025 finished. The protection that we will use is stored in fab_final_pro,
5026 and was set when we did a creat_copy_attrs to create the file that we
5027 are renaming.
5029 We could use the chmod function, but Eunichs uses 3 bits per user category
5030 to describe the protection, and VMS uses 4 (write and delete are separate
5031 bits). To maintain portability, the VMS implementation of `chmod' wires
5032 the W and D bits together. */
5035 static struct fibdef fib; /* We need this initialized to zero */
5036 char vms_file_written[NAM$C_MAXRSS];
5039 rename_sans_version (from,to)
5040 char *from, *to;
5042 short int chan;
5043 int stat;
5044 short int iosb[4];
5045 int status;
5046 struct FAB to_fab = cc$rms_fab;
5047 struct NAM to_nam = cc$rms_nam;
5048 struct dsc$descriptor fib_d ={sizeof (fib),0,0,(char*) &fib};
5049 struct dsc$descriptor fib_attr[2]
5050 = {{sizeof (fab_final_pro),ATR$C_FPRO,0,(char*) &fab_final_pro},{0,0,0,0}};
5051 char to_esn[NAM$C_MAXRSS];
5053 $DESCRIPTOR (disk,to_esn);
5055 to_fab.fab$l_fna = to;
5056 to_fab.fab$b_fns = strlen (to);
5057 to_fab.fab$l_nam = &to_nam;
5058 to_fab.fab$l_fop = FAB$M_NAM;
5060 to_nam.nam$l_esa = to_esn;
5061 to_nam.nam$b_ess = sizeof to_esn;
5063 status = SYS$PARSE (&to_fab, 0, 0); /* figure out the full file name */
5065 if (to_nam.nam$l_fnb && NAM$M_EXP_VER)
5066 *(to_nam.nam$l_ver) = '\0';
5068 stat = rename (from, to_esn);
5069 if (stat < 0)
5070 return stat;
5072 strcpy (vms_file_written, to_esn);
5074 to_fab.fab$l_fna = vms_file_written; /* this points to the versionless name */
5075 to_fab.fab$b_fns = strlen (vms_file_written);
5077 /* Now set the file protection to the correct value */
5078 SYS$OPEN (&to_fab, 0, 0); /* This fills in the nam$w_fid fields */
5080 /* Copy these fields into the fib */
5081 fib.fib$r_fid_overlay.fib$w_fid[0] = to_nam.nam$w_fid[0];
5082 fib.fib$r_fid_overlay.fib$w_fid[1] = to_nam.nam$w_fid[1];
5083 fib.fib$r_fid_overlay.fib$w_fid[2] = to_nam.nam$w_fid[2];
5085 SYS$CLOSE (&to_fab, 0, 0);
5087 stat = SYS$ASSIGN (&disk, &chan, 0, 0); /* open a channel to the disk */
5088 if (!stat)
5089 LIB$SIGNAL (stat);
5090 stat = SYS$QIOW (0, chan, IO$_MODIFY, iosb, 0, 0, &fib_d,
5091 0, 0, 0, &fib_attr, 0);
5092 if (!stat)
5093 LIB$SIGNAL (stat);
5094 stat = SYS$DASSGN (chan);
5095 if (!stat)
5096 LIB$SIGNAL (stat);
5097 strcpy (vms_file_written, to_esn); /* We will write this to the terminal*/
5098 return 0;
5102 link (file, new)
5103 char * file, * new;
5105 register status;
5106 struct FAB fab;
5107 struct NAM nam;
5108 unsigned short fid[3];
5109 char esa[NAM$C_MAXRSS];
5111 fab = cc$rms_fab;
5112 fab.fab$l_fop = FAB$M_OFP;
5113 fab.fab$l_fna = file;
5114 fab.fab$b_fns = strlen (file);
5115 fab.fab$l_nam = &nam;
5117 nam = cc$rms_nam;
5118 nam.nam$l_esa = esa;
5119 nam.nam$b_ess = NAM$C_MAXRSS;
5121 status = SYS$PARSE (&fab);
5122 if ((status & 1) == 0)
5124 errno = EVMSERR;
5125 vaxc$errno = status;
5126 return -1;
5128 status = SYS$SEARCH (&fab);
5129 if ((status & 1) == 0)
5131 errno = EVMSERR;
5132 vaxc$errno = status;
5133 return -1;
5136 fid[0] = nam.nam$w_fid[0];
5137 fid[1] = nam.nam$w_fid[1];
5138 fid[2] = nam.nam$w_fid[2];
5140 fab.fab$l_fna = new;
5141 fab.fab$b_fns = strlen (new);
5143 status = SYS$PARSE (&fab);
5144 if ((status & 1) == 0)
5146 errno = EVMSERR;
5147 vaxc$errno = status;
5148 return -1;
5151 nam.nam$w_fid[0] = fid[0];
5152 nam.nam$w_fid[1] = fid[1];
5153 nam.nam$w_fid[2] = fid[2];
5155 nam.nam$l_esa = nam.nam$l_name;
5156 nam.nam$b_esl = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver;
5158 status = SYS$ENTER (&fab);
5159 if ((status & 1) == 0)
5161 errno = EVMSERR;
5162 vaxc$errno = status;
5163 return -1;
5166 return 0;
5169 void
5170 croak (badfunc)
5171 char *badfunc;
5173 printf ("%s not yet implemented\r\n", badfunc);
5174 reset_all_sys_modes ();
5175 exit (1);
5178 long
5179 random ()
5181 /* Arrange to return a range centered on zero. */
5182 return rand () - (1 << 30);
5185 void
5186 srandom (seed)
5188 srand (seed);
5190 #endif /* VMS */
5192 #ifdef AIXHFT
5194 /* Called from init_sys_modes. */
5195 void
5196 hft_init (struct tty_display_info *tty_out)
5198 int junk;
5200 /* If we're not on an HFT we shouldn't do any of this. We determine
5201 if we are on an HFT by trying to get an HFT error code. If this
5202 call fails, we're not on an HFT. */
5203 #ifdef IBMR2AIX
5204 if (ioctl (0, HFQERROR, &junk) < 0)
5205 return;
5206 #else /* not IBMR2AIX */
5207 if (ioctl (0, HFQEIO, 0) < 0)
5208 return;
5209 #endif /* not IBMR2AIX */
5211 /* On AIX the default hft keyboard mapping uses backspace rather than delete
5212 as the rubout key's ASCII code. Here this is changed. The bug is that
5213 there's no way to determine the old mapping, so in reset_sys_modes
5214 we need to assume that the normal map had been present. Of course, this
5215 code also doesn't help if on a terminal emulator which doesn't understand
5216 HFT VTD's. */
5218 struct hfbuf buf;
5219 struct hfkeymap keymap;
5221 buf.hf_bufp = (char *)&keymap;
5222 buf.hf_buflen = sizeof (keymap);
5223 keymap.hf_nkeys = 2;
5224 keymap.hfkey[0].hf_kpos = 15;
5225 keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
5226 #ifdef IBMR2AIX
5227 keymap.hfkey[0].hf_keyidh = '<';
5228 #else /* not IBMR2AIX */
5229 keymap.hfkey[0].hf_page = '<';
5230 #endif /* not IBMR2AIX */
5231 keymap.hfkey[0].hf_char = 127;
5232 keymap.hfkey[1].hf_kpos = 15;
5233 keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
5234 #ifdef IBMR2AIX
5235 keymap.hfkey[1].hf_keyidh = '<';
5236 #else /* not IBMR2AIX */
5237 keymap.hfkey[1].hf_page = '<';
5238 #endif /* not IBMR2AIX */
5239 keymap.hfkey[1].hf_char = 127;
5240 hftctl (0, HFSKBD, &buf);
5244 /* Reset the rubout key to backspace. */
5246 void
5247 hft_reset (struct tty_display_info *tty_out)
5249 struct hfbuf buf;
5250 struct hfkeymap keymap;
5251 int junk;
5253 #ifdef IBMR2AIX
5254 if (ioctl (0, HFQERROR, &junk) < 0)
5255 return;
5256 #else /* not IBMR2AIX */
5257 if (ioctl (0, HFQEIO, 0) < 0)
5258 return;
5259 #endif /* not IBMR2AIX */
5261 buf.hf_bufp = (char *)&keymap;
5262 buf.hf_buflen = sizeof (keymap);
5263 keymap.hf_nkeys = 2;
5264 keymap.hfkey[0].hf_kpos = 15;
5265 keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
5266 #ifdef IBMR2AIX
5267 keymap.hfkey[0].hf_keyidh = '<';
5268 #else /* not IBMR2AIX */
5269 keymap.hfkey[0].hf_page = '<';
5270 #endif /* not IBMR2AIX */
5271 keymap.hfkey[0].hf_char = 8;
5272 keymap.hfkey[1].hf_kpos = 15;
5273 keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
5274 #ifdef IBMR2AIX
5275 keymap.hfkey[1].hf_keyidh = '<';
5276 #else /* not IBMR2AIX */
5277 keymap.hfkey[1].hf_page = '<';
5278 #endif /* not IBMR2AIX */
5279 keymap.hfkey[1].hf_char = 8;
5280 hftctl (0, HFSKBD, &buf);
5283 #endif /* AIXHFT */
5286 #ifndef BSTRING
5288 #ifndef bzero
5290 void
5291 bzero (b, length)
5292 register char *b;
5293 register int length;
5295 #ifdef VMS
5296 short zero = 0;
5297 long max_str = 65535;
5299 while (length > max_str) {
5300 (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
5301 length -= max_str;
5302 b += max_str;
5304 max_str = length;
5305 (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
5306 #else
5307 while (length-- > 0)
5308 *b++ = 0;
5309 #endif /* not VMS */
5312 #endif /* no bzero */
5313 #endif /* BSTRING */
5315 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
5316 #undef bcopy
5318 /* Saying `void' requires a declaration, above, where bcopy is used
5319 and that declaration causes pain for systems where bcopy is a macro. */
5320 bcopy (b1, b2, length)
5321 register char *b1;
5322 register char *b2;
5323 register int length;
5325 #ifdef VMS
5326 long max_str = 65535;
5328 while (length > max_str) {
5329 (void) LIB$MOVC3 (&max_str, b1, b2);
5330 length -= max_str;
5331 b1 += max_str;
5332 b2 += max_str;
5334 max_str = length;
5335 (void) LIB$MOVC3 (&length, b1, b2);
5336 #else
5337 while (length-- > 0)
5338 *b2++ = *b1++;
5339 #endif /* not VMS */
5341 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
5343 #ifndef BSTRING
5344 #ifndef bcmp
5346 bcmp (b1, b2, length) /* This could be a macro! */
5347 register char *b1;
5348 register char *b2;
5349 register int length;
5351 #ifdef VMS
5352 struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
5353 struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
5355 return STR$COMPARE (&src1, &src2);
5356 #else
5357 while (length-- > 0)
5358 if (*b1++ != *b2++)
5359 return 1;
5361 return 0;
5362 #endif /* not VMS */
5364 #endif /* no bcmp */
5365 #endif /* not BSTRING */
5367 #ifndef HAVE_STRSIGNAL
5368 char *
5369 strsignal (code)
5370 int code;
5372 char *signame = 0;
5374 if (0 <= code && code < NSIG)
5376 #ifdef VMS
5377 signame = sys_errlist[code];
5378 #else
5379 /* Cast to suppress warning if the table has const char *. */
5380 signame = (char *) sys_siglist[code];
5381 #endif
5384 return signame;
5386 #endif /* HAVE_STRSIGNAL */
5388 #ifdef HAVE_TERMIOS
5389 /* For make-serial-process */
5390 int serial_open (char *port)
5392 int fd = -1;
5394 fd = emacs_open ((char*) port,
5395 O_RDWR
5396 #ifdef O_NONBLOCK
5397 | O_NONBLOCK
5398 #else
5399 | O_NDELAY
5400 #endif
5401 #ifdef O_NOCTTY
5402 | O_NOCTTY
5403 #endif
5404 , 0);
5405 if (fd < 0)
5407 error ("Could not open %s: %s",
5408 port, emacs_strerror (errno));
5410 #ifdef TIOCEXCL
5411 ioctl (fd, TIOCEXCL, (char *) 0);
5412 #endif
5414 return fd;
5416 #endif /* TERMIOS */
5418 #ifdef HAVE_TERMIOS
5419 /* For serial-process-configure */
5420 void
5421 serial_configure (struct Lisp_Process *p,
5422 Lisp_Object contact)
5424 Lisp_Object childp2 = Qnil;
5425 Lisp_Object tem = Qnil;
5426 struct termios attr;
5427 int err = -1;
5428 char summary[4] = "???"; /* This usually becomes "8N1". */
5430 childp2 = Fcopy_sequence (p->childp);
5432 /* Read port attributes and prepare default configuration. */
5433 err = tcgetattr (p->outfd, &attr);
5434 if (err != 0)
5435 error ("tcgetattr() failed: %s", emacs_strerror (errno));
5436 cfmakeraw (&attr);
5437 #if defined (CLOCAL)
5438 attr.c_cflag |= CLOCAL;
5439 #endif
5440 #if defined (CREAD)
5441 attr.c_cflag | CREAD;
5442 #endif
5444 /* Configure speed. */
5445 if (!NILP (Fplist_member (contact, QCspeed)))
5446 tem = Fplist_get (contact, QCspeed);
5447 else
5448 tem = Fplist_get (p->childp, QCspeed);
5449 CHECK_NUMBER (tem);
5450 err = cfsetspeed (&attr, XINT (tem));
5451 if (err != 0)
5452 error ("cfsetspeed(%d) failed: %s", XINT (tem), emacs_strerror (errno));
5453 childp2 = Fplist_put (childp2, QCspeed, tem);
5455 /* Configure bytesize. */
5456 if (!NILP (Fplist_member (contact, QCbytesize)))
5457 tem = Fplist_get (contact, QCbytesize);
5458 else
5459 tem = Fplist_get (p->childp, QCbytesize);
5460 if (NILP (tem))
5461 tem = make_number (8);
5462 CHECK_NUMBER (tem);
5463 if (XINT (tem) != 7 && XINT (tem) != 8)
5464 error (":bytesize must be nil (8), 7, or 8");
5465 summary[0] = XINT(tem) + '0';
5466 #if defined (CSIZE) && defined (CS7) && defined (CS8)
5467 attr.c_cflag &= ~CSIZE;
5468 attr.c_cflag |= ((XINT (tem) == 7) ? CS7 : CS8);
5469 #else
5470 /* Don't error on bytesize 8, which should be set by cfmakeraw(). */
5471 if (XINT (tem) != 8)
5472 error ("Bytesize cannot be changed");
5473 #endif
5474 childp2 = Fplist_put (childp2, QCbytesize, tem);
5476 /* Configure parity. */
5477 if (!NILP (Fplist_member (contact, QCparity)))
5478 tem = Fplist_get (contact, QCparity);
5479 else
5480 tem = Fplist_get (p->childp, QCparity);
5481 if (!NILP (tem) && !EQ (tem, Qeven) && !EQ (tem, Qodd))
5482 error (":parity must be nil (no parity), `even', or `odd'");
5483 #if defined (PARENB) && defined (PARODD) && defined (IGNPAR) && defined (INPCK)
5484 attr.c_cflag &= ~(PARENB | PARODD);
5485 attr.c_iflag &= ~(IGNPAR | INPCK);
5486 if (NILP (tem))
5488 summary[1] = 'N';
5490 else if (EQ (tem, Qeven))
5492 summary[1] = 'E';
5493 attr.c_cflag |= PARENB;
5494 attr.c_iflag |= (IGNPAR | INPCK);
5496 else if (EQ (tem, Qodd))
5498 summary[1] = 'O';
5499 attr.c_cflag |= (PARENB | PARODD);
5500 attr.c_iflag |= (IGNPAR | INPCK);
5502 #else
5503 /* Don't error on no parity, which should be set by cfmakeraw(). */
5504 if (!NILP (tem))
5505 error ("Parity cannot be configured");
5506 #endif
5507 childp2 = Fplist_put (childp2, QCparity, tem);
5509 /* Configure stopbits. */
5510 if (!NILP (Fplist_member (contact, QCstopbits)))
5511 tem = Fplist_get (contact, QCstopbits);
5512 else
5513 tem = Fplist_get (p->childp, QCstopbits);
5514 if (NILP (tem))
5515 tem = make_number (1);
5516 CHECK_NUMBER (tem);
5517 if (XINT (tem) != 1 && XINT (tem) != 2)
5518 error (":stopbits must be nil (1 stopbit), 1, or 2");
5519 summary[2] = XINT (tem) + '0';
5520 #if defined (CSTOPB)
5521 attr.c_cflag &= ~CSTOPB;
5522 if (XINT (tem) == 2)
5523 attr.c_cflag |= CSTOPB;
5524 #else
5525 /* Don't error on 1 stopbit, which should be set by cfmakeraw(). */
5526 if (XINT (tem) != 1)
5527 error ("Stopbits cannot be configured");
5528 #endif
5529 childp2 = Fplist_put (childp2, QCstopbits, tem);
5531 /* Configure flowcontrol. */
5532 if (!NILP (Fplist_member (contact, QCflowcontrol)))
5533 tem = Fplist_get (contact, QCflowcontrol);
5534 else
5535 tem = Fplist_get (p->childp, QCflowcontrol);
5536 if (!NILP (tem) && !EQ (tem, Qhw) && !EQ (tem, Qsw))
5537 error (":flowcontrol must be nil (no flowcontrol), `hw', or `sw'");
5538 #if defined (CRTSCTS)
5539 attr.c_cflag &= ~CRTSCTS;
5540 #endif
5541 #if defined (CNEW_RTSCTS)
5542 attr.c_cflag &= ~CNEW_RTSCTS;
5543 #endif
5544 #if defined (IXON) && defined (IXOFF)
5545 attr.c_iflag &= ~(IXON | IXOFF);
5546 #endif
5547 if (NILP (tem))
5549 /* Already configured. */
5551 else if (EQ (tem, Qhw))
5553 #if defined (CRTSCTS)
5554 attr.c_cflag |= CRTSCTS;
5555 #elif defined (CNEW_RTSCTS)
5556 attr.c_cflag |= CNEW_RTSCTS;
5557 #else
5558 error ("Hardware flowcontrol (RTS/CTS) not supported");
5559 #endif
5561 else if (EQ (tem, Qsw))
5563 #if defined (IXON) && defined (IXOFF)
5564 attr.c_iflag |= (IXON | IXOFF);
5565 #else
5566 error ("Software flowcontrol (XON/XOFF) not supported");
5567 #endif
5569 childp2 = Fplist_put (childp2, QCflowcontrol, tem);
5571 /* Activate configuration. */
5572 err = tcsetattr (p->outfd, TCSANOW, &attr);
5573 if (err != 0)
5574 error ("tcsetattr() failed: %s", emacs_strerror (errno));
5576 childp2 = Fplist_put (childp2, QCsummary, build_string (summary));
5577 p->childp = childp2;
5580 #endif /* TERMIOS */
5582 /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
5583 (do not change this comment) */