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