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