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