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