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