Rename s/usg5-4.h -> s/usg5-4-common.h.
[bpt/emacs.git] / src / sysdep.c
... / ...
CommitLineData
1/* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5
6This file is part of GNU Emacs.
7
8GNU Emacs is free software: you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
12
13GNU Emacs is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
20
21#include <config.h>
22#include <ctype.h>
23#include <signal.h>
24#include <stdio.h>
25#include <setjmp.h>
26#ifdef HAVE_PWD_H
27#include <pwd.h>
28#include <grp.h>
29#endif /* HAVE_PWD_H */
30#ifdef HAVE_LIMITS_H
31#include <limits.h>
32#endif /* HAVE_LIMITS_H */
33#ifdef HAVE_UNISTD_H
34#include <unistd.h>
35#endif
36
37#include "lisp.h"
38/* Including stdlib.h isn't necessarily enough to get srandom
39 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
40
41/* The w32 build defines select stuff in w32.h, which is included by
42 sys/select.h (included below). */
43#ifndef WINDOWSNT
44#include "sysselect.h"
45#endif
46
47#include "blockinput.h"
48
49#ifdef WINDOWSNT
50#define read sys_read
51#define write sys_write
52#include <windows.h>
53#ifndef NULL
54#define NULL 0
55#endif
56#endif /* not WINDOWSNT */
57
58#include <sys/types.h>
59#include <sys/stat.h>
60#include <errno.h>
61
62#ifdef HAVE_SETPGID
63#if !defined (USG)
64#undef setpgrp
65#define setpgrp setpgid
66#endif
67#endif
68
69/* Get SI_SRPC_DOMAIN, if it is available. */
70#ifdef HAVE_SYS_SYSTEMINFO_H
71#include <sys/systeminfo.h>
72#endif
73
74#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
75#include <dos.h>
76#include "dosfns.h"
77#include "msdos.h"
78#include <sys/param.h>
79#endif
80
81#include <sys/file.h>
82
83#ifdef HAVE_FCNTL_H
84#include <fcntl.h>
85#endif
86
87#ifndef MSDOS
88#include <sys/ioctl.h>
89#endif
90
91#include "systty.h"
92#include "syswait.h"
93
94#if defined (USG)
95#include <sys/utsname.h>
96#include <memory.h>
97#endif /* USG */
98
99extern int quit_char;
100
101#include "keyboard.h"
102#include "frame.h"
103#include "window.h"
104#include "termhooks.h"
105#include "termchar.h"
106#include "termopts.h"
107#include "dispextern.h"
108#include "process.h"
109#include "cm.h" /* for reset_sys_modes */
110
111/* For serial_configure and serial_open. */
112extern Lisp_Object QCport, QCspeed, QCprocess;
113extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
114extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
115
116#ifdef WINDOWSNT
117#include <direct.h>
118/* In process.h which conflicts with the local copy. */
119#define _P_WAIT 0
120int _cdecl _spawnlp (int, const char *, const char *, ...);
121int _cdecl _getpid (void);
122extern char *getwd (char *);
123#endif
124
125#include "syssignal.h"
126#include "systime.h"
127#ifdef HAVE_UTIME_H
128#include <utime.h>
129#endif
130
131#ifndef HAVE_UTIMES
132#ifndef HAVE_STRUCT_UTIMBUF
133/* We want to use utime rather than utimes, but we couldn't find the
134 structure declaration. We'll use the traditional one. */
135struct utimbuf {
136 long actime;
137 long modtime;
138};
139#endif
140#endif
141
142/* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
143#ifndef LPASS8
144#define LPASS8 0
145#endif
146
147static const int baud_convert[] =
148 {
149 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
150 1800, 2400, 4800, 9600, 19200, 38400
151 };
152
153#ifdef HAVE_SPEED_T
154#include <termios.h>
155#else
156#if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
157#else
158#if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
159#include <termios.h>
160#endif
161#endif
162#endif
163
164int emacs_ospeed;
165
166void croak (char *) NO_RETURN;
167
168/* Temporary used by `sigblock' when defined in terms of signprocmask. */
169
170SIGMASKTYPE sigprocmask_set;
171
172
173#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
174
175/* Return the current working directory. Returns NULL on errors.
176 Any other returned value must be freed with free. This is used
177 only when get_current_dir_name is not defined on the system. */
178char*
179get_current_dir_name (void)
180{
181 char *buf;
182 char *pwd;
183 struct stat dotstat, pwdstat;
184 /* If PWD is accurate, use it instead of calling getwd. PWD is
185 sometimes a nicer name, and using it may avoid a fatal error if a
186 parent directory is searchable but not readable. */
187 if ((pwd = getenv ("PWD")) != 0
188 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
189 && stat (pwd, &pwdstat) == 0
190 && stat (".", &dotstat) == 0
191 && dotstat.st_ino == pwdstat.st_ino
192 && dotstat.st_dev == pwdstat.st_dev
193#ifdef MAXPATHLEN
194 && strlen (pwd) < MAXPATHLEN
195#endif
196 )
197 {
198 buf = (char *) malloc (strlen (pwd) + 1);
199 if (!buf)
200 return NULL;
201 strcpy (buf, pwd);
202 }
203#ifdef HAVE_GETCWD
204 else
205 {
206 size_t buf_size = 1024;
207 buf = (char *) malloc (buf_size);
208 if (!buf)
209 return NULL;
210 for (;;)
211 {
212 if (getcwd (buf, buf_size) == buf)
213 break;
214 if (errno != ERANGE)
215 {
216 int tmp_errno = errno;
217 free (buf);
218 errno = tmp_errno;
219 return NULL;
220 }
221 buf_size *= 2;
222 buf = (char *) realloc (buf, buf_size);
223 if (!buf)
224 return NULL;
225 }
226 }
227#else
228 else
229 {
230 /* We need MAXPATHLEN here. */
231 buf = (char *) malloc (MAXPATHLEN + 1);
232 if (!buf)
233 return NULL;
234 if (getwd (buf) == NULL)
235 {
236 int tmp_errno = errno;
237 free (buf);
238 errno = tmp_errno;
239 return NULL;
240 }
241 }
242#endif
243 return buf;
244}
245#endif
246
247\f
248/* Discard pending input on all input descriptors. */
249
250void
251discard_tty_input (void)
252{
253#ifndef WINDOWSNT
254 struct emacs_tty buf;
255
256 if (noninteractive)
257 return;
258
259#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
260 while (dos_keyread () != -1)
261 ;
262#else /* not MSDOS */
263 {
264 struct tty_display_info *tty;
265 for (tty = tty_list; tty; tty = tty->next)
266 {
267 if (tty->input) /* Is the device suspended? */
268 {
269 EMACS_GET_TTY (fileno (tty->input), &buf);
270 EMACS_SET_TTY (fileno (tty->input), &buf, 0);
271 }
272 }
273 }
274#endif /* not MSDOS */
275#endif /* not WINDOWSNT */
276}
277
278\f
279#ifdef SIGTSTP
280
281/* Arrange for character C to be read as the next input from
282 the terminal.
283 XXX What if we have multiple ttys?
284*/
285
286void
287stuff_char (char c)
288{
289 if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
290 return;
291
292/* Should perhaps error if in batch mode */
293#ifdef TIOCSTI
294 ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
295#else /* no TIOCSTI */
296 error ("Cannot stuff terminal input characters in this version of Unix");
297#endif /* no TIOCSTI */
298}
299
300#endif /* SIGTSTP */
301\f
302void
303init_baud_rate (int fd)
304{
305 if (noninteractive)
306 emacs_ospeed = 0;
307 else
308 {
309#ifdef DOS_NT
310 emacs_ospeed = 15;
311#else /* not DOS_NT */
312#ifdef HAVE_TERMIOS
313 struct termios sg;
314
315 sg.c_cflag = B9600;
316 tcgetattr (fd, &sg);
317 emacs_ospeed = cfgetospeed (&sg);
318#else /* not TERMIOS */
319#ifdef HAVE_TERMIO
320 struct termio sg;
321
322 sg.c_cflag = B9600;
323#ifdef HAVE_TCATTR
324 tcgetattr (fd, &sg);
325#else
326 ioctl (fd, TCGETA, &sg);
327#endif
328 emacs_ospeed = sg.c_cflag & CBAUD;
329#else /* neither TERMIOS nor TERMIO */
330 struct sgttyb sg;
331
332 sg.sg_ospeed = B9600;
333 if (ioctl (fd, TIOCGETP, &sg) < 0)
334 abort ();
335 emacs_ospeed = sg.sg_ospeed;
336#endif /* not HAVE_TERMIO */
337#endif /* not HAVE_TERMIOS */
338#endif /* not DOS_NT */
339 }
340
341 baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
342 ? baud_convert[emacs_ospeed] : 9600);
343 if (baud_rate == 0)
344 baud_rate = 1200;
345}
346
347\f
348/*ARGSUSED*/
349void
350set_exclusive_use (int fd)
351{
352#ifdef FIOCLEX
353 ioctl (fd, FIOCLEX, 0);
354#endif
355 /* Ok to do nothing if this feature does not exist */
356}
357\f
358
359int wait_debugging; /* Set nonzero to make following function work under dbx
360 (at least for bsd). */
361
362SIGTYPE
363wait_for_termination_signal (void)
364{}
365
366#ifndef MSDOS
367/* Wait for subprocess with process id `pid' to terminate and
368 make sure it will get eliminated (not remain forever as a zombie) */
369
370void
371wait_for_termination (int pid)
372{
373 while (1)
374 {
375#if defined (BSD_SYSTEM) || defined (HPUX)
376 /* Note that kill returns -1 even if the process is just a zombie now.
377 But inevitably a SIGCHLD interrupt should be generated
378 and child_sig will do wait3 and make the process go away. */
379 /* There is some indication that there is a bug involved with
380 termination of subprocesses, perhaps involving a kernel bug too,
381 but no idea what it is. Just as a hunch we signal SIGCHLD to see
382 if that causes the problem to go away or get worse. */
383 sigsetmask (sigmask (SIGCHLD));
384 if (0 > kill (pid, 0))
385 {
386 sigsetmask (SIGEMPTYMASK);
387 kill (getpid (), SIGCHLD);
388 break;
389 }
390 if (wait_debugging)
391 sleep (1);
392 else
393 sigpause (SIGEMPTYMASK);
394#else /* not BSD_SYSTEM, and not HPUX version >= 6 */
395#ifdef WINDOWSNT
396 wait (0);
397 break;
398#else /* not WINDOWSNT */
399 sigblock (sigmask (SIGCHLD));
400 errno = 0;
401 if (kill (pid, 0) == -1 && errno == ESRCH)
402 {
403 sigunblock (sigmask (SIGCHLD));
404 break;
405 }
406
407 sigsuspend (&empty_mask);
408#endif /* not WINDOWSNT */
409#endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
410 }
411}
412
413/*
414 * flush any pending output
415 * (may flush input as well; it does not matter the way we use it)
416 */
417
418void
419flush_pending_output (int channel)
420{
421#ifdef HAVE_TERMIOS
422 /* If we try this, we get hit with SIGTTIN, because
423 the child's tty belongs to the child's pgrp. */
424#else
425#ifdef TCFLSH
426 ioctl (channel, TCFLSH, 1);
427#else
428#ifdef TIOCFLUSH
429 int zero = 0;
430 /* 3rd arg should be ignored
431 but some 4.2 kernels actually want the address of an int
432 and nonzero means something different. */
433 ioctl (channel, TIOCFLUSH, &zero);
434#endif
435#endif
436#endif
437}
438\f
439/* Set up the terminal at the other end of a pseudo-terminal that
440 we will be controlling an inferior through.
441 It should not echo or do line-editing, since that is done
442 in Emacs. No padding needed for insertion into an Emacs buffer. */
443
444void
445child_setup_tty (int out)
446{
447#ifndef WINDOWSNT
448 struct emacs_tty s;
449
450 EMACS_GET_TTY (out, &s);
451
452#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
453 s.main.c_oflag |= OPOST; /* Enable output postprocessing */
454 s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */
455#ifdef NLDLY
456 /* http://lists.gnu.org/archive/html/emacs-devel/2008-05/msg00406.html
457 Some versions of GNU Hurd do not have FFDLY? */
458#ifdef FFDLY
459 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
460 /* No output delays */
461#else
462 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY);
463 /* No output delays */
464#endif
465#endif
466 s.main.c_lflag &= ~ECHO; /* Disable echo */
467 s.main.c_lflag |= ISIG; /* Enable signals */
468#ifdef IUCLC
469 s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */
470#endif
471#ifdef ISTRIP
472 s.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
473#endif
474#ifdef OLCUC
475 s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */
476#endif
477 s.main.c_oflag &= ~TAB3; /* Disable tab expansion */
478 s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
479 s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
480 s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
481
482#ifdef HPUX
483 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
484#endif /* HPUX */
485
486#ifdef SIGNALS_VIA_CHARACTERS
487 /* the QUIT and INTR character are used in process_send_signal
488 so set them here to something useful. */
489 if (s.main.c_cc[VQUIT] == CDISABLE)
490 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
491 if (s.main.c_cc[VINTR] == CDISABLE)
492 s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
493#endif /* not SIGNALS_VIA_CHARACTERS */
494
495#ifdef AIX
496 /* Also, PTY overloads NUL and BREAK.
497 don't ignore break, but don't signal either, so it looks like NUL. */
498 s.main.c_iflag &= ~IGNBRK;
499 s.main.c_iflag &= ~BRKINT;
500 /* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
501 unconditionally. Then a SIGNALS_VIA_CHARACTERS conditional
502 would force it to 0377. That looks like duplicated code. */
503 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
504#endif /* AIX */
505
506 /* We used to enable ICANON (and set VEOF to 04), but this leads to
507 problems where process.c wants to send EOFs every once in a while
508 to force the output, which leads to weird effects when the
509 subprocess has disabled ICANON and ends up seeing those spurious
510 extra EOFs. So we don't send EOFs any more in
511 process.c:send_process, and instead we disable ICANON by default,
512 so if a subsprocess sets up ICANON, it's his problem (or the Elisp
513 package that talks to it) to deal with lines that are too long. */
514 s.main.c_lflag &= ~ICANON; /* Disable line editing and eof processing */
515 s.main.c_cc[VMIN] = 1;
516 s.main.c_cc[VTIME] = 0;
517
518#else /* not HAVE_TERMIO */
519
520 s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
521 | CBREAK | TANDEM);
522 s.main.sg_flags |= LPASS8;
523 s.main.sg_erase = 0377;
524 s.main.sg_kill = 0377;
525 s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */
526
527#endif /* not HAVE_TERMIO */
528
529 EMACS_SET_TTY (out, &s, 0);
530
531#endif /* not WINDOWSNT */
532}
533#endif /* MSDOS */
534
535\f
536/* Record a signal code and the handler for it. */
537struct save_signal
538{
539 int code;
540 SIGTYPE (*handler) (int);
541};
542
543static void save_signal_handlers (struct save_signal *);
544static void restore_signal_handlers (struct save_signal *);
545
546/* Suspend the Emacs process; give terminal to its superior. */
547
548void
549sys_suspend (void)
550{
551#if defined (SIGTSTP) && !defined (MSDOS)
552
553 {
554 int pgrp = EMACS_GETPGRP (0);
555 EMACS_KILLPG (pgrp, SIGTSTP);
556 }
557
558#else /* No SIGTSTP */
559/* On a system where suspending is not implemented,
560 instead fork a subshell and let it talk directly to the terminal
561 while we wait. */
562 sys_subshell ();
563
564#endif /* no SIGTSTP */
565}
566
567/* Fork a subshell. */
568
569void
570sys_subshell (void)
571{
572#ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
573 int st;
574 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
575#endif
576 int pid;
577 struct save_signal saved_handlers[5];
578 Lisp_Object dir;
579 unsigned char *str = 0;
580 int len;
581
582 saved_handlers[0].code = SIGINT;
583 saved_handlers[1].code = SIGQUIT;
584 saved_handlers[2].code = SIGTERM;
585#ifdef SIGIO
586 saved_handlers[3].code = SIGIO;
587 saved_handlers[4].code = 0;
588#else
589 saved_handlers[3].code = 0;
590#endif
591
592 /* Mentioning current_buffer->buffer would mean including buffer.h,
593 which somehow wedges the hp compiler. So instead... */
594
595 dir = intern ("default-directory");
596 if (NILP (Fboundp (dir)))
597 goto xyzzy;
598 dir = Fsymbol_value (dir);
599 if (!STRINGP (dir))
600 goto xyzzy;
601
602 dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
603 str = (unsigned char *) alloca (SCHARS (dir) + 2);
604 len = SCHARS (dir);
605 memcpy (str, SDATA (dir), len);
606 if (str[len - 1] != '/') str[len++] = '/';
607 str[len] = 0;
608 xyzzy:
609
610#ifdef DOS_NT
611 pid = 0;
612 save_signal_handlers (saved_handlers);
613 synch_process_alive = 1;
614#else
615 pid = vfork ();
616 if (pid == -1)
617 error ("Can't spawn subshell");
618#endif
619
620 if (pid == 0)
621 {
622 char *sh = 0;
623
624#ifdef DOS_NT /* MW, Aug 1993 */
625 getwd (oldwd);
626 if (sh == 0)
627 sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
628#endif
629 if (sh == 0)
630 sh = (char *) egetenv ("SHELL");
631 if (sh == 0)
632 sh = "sh";
633
634 /* Use our buffer's default directory for the subshell. */
635 if (str)
636 chdir ((char *) str);
637
638 close_process_descs (); /* Close Emacs's pipes/ptys */
639
640#ifdef SET_EMACS_PRIORITY
641 {
642 extern EMACS_INT emacs_priority;
643
644 if (emacs_priority < 0)
645 nice (-emacs_priority);
646 }
647#endif
648
649#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
650 {
651 char *epwd = getenv ("PWD");
652 char old_pwd[MAXPATHLEN+1+4];
653
654 /* If PWD is set, pass it with corrected value. */
655 if (epwd)
656 {
657 strcpy (old_pwd, epwd);
658 if (str[len - 1] == '/')
659 str[len - 1] = '\0';
660 setenv ("PWD", str, 1);
661 }
662 st = system (sh);
663 chdir (oldwd);
664 if (epwd)
665 putenv (old_pwd); /* restore previous value */
666 }
667#else /* not MSDOS */
668#ifdef WINDOWSNT
669 /* Waits for process completion */
670 pid = _spawnlp (_P_WAIT, sh, sh, NULL);
671 chdir (oldwd);
672 if (pid == -1)
673 write (1, "Can't execute subshell", 22);
674#else /* not WINDOWSNT */
675 execlp (sh, sh, (char *) 0);
676 write (1, "Can't execute subshell", 22);
677 _exit (1);
678#endif /* not WINDOWSNT */
679#endif /* not MSDOS */
680 }
681
682 /* Do this now if we did not do it before. */
683#ifndef MSDOS
684 save_signal_handlers (saved_handlers);
685 synch_process_alive = 1;
686#endif
687
688#ifndef DOS_NT
689 wait_for_termination (pid);
690#endif
691 restore_signal_handlers (saved_handlers);
692 synch_process_alive = 0;
693}
694
695static void
696save_signal_handlers (struct save_signal *saved_handlers)
697{
698 while (saved_handlers->code)
699 {
700 saved_handlers->handler
701 = (SIGTYPE (*) (int)) signal (saved_handlers->code, SIG_IGN);
702 saved_handlers++;
703 }
704}
705
706static void
707restore_signal_handlers (struct save_signal *saved_handlers)
708{
709 while (saved_handlers->code)
710 {
711 signal (saved_handlers->code, saved_handlers->handler);
712 saved_handlers++;
713 }
714}
715\f
716#ifndef SIGIO
717/* If SIGIO is broken, don't do anything. */
718void
719init_sigio (int fd)
720{
721}
722
723void
724reset_sigio (int fd)
725{
726}
727
728void
729request_sigio (void)
730{
731}
732
733void
734unrequest_sigio (void)
735{
736}
737
738#else
739#ifdef F_SETFL
740
741int old_fcntl_flags[MAXDESC];
742
743void
744init_sigio (int fd)
745{
746#ifdef FASYNC
747 old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
748 fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC);
749#endif
750 interrupts_deferred = 0;
751}
752
753void
754reset_sigio (int fd)
755{
756#ifdef FASYNC
757 fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
758#endif
759}
760
761#ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
762/* XXX Uhm, FASYNC is not used anymore here. */
763/* XXX Yeah, but you need it for SIGIO, don't you? */
764
765void
766request_sigio (void)
767{
768 if (noninteractive)
769 return;
770
771#ifdef SIGWINCH
772 sigunblock (sigmask (SIGWINCH));
773#endif
774 sigunblock (sigmask (SIGIO));
775
776 interrupts_deferred = 0;
777}
778
779void
780unrequest_sigio (void)
781{
782 if (noninteractive)
783 return;
784
785#if 0 /* XXX What's wrong with blocking SIGIO under X? */
786 if (x_display_list)
787 return;
788#endif
789
790#ifdef SIGWINCH
791 sigblock (sigmask (SIGWINCH));
792#endif
793 sigblock (sigmask (SIGIO));
794 interrupts_deferred = 1;
795}
796
797#else /* no FASYNC */
798#ifndef MSDOS
799
800void
801request_sigio (void)
802{
803 if (noninteractive || read_socket_hook)
804 return;
805
806 croak ("request_sigio");
807}
808
809void
810unrequest_sigio (void)
811{
812 if (noninteractive || read_socket_hook)
813 return;
814
815 croak ("unrequest_sigio");
816}
817
818#endif /* MSDOS */
819#endif /* FASYNC */
820#endif /* F_SETFL */
821#endif /* SIGIO */
822
823\f
824/* Getting and setting emacs_tty structures. */
825
826/* Set *TC to the parameters associated with the terminal FD.
827 Return zero if all's well, or -1 if we ran into an error we
828 couldn't deal with. */
829int
830emacs_get_tty (int fd, struct emacs_tty *settings)
831{
832 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
833#ifdef HAVE_TCATTR
834 /* We have those nifty POSIX tcmumbleattr functions. */
835 memset (&settings->main, 0, sizeof (settings->main));
836 if (tcgetattr (fd, &settings->main) < 0)
837 return -1;
838
839#else
840#ifdef HAVE_TERMIO
841 /* The SYSV-style interface? */
842 if (ioctl (fd, TCGETA, &settings->main) < 0)
843 return -1;
844
845#else
846#ifndef DOS_NT
847 /* I give up - I hope you have the BSD ioctls. */
848 if (ioctl (fd, TIOCGETP, &settings->main) < 0)
849 return -1;
850#endif /* not DOS_NT */
851#endif
852#endif
853
854 /* Suivant - Do we have to get struct ltchars data? */
855#ifdef HAVE_LTCHARS
856 if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
857 return -1;
858#endif
859
860 /* How about a struct tchars and a wordful of lmode bits? */
861#ifdef HAVE_TCHARS
862 if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
863 || ioctl (fd, TIOCLGET, &settings->lmode) < 0)
864 return -1;
865#endif
866
867 /* We have survived the tempest. */
868 return 0;
869}
870
871
872/* Set the parameters of the tty on FD according to the contents of
873 *SETTINGS. If FLUSHP is non-zero, we discard input.
874 Return 0 if all went well, and -1 if anything failed. */
875
876int
877emacs_set_tty (int fd, struct emacs_tty *settings, int flushp)
878{
879 /* Set the primary parameters - baud rate, character size, etcetera. */
880#ifdef HAVE_TCATTR
881 int i;
882 /* We have those nifty POSIX tcmumbleattr functions.
883 William J. Smith <wjs@wiis.wang.com> writes:
884 "POSIX 1003.1 defines tcsetattr to return success if it was
885 able to perform any of the requested actions, even if some
886 of the requested actions could not be performed.
887 We must read settings back to ensure tty setup properly.
888 AIX requires this to keep tty from hanging occasionally." */
889 /* This make sure that we don't loop indefinitely in here. */
890 for (i = 0 ; i < 10 ; i++)
891 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
892 {
893 if (errno == EINTR)
894 continue;
895 else
896 return -1;
897 }
898 else
899 {
900 struct termios new;
901
902 memset (&new, 0, sizeof (new));
903 /* Get the current settings, and see if they're what we asked for. */
904 tcgetattr (fd, &new);
905 /* We cannot use memcmp on the whole structure here because under
906 * aix386 the termios structure has some reserved field that may
907 * not be filled in.
908 */
909 if ( new.c_iflag == settings->main.c_iflag
910 && new.c_oflag == settings->main.c_oflag
911 && new.c_cflag == settings->main.c_cflag
912 && new.c_lflag == settings->main.c_lflag
913 && memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
914 break;
915 else
916 continue;
917 }
918
919#else
920#ifdef HAVE_TERMIO
921 /* The SYSV-style interface? */
922 if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
923 return -1;
924
925#else
926#ifndef DOS_NT
927 /* I give up - I hope you have the BSD ioctls. */
928 if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
929 return -1;
930#endif /* not DOS_NT */
931
932#endif
933#endif
934
935 /* Suivant - Do we have to get struct ltchars data? */
936#ifdef HAVE_LTCHARS
937 if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
938 return -1;
939#endif
940
941 /* How about a struct tchars and a wordful of lmode bits? */
942#ifdef HAVE_TCHARS
943 if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
944 || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
945 return -1;
946#endif
947
948 /* We have survived the tempest. */
949 return 0;
950}
951
952\f
953
954#ifdef F_SETOWN
955int old_fcntl_owner[MAXDESC];
956#endif /* F_SETOWN */
957
958/* This may also be defined in stdio,
959 but if so, this does no harm,
960 and using the same name avoids wasting the other one's space. */
961
962#if defined (USG)
963unsigned char _sobuf[BUFSIZ+8];
964#else
965char _sobuf[BUFSIZ];
966#endif
967
968#ifdef HAVE_LTCHARS
969static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
970#endif
971#ifdef HAVE_TCHARS
972static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
973#endif
974
975/* Initialize the terminal mode on all tty devices that are currently
976 open. */
977
978void
979init_all_sys_modes (void)
980{
981 struct tty_display_info *tty;
982 for (tty = tty_list; tty; tty = tty->next)
983 init_sys_modes (tty);
984}
985
986/* Initialize the terminal mode on the given tty device. */
987
988void
989init_sys_modes (struct tty_display_info *tty_out)
990{
991 struct emacs_tty tty;
992
993 Vtty_erase_char = Qnil;
994
995 if (noninteractive)
996 return;
997
998 if (!tty_out->output)
999 return; /* The tty is suspended. */
1000
1001 if (! tty_out->old_tty)
1002 tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
1003
1004 EMACS_GET_TTY (fileno (tty_out->input), tty_out->old_tty);
1005
1006 tty = *tty_out->old_tty;
1007
1008#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1009 XSETINT (Vtty_erase_char, tty.main.c_cc[VERASE]);
1010
1011 tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
1012 tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
1013#ifdef INLCR /* I'm just being cautious,
1014 since I can't check how widespread INLCR is--rms. */
1015 tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
1016#endif
1017#ifdef ISTRIP
1018 tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
1019#endif
1020 tty.main.c_lflag &= ~ECHO; /* Disable echo */
1021 tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */
1022#ifdef IEXTEN
1023 tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
1024#endif
1025 tty.main.c_lflag |= ISIG; /* Enable signals */
1026 if (tty_out->flow_control)
1027 {
1028 tty.main.c_iflag |= IXON; /* Enable start/stop output control */
1029#ifdef IXANY
1030 tty.main.c_iflag &= ~IXANY;
1031#endif /* IXANY */
1032 }
1033 else
1034 tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
1035 tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
1036 on output */
1037 tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */
1038#ifdef CS8
1039 if (tty_out->meta_key)
1040 {
1041 tty.main.c_cflag |= CS8; /* allow 8th bit on input */
1042 tty.main.c_cflag &= ~PARENB;/* Don't check parity */
1043 }
1044#endif
1045 if (tty_out->input == stdin)
1046 {
1047 tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
1048 /* Set up C-g for both SIGQUIT and SIGINT.
1049 We don't know which we will get, but we handle both alike
1050 so which one it really gives us does not matter. */
1051 tty.main.c_cc[VQUIT] = quit_char;
1052 }
1053 else
1054 {
1055 /* We normally don't get interrupt or quit signals from tty
1056 devices other than our controlling terminal; therefore,
1057 we must handle C-g as normal input. Unfortunately, this
1058 means that the interrupt and quit feature must be
1059 disabled on secondary ttys, or we would not even see the
1060 keypress.
1061
1062 Note that even though emacsclient could have special code
1063 to pass SIGINT to Emacs, we should _not_ enable
1064 interrupt/quit keys for emacsclient frames. This means
1065 that we can't break out of loops in C code from a
1066 secondary tty frame, but we can always decide what
1067 display the C-g came from, which is more important from a
1068 usability point of view. (Consider the case when two
1069 people work together using the same Emacs instance.) */
1070 tty.main.c_cc[VINTR] = CDISABLE;
1071 tty.main.c_cc[VQUIT] = CDISABLE;
1072 }
1073 tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
1074 tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
1075#ifdef VSWTCH
1076 tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
1077 of C-z */
1078#endif /* VSWTCH */
1079
1080#if defined (__mips__) || defined (HAVE_TCATTR)
1081#ifdef VSUSP
1082 tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
1083#endif /* VSUSP */
1084#ifdef V_DSUSP
1085 tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
1086#endif /* V_DSUSP */
1087#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1088 tty.main.c_cc[VDSUSP] = CDISABLE;
1089#endif /* VDSUSP */
1090#ifdef VLNEXT
1091 tty.main.c_cc[VLNEXT] = CDISABLE;
1092#endif /* VLNEXT */
1093#ifdef VREPRINT
1094 tty.main.c_cc[VREPRINT] = CDISABLE;
1095#endif /* VREPRINT */
1096#ifdef VWERASE
1097 tty.main.c_cc[VWERASE] = CDISABLE;
1098#endif /* VWERASE */
1099#ifdef VDISCARD
1100 tty.main.c_cc[VDISCARD] = CDISABLE;
1101#endif /* VDISCARD */
1102
1103 if (tty_out->flow_control)
1104 {
1105#ifdef VSTART
1106 tty.main.c_cc[VSTART] = '\021';
1107#endif /* VSTART */
1108#ifdef VSTOP
1109 tty.main.c_cc[VSTOP] = '\023';
1110#endif /* VSTOP */
1111 }
1112 else
1113 {
1114#ifdef VSTART
1115 tty.main.c_cc[VSTART] = CDISABLE;
1116#endif /* VSTART */
1117#ifdef VSTOP
1118 tty.main.c_cc[VSTOP] = CDISABLE;
1119#endif /* VSTOP */
1120 }
1121#endif /* mips or HAVE_TCATTR */
1122
1123#ifdef AIX
1124 tty.main.c_cc[VSTRT] = CDISABLE;
1125 tty.main.c_cc[VSTOP] = CDISABLE;
1126 tty.main.c_cc[VSUSP] = CDISABLE;
1127 tty.main.c_cc[VDSUSP] = CDISABLE;
1128 if (tty_out->flow_control)
1129 {
1130#ifdef VSTART
1131 tty.main.c_cc[VSTART] = '\021';
1132#endif /* VSTART */
1133#ifdef VSTOP
1134 tty.main.c_cc[VSTOP] = '\023';
1135#endif /* VSTOP */
1136 }
1137 /* Also, PTY overloads NUL and BREAK.
1138 don't ignore break, but don't signal either, so it looks like NUL.
1139 This really serves a purpose only if running in an XTERM window
1140 or via TELNET or the like, but does no harm elsewhere. */
1141 tty.main.c_iflag &= ~IGNBRK;
1142 tty.main.c_iflag &= ~BRKINT;
1143#endif
1144#else /* if not HAVE_TERMIO */
1145#ifndef DOS_NT
1146 XSETINT (Vtty_erase_char, tty.main.sg_erase);
1147 tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1148 if (meta_key)
1149 tty.main.sg_flags |= ANYP;
1150 tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
1151#endif /* not DOS_NT */
1152#endif /* not HAVE_TERMIO */
1153
1154 /* If going to use CBREAK mode, we must request C-g to interrupt
1155 and turn off start and stop chars, etc. If not going to use
1156 CBREAK mode, do this anyway so as to turn off local flow
1157 control for user coming over network on 4.2; in this case,
1158 only t_stopc and t_startc really matter. */
1159#ifndef HAVE_TERMIO
1160#ifdef HAVE_TCHARS
1161 /* Note: if not using CBREAK mode, it makes no difference how we
1162 set this */
1163 tty.tchars = new_tchars;
1164 tty.tchars.t_intrc = quit_char;
1165 if (tty_out->flow_control)
1166 {
1167 tty.tchars.t_startc = '\021';
1168 tty.tchars.t_stopc = '\023';
1169 }
1170
1171 tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | tty_out->old_tty.lmode;
1172
1173#endif /* HAVE_TCHARS */
1174#endif /* not HAVE_TERMIO */
1175
1176#ifdef HAVE_LTCHARS
1177 tty.ltchars = new_ltchars;
1178#endif /* HAVE_LTCHARS */
1179#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1180 if (!tty_out->term_initted)
1181 internal_terminal_init ();
1182 dos_ttraw (tty_out);
1183#endif
1184
1185 EMACS_SET_TTY (fileno (tty_out->input), &tty, 0);
1186
1187 /* This code added to insure that, if flow-control is not to be used,
1188 we have an unlocked terminal at the start. */
1189
1190#ifdef TCXONC
1191 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
1192#endif
1193#ifdef TIOCSTART
1194 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
1195#endif
1196
1197#if defined (HAVE_TERMIOS) || defined (HPUX)
1198#ifdef TCOON
1199 if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
1200#endif
1201#endif
1202
1203#ifdef F_SETFL
1204#ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1205 if (interrupt_input)
1206 {
1207 old_fcntl_owner[fileno (tty_out->input)] =
1208 fcntl (fileno (tty_out->input), F_GETOWN, 0);
1209 fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
1210 init_sigio (fileno (tty_out->input));
1211#ifdef HAVE_GPM
1212 if (gpm_tty == tty_out)
1213 {
1214 /* Arrange for mouse events to give us SIGIO signals. */
1215 fcntl (gpm_fd, F_SETOWN, getpid ());
1216 fcntl (gpm_fd, F_SETFL, fcntl (gpm_fd, F_GETFL, 0) | O_NONBLOCK);
1217 init_sigio (gpm_fd);
1218 }
1219#endif /* HAVE_GPM */
1220 }
1221#endif /* F_GETOWN */
1222#endif /* F_SETFL */
1223
1224#ifdef _IOFBF
1225 /* This symbol is defined on recent USG systems.
1226 Someone says without this call USG won't really buffer the file
1227 even with a call to setbuf. */
1228 setvbuf (tty_out->output, (char *) _sobuf, _IOFBF, sizeof _sobuf);
1229#else
1230 setbuf (tty_out->output, (char *) _sobuf);
1231#endif
1232
1233 if (tty_out->terminal->set_terminal_modes_hook)
1234 tty_out->terminal->set_terminal_modes_hook (tty_out->terminal);
1235
1236 if (!tty_out->term_initted)
1237 {
1238 Lisp_Object tail, frame;
1239 FOR_EACH_FRAME (tail, frame)
1240 {
1241 /* XXX This needs to be revised. */
1242 if (FRAME_TERMCAP_P (XFRAME (frame))
1243 && FRAME_TTY (XFRAME (frame)) == tty_out)
1244 init_frame_faces (XFRAME (frame));
1245 }
1246 }
1247
1248 if (tty_out->term_initted && no_redraw_on_reenter)
1249 {
1250 /* We used to call "direct_output_forward_char(0)" here,
1251 but it's not clear why, since it may not do anything anyway. */
1252 }
1253 else
1254 {
1255 Lisp_Object tail, frame;
1256 frame_garbaged = 1;
1257 FOR_EACH_FRAME (tail, frame)
1258 {
1259 if ((FRAME_TERMCAP_P (XFRAME (frame))
1260 || FRAME_MSDOS_P (XFRAME (frame)))
1261 && FRAME_TTY (XFRAME (frame)) == tty_out)
1262 FRAME_GARBAGED_P (XFRAME (frame)) = 1;
1263 }
1264 }
1265
1266 tty_out->term_initted = 1;
1267}
1268
1269/* Return nonzero if safe to use tabs in output.
1270 At the time this is called, init_sys_modes has not been done yet. */
1271
1272int
1273tabs_safe_p (int fd)
1274{
1275 struct emacs_tty etty;
1276
1277 EMACS_GET_TTY (fd, &etty);
1278 return EMACS_TTY_TABS_OK (&etty);
1279}
1280\f
1281/* Get terminal size from system.
1282 Store number of lines into *HEIGHTP and width into *WIDTHP.
1283 We store 0 if there's no valid information. */
1284
1285void
1286get_tty_size (int fd, int *widthp, int *heightp)
1287{
1288
1289#ifdef TIOCGWINSZ
1290
1291 /* BSD-style. */
1292 struct winsize size;
1293
1294 if (ioctl (fd, TIOCGWINSZ, &size) == -1)
1295 *widthp = *heightp = 0;
1296 else
1297 {
1298 *widthp = size.ws_col;
1299 *heightp = size.ws_row;
1300 }
1301
1302#else
1303#ifdef TIOCGSIZE
1304
1305 /* SunOS - style. */
1306 struct ttysize size;
1307
1308 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1309 *widthp = *heightp = 0;
1310 else
1311 {
1312 *widthp = size.ts_cols;
1313 *heightp = size.ts_lines;
1314 }
1315
1316#else
1317#ifdef MSDOS
1318 *widthp = ScreenCols ();
1319 *heightp = ScreenRows ();
1320#else /* system doesn't know size */
1321 *widthp = 0;
1322 *heightp = 0;
1323#endif
1324#endif /* not SunOS-style */
1325#endif /* not BSD-style */
1326}
1327
1328/* Set the logical window size associated with descriptor FD
1329 to HEIGHT and WIDTH. This is used mainly with ptys. */
1330
1331int
1332set_window_size (int fd, int height, int width)
1333{
1334#ifdef TIOCSWINSZ
1335
1336 /* BSD-style. */
1337 struct winsize size;
1338 size.ws_row = height;
1339 size.ws_col = width;
1340
1341 if (ioctl (fd, TIOCSWINSZ, &size) == -1)
1342 return 0; /* error */
1343 else
1344 return 1;
1345
1346#else
1347#ifdef TIOCSSIZE
1348
1349 /* SunOS - style. */
1350 struct ttysize size;
1351 size.ts_lines = height;
1352 size.ts_cols = width;
1353
1354 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1355 return 0;
1356 else
1357 return 1;
1358#else
1359 return -1;
1360#endif /* not SunOS-style */
1361#endif /* not BSD-style */
1362}
1363
1364\f
1365
1366/* Prepare all terminal devices for exiting Emacs. */
1367
1368void
1369reset_all_sys_modes (void)
1370{
1371 struct tty_display_info *tty;
1372 for (tty = tty_list; tty; tty = tty->next)
1373 reset_sys_modes (tty);
1374}
1375
1376/* Prepare the terminal for closing it; move the cursor to the
1377 bottom of the frame, turn off interrupt-driven I/O, etc. */
1378
1379void
1380reset_sys_modes (struct tty_display_info *tty_out)
1381{
1382 if (noninteractive)
1383 {
1384 fflush (stdout);
1385 return;
1386 }
1387 if (!tty_out->term_initted)
1388 return;
1389
1390 if (!tty_out->output)
1391 return; /* The tty is suspended. */
1392
1393 /* Go to and clear the last line of the terminal. */
1394
1395 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1396
1397 /* Code adapted from tty_clear_end_of_line. */
1398 if (tty_out->TS_clr_line)
1399 {
1400 emacs_tputs (tty_out, tty_out->TS_clr_line, 1, cmputc);
1401 }
1402 else
1403 { /* have to do it the hard way */
1404 int i;
1405 tty_turn_off_insert (tty_out);
1406
1407 for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
1408 {
1409 fputc (' ', tty_out->output);
1410 }
1411 }
1412
1413 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1414 fflush (tty_out->output);
1415
1416 if (tty_out->terminal->reset_terminal_modes_hook)
1417 tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
1418
1419#ifdef BSD_SYSTEM
1420 /* Avoid possible loss of output when changing terminal modes. */
1421 fsync (fileno (tty_out->output));
1422#endif
1423
1424#ifdef F_SETFL
1425#ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1426 if (interrupt_input)
1427 {
1428 reset_sigio (fileno (tty_out->input));
1429 fcntl (fileno (tty_out->input), F_SETOWN,
1430 old_fcntl_owner[fileno (tty_out->input)]);
1431 }
1432#endif /* F_SETOWN */
1433#ifdef O_NDELAY
1434 fcntl (fileno (tty_out->input), F_SETFL,
1435 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY);
1436#endif
1437#endif /* F_SETFL */
1438
1439 if (tty_out->old_tty)
1440 while (EMACS_SET_TTY (fileno (tty_out->input),
1441 tty_out->old_tty, 0) < 0 && errno == EINTR)
1442 ;
1443
1444#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1445 dos_ttcooked ();
1446#endif
1447
1448}
1449\f
1450#ifdef HAVE_PTYS
1451
1452/* Set up the proper status flags for use of a pty. */
1453
1454void
1455setup_pty (int fd)
1456{
1457 /* I'm told that TOICREMOTE does not mean control chars
1458 "can't be sent" but rather that they don't have
1459 input-editing or signaling effects.
1460 That should be good, because we have other ways
1461 to do those things in Emacs.
1462 However, telnet mode seems not to work on 4.2.
1463 So TIOCREMOTE is turned off now. */
1464
1465 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1466 will hang. In particular, the "timeout" feature (which
1467 causes a read to return if there is no data available)
1468 does this. Also it is known that telnet mode will hang
1469 in such a way that Emacs must be stopped (perhaps this
1470 is the same problem).
1471
1472 If TIOCREMOTE is turned off, then there is a bug in
1473 hp-ux which sometimes loses data. Apparently the
1474 code which blocks the master process when the internal
1475 buffer fills up does not work. Other than this,
1476 though, everything else seems to work fine.
1477
1478 Since the latter lossage is more benign, we may as well
1479 lose that way. -- cph */
1480#ifdef FIONBIO
1481#if defined(UNIX98_PTYS)
1482 {
1483 int on = 1;
1484 ioctl (fd, FIONBIO, &on);
1485 }
1486#endif
1487#endif
1488}
1489#endif /* HAVE_PTYS */
1490\f
1491/* init_system_name sets up the string for the Lisp function
1492 system-name to return. */
1493
1494extern Lisp_Object Vsystem_name;
1495
1496#ifdef HAVE_SOCKETS
1497#include <sys/socket.h>
1498#include <netdb.h>
1499#endif /* HAVE_SOCKETS */
1500
1501#ifdef TRY_AGAIN
1502#ifndef HAVE_H_ERRNO
1503extern int h_errno;
1504#endif
1505#endif /* TRY_AGAIN */
1506
1507void
1508init_system_name (void)
1509{
1510#ifndef HAVE_GETHOSTNAME
1511 struct utsname uts;
1512 uname (&uts);
1513 Vsystem_name = build_string (uts.nodename);
1514#else /* HAVE_GETHOSTNAME */
1515 unsigned int hostname_size = 256;
1516 char *hostname = (char *) alloca (hostname_size);
1517
1518 /* Try to get the host name; if the buffer is too short, try
1519 again. Apparently, the only indication gethostname gives of
1520 whether the buffer was large enough is the presence or absence
1521 of a '\0' in the string. Eech. */
1522 for (;;)
1523 {
1524 gethostname (hostname, hostname_size - 1);
1525 hostname[hostname_size - 1] = '\0';
1526
1527 /* Was the buffer large enough for the '\0'? */
1528 if (strlen (hostname) < hostname_size - 1)
1529 break;
1530
1531 hostname_size <<= 1;
1532 hostname = (char *) alloca (hostname_size);
1533 }
1534#ifdef HAVE_SOCKETS
1535 /* Turn the hostname into the official, fully-qualified hostname.
1536 Don't do this if we're going to dump; this can confuse system
1537 libraries on some machines and make the dumped emacs core dump. */
1538#ifndef CANNOT_DUMP
1539 if (initialized)
1540#endif /* not CANNOT_DUMP */
1541 if (! strchr (hostname, '.'))
1542 {
1543 int count;
1544#ifdef HAVE_GETADDRINFO
1545 struct addrinfo *res;
1546 struct addrinfo hints;
1547 int ret;
1548
1549 memset (&hints, 0, sizeof (hints));
1550 hints.ai_socktype = SOCK_STREAM;
1551 hints.ai_flags = AI_CANONNAME;
1552
1553 for (count = 0;; count++)
1554 {
1555 if ((ret = getaddrinfo (hostname, NULL, &hints, &res)) == 0
1556 || ret != EAI_AGAIN)
1557 break;
1558
1559 if (count >= 5)
1560 break;
1561 Fsleep_for (make_number (1), Qnil);
1562 }
1563
1564 if (ret == 0)
1565 {
1566 struct addrinfo *it = res;
1567 while (it)
1568 {
1569 char *fqdn = it->ai_canonname;
1570 if (fqdn && strchr (fqdn, '.')
1571 && strcmp (fqdn, "localhost.localdomain") != 0)
1572 break;
1573 it = it->ai_next;
1574 }
1575 if (it)
1576 {
1577 hostname = alloca (strlen (it->ai_canonname) + 1);
1578 strcpy (hostname, it->ai_canonname);
1579 }
1580 freeaddrinfo (res);
1581 }
1582#else /* !HAVE_GETADDRINFO */
1583 struct hostent *hp;
1584 for (count = 0;; count++)
1585 {
1586
1587#ifdef TRY_AGAIN
1588 h_errno = 0;
1589#endif
1590 hp = gethostbyname (hostname);
1591#ifdef TRY_AGAIN
1592 if (! (hp == 0 && h_errno == TRY_AGAIN))
1593#endif
1594
1595 break;
1596
1597 if (count >= 5)
1598 break;
1599 Fsleep_for (make_number (1), Qnil);
1600 }
1601
1602 if (hp)
1603 {
1604 char *fqdn = (char *) hp->h_name;
1605
1606 if (!strchr (fqdn, '.'))
1607 {
1608 /* We still don't have a fully qualified domain name.
1609 Try to find one in the list of alternate names */
1610 char **alias = hp->h_aliases;
1611 while (*alias
1612 && (!strchr (*alias, '.')
1613 || !strcmp (*alias, "localhost.localdomain")))
1614 alias++;
1615 if (*alias)
1616 fqdn = *alias;
1617 }
1618 hostname = fqdn;
1619 }
1620#endif /* !HAVE_GETADDRINFO */
1621 }
1622#endif /* HAVE_SOCKETS */
1623 Vsystem_name = build_string (hostname);
1624#endif /* HAVE_GETHOSTNAME */
1625 {
1626 unsigned char *p;
1627 for (p = SDATA (Vsystem_name); *p; p++)
1628 if (*p == ' ' || *p == '\t')
1629 *p = '-';
1630 }
1631}
1632\f
1633#ifndef MSDOS
1634#if !defined (HAVE_SELECT)
1635
1636#include "sysselect.h"
1637#undef select
1638
1639#if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
1640/* Cause explanatory error message at compile time,
1641 since the select emulation is not good enough for X. */
1642int *x = &x_windows_lose_if_no_select_system_call;
1643#endif
1644
1645/* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1646 * Only checks read descriptors.
1647 */
1648/* How long to wait between checking fds in select */
1649#define SELECT_PAUSE 1
1650int select_alarmed;
1651
1652/* For longjmp'ing back to read_input_waiting. */
1653
1654jmp_buf read_alarm_throw;
1655
1656/* Nonzero if the alarm signal should throw back to read_input_waiting.
1657 The read_socket_hook function sets this to 1 while it is waiting. */
1658
1659int read_alarm_should_throw;
1660
1661void
1662select_alarm (int ignore)
1663{
1664 select_alarmed = 1;
1665 signal (SIGALRM, SIG_IGN);
1666 SIGNAL_THREAD_CHECK (SIGALRM);
1667 if (read_alarm_should_throw)
1668 longjmp (read_alarm_throw, 1);
1669}
1670
1671#ifndef WINDOWSNT
1672/* Only rfds are checked. */
1673int
1674sys_select (int nfds,
1675 SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
1676 EMACS_TIME *timeout)
1677{
1678 /* XXX This needs to be updated for multi-tty support. Is there
1679 anybody who needs to emulate select these days? */
1680 int ravail = 0;
1681 SELECT_TYPE orfds;
1682 int timeoutval;
1683 int *local_timeout;
1684 extern int proc_buffered_char[];
1685 extern int process_tick, update_tick;
1686 unsigned char buf;
1687
1688#if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
1689 /* If we're using X, then the native select will work; we only need the
1690 emulation for non-X usage. */
1691 if (!NILP (Vinitial_window_system))
1692 return select (nfds, rfds, wfds, efds, timeout);
1693#endif
1694 timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
1695 local_timeout = &timeoutval;
1696 FD_ZERO (&orfds);
1697 if (rfds)
1698 {
1699 orfds = *rfds;
1700 FD_ZERO (rfds);
1701 }
1702 if (wfds)
1703 FD_ZERO (wfds);
1704 if (efds)
1705 FD_ZERO (efds);
1706
1707 /* If we are looking only for the terminal, with no timeout,
1708 just read it and wait -- that's more efficient. */
1709 if (*local_timeout == 100000 && process_tick == update_tick
1710 && FD_ISSET (0, &orfds))
1711 {
1712 int fd;
1713 for (fd = 1; fd < nfds; ++fd)
1714 if (FD_ISSET (fd, &orfds))
1715 goto hardway;
1716 if (! detect_input_pending ())
1717 read_input_waiting ();
1718 FD_SET (0, rfds);
1719 return 1;
1720 }
1721
1722 hardway:
1723 /* Once a second, till the timer expires, check all the flagged read
1724 * descriptors to see if any input is available. If there is some then
1725 * set the corresponding bit in the return copy of rfds.
1726 */
1727 while (1)
1728 {
1729 register int to_check, fd;
1730
1731 if (rfds)
1732 {
1733 for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
1734 {
1735 if (FD_ISSET (fd, &orfds))
1736 {
1737 int avail = 0, status = 0;
1738
1739 if (fd == 0)
1740 avail = detect_input_pending (); /* Special keyboard handler */
1741 else
1742 {
1743#ifdef FIONREAD
1744 status = ioctl (fd, FIONREAD, &avail);
1745#else /* no FIONREAD */
1746 /* Hoping it will return -1 if nothing available
1747 or 0 if all 0 chars requested are read. */
1748 if (proc_buffered_char[fd] >= 0)
1749 avail = 1;
1750 else
1751 {
1752 avail = read (fd, &buf, 1);
1753 if (avail > 0)
1754 proc_buffered_char[fd] = buf;
1755 }
1756#endif /* no FIONREAD */
1757 }
1758 if (status >= 0 && avail > 0)
1759 {
1760 FD_SET (fd, rfds);
1761 ravail++;
1762 }
1763 }
1764 }
1765 }
1766 if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
1767 break;
1768
1769 turn_on_atimers (0);
1770 signal (SIGALRM, select_alarm);
1771 select_alarmed = 0;
1772 alarm (SELECT_PAUSE);
1773
1774 /* Wait for a SIGALRM (or maybe a SIGTINT) */
1775 while (select_alarmed == 0 && *local_timeout != 0
1776 && process_tick == update_tick)
1777 {
1778 /* If we are interested in terminal input,
1779 wait by reading the terminal.
1780 That makes instant wakeup for terminal input at least. */
1781 if (FD_ISSET (0, &orfds))
1782 {
1783 read_input_waiting ();
1784 if (detect_input_pending ())
1785 select_alarmed = 1;
1786 }
1787 else
1788 pause ();
1789 }
1790 (*local_timeout) -= SELECT_PAUSE;
1791
1792 /* Reset the old alarm if there was one. */
1793 turn_on_atimers (1);
1794
1795 if (*local_timeout == 0) /* Stop on timer being cleared */
1796 break;
1797 }
1798 return ravail;
1799}
1800#endif /* not WINDOWSNT */
1801
1802/* Read keyboard input into the standard buffer,
1803 waiting for at least one character. */
1804
1805void
1806read_input_waiting (void)
1807{
1808 /* XXX This needs to be updated for multi-tty support. Is there
1809 anybody who needs to emulate select these days? */
1810 int nread, i;
1811
1812 if (read_socket_hook)
1813 {
1814 struct input_event hold_quit;
1815
1816 EVENT_INIT (hold_quit);
1817 hold_quit.kind = NO_EVENT;
1818
1819 read_alarm_should_throw = 0;
1820 if (! setjmp (read_alarm_throw))
1821 nread = (*read_socket_hook) (0, 1, &hold_quit);
1822 else
1823 nread = -1;
1824
1825 if (hold_quit.kind != NO_EVENT)
1826 kbd_buffer_store_event (&hold_quit);
1827 }
1828 else
1829 {
1830 struct input_event e;
1831 char buf[3];
1832 nread = read (fileno (stdin), buf, 1);
1833 EVENT_INIT (e);
1834
1835 /* Scan the chars for C-g and store them in kbd_buffer. */
1836 e.kind = ASCII_KEYSTROKE_EVENT;
1837 e.frame_or_window = selected_frame;
1838 e.modifiers = 0;
1839 for (i = 0; i < nread; i++)
1840 {
1841 /* Convert chars > 0177 to meta events if desired.
1842 We do this under the same conditions that read_avail_input does. */
1843 if (read_socket_hook == 0)
1844 {
1845 /* If the user says she has a meta key, then believe her. */
1846 if (meta_key == 1 && (buf[i] & 0x80))
1847 e.modifiers = meta_modifier;
1848 if (meta_key != 2)
1849 buf[i] &= ~0x80;
1850 }
1851
1852 XSETINT (e.code, buf[i]);
1853 kbd_buffer_store_event (&e);
1854 /* Don't look at input that follows a C-g too closely.
1855 This reduces lossage due to autorepeat on C-g. */
1856 if (buf[i] == quit_char)
1857 break;
1858 }
1859 }
1860}
1861
1862#if !defined (HAVE_SELECT)
1863#define select sys_select
1864#endif
1865
1866#endif /* not HAVE_SELECT */
1867#endif /* not MSDOS */
1868\f
1869/* POSIX signals support - DJB */
1870/* Anyone with POSIX signals should have ANSI C declarations */
1871
1872sigset_t empty_mask, full_mask;
1873
1874#ifndef WINDOWSNT
1875
1876signal_handler_t
1877sys_signal (int signal_number, signal_handler_t action)
1878{
1879 struct sigaction new_action, old_action;
1880 sigemptyset (&new_action.sa_mask);
1881 new_action.sa_handler = action;
1882 new_action.sa_flags = 0;
1883#if defined (SA_RESTART)
1884 /* Emacs mostly works better with restartable system services. If this
1885 flag exists, we probably want to turn it on here.
1886 However, on some systems this resets the timeout of `select'
1887 which means that `select' never finishes if it keeps getting signals.
1888 BROKEN_SA_RESTART is defined on those systems. */
1889 /* It's not clear why the comment above says "mostly works better". --Stef
1890 When SYNC_INPUT is set, we don't want SA_RESTART because we need to poll
1891 for pending input so we need long-running syscalls to be interrupted
1892 after a signal that sets the interrupt_input_pending flag. */
1893 /* Non-interactive keyboard input goes through stdio, where we always
1894 want restartable system calls. */
1895# if defined (BROKEN_SA_RESTART) || defined(SYNC_INPUT)
1896 if (noninteractive)
1897# endif
1898 new_action.sa_flags = SA_RESTART;
1899#endif
1900 sigaction (signal_number, &new_action, &old_action);
1901 return (old_action.sa_handler);
1902}
1903
1904#endif /* WINDOWSNT */
1905
1906#ifndef __GNUC__
1907/* If we're compiling with GCC, we don't need this function, since it
1908 can be written as a macro. */
1909sigset_t
1910sys_sigmask (int sig)
1911{
1912 sigset_t mask;
1913 sigemptyset (&mask);
1914 sigaddset (&mask, sig);
1915 return mask;
1916}
1917#endif
1918
1919/* I'd like to have these guys return pointers to the mask storage in here,
1920 but there'd be trouble if the code was saving multiple masks. I'll be
1921 safe and pass the structure. It normally won't be more than 2 bytes
1922 anyhow. - DJB */
1923
1924sigset_t
1925sys_sigblock (sigset_t new_mask)
1926{
1927 sigset_t old_mask;
1928 sigprocmask (SIG_BLOCK, &new_mask, &old_mask);
1929 return (old_mask);
1930}
1931
1932sigset_t
1933sys_sigunblock (sigset_t new_mask)
1934{
1935 sigset_t old_mask;
1936 sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask);
1937 return (old_mask);
1938}
1939
1940sigset_t
1941sys_sigsetmask (sigset_t new_mask)
1942{
1943 sigset_t old_mask;
1944 sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
1945 return (old_mask);
1946}
1947
1948\f
1949#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
1950static char *my_sys_siglist[NSIG];
1951# ifdef sys_siglist
1952# undef sys_siglist
1953# endif
1954# define sys_siglist my_sys_siglist
1955#endif
1956
1957void
1958init_signals (void)
1959{
1960 sigemptyset (&empty_mask);
1961 sigfillset (&full_mask);
1962
1963#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
1964 if (! initialized)
1965 {
1966# ifdef SIGABRT
1967 sys_siglist[SIGABRT] = "Aborted";
1968# endif
1969# ifdef SIGAIO
1970 sys_siglist[SIGAIO] = "LAN I/O interrupt";
1971# endif
1972# ifdef SIGALRM
1973 sys_siglist[SIGALRM] = "Alarm clock";
1974# endif
1975# ifdef SIGBUS
1976 sys_siglist[SIGBUS] = "Bus error";
1977# endif
1978# ifdef SIGCLD
1979 sys_siglist[SIGCLD] = "Child status changed";
1980# endif
1981# ifdef SIGCHLD
1982 sys_siglist[SIGCHLD] = "Child status changed";
1983# endif
1984# ifdef SIGCONT
1985 sys_siglist[SIGCONT] = "Continued";
1986# endif
1987# ifdef SIGDANGER
1988 sys_siglist[SIGDANGER] = "Swap space dangerously low";
1989# endif
1990# ifdef SIGDGNOTIFY
1991 sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
1992# endif
1993# ifdef SIGEMT
1994 sys_siglist[SIGEMT] = "Emulation trap";
1995# endif
1996# ifdef SIGFPE
1997 sys_siglist[SIGFPE] = "Arithmetic exception";
1998# endif
1999# ifdef SIGFREEZE
2000 sys_siglist[SIGFREEZE] = "SIGFREEZE";
2001# endif
2002# ifdef SIGGRANT
2003 sys_siglist[SIGGRANT] = "Monitor mode granted";
2004# endif
2005# ifdef SIGHUP
2006 sys_siglist[SIGHUP] = "Hangup";
2007# endif
2008# ifdef SIGILL
2009 sys_siglist[SIGILL] = "Illegal instruction";
2010# endif
2011# ifdef SIGINT
2012 sys_siglist[SIGINT] = "Interrupt";
2013# endif
2014# ifdef SIGIO
2015 sys_siglist[SIGIO] = "I/O possible";
2016# endif
2017# ifdef SIGIOINT
2018 sys_siglist[SIGIOINT] = "I/O intervention required";
2019# endif
2020# ifdef SIGIOT
2021 sys_siglist[SIGIOT] = "IOT trap";
2022# endif
2023# ifdef SIGKILL
2024 sys_siglist[SIGKILL] = "Killed";
2025# endif
2026# ifdef SIGLOST
2027 sys_siglist[SIGLOST] = "Resource lost";
2028# endif
2029# ifdef SIGLWP
2030 sys_siglist[SIGLWP] = "SIGLWP";
2031# endif
2032# ifdef SIGMSG
2033 sys_siglist[SIGMSG] = "Monitor mode data available";
2034# endif
2035# ifdef SIGPHONE
2036 sys_siglist[SIGWIND] = "SIGPHONE";
2037# endif
2038# ifdef SIGPIPE
2039 sys_siglist[SIGPIPE] = "Broken pipe";
2040# endif
2041# ifdef SIGPOLL
2042 sys_siglist[SIGPOLL] = "Pollable event occurred";
2043# endif
2044# ifdef SIGPROF
2045 sys_siglist[SIGPROF] = "Profiling timer expired";
2046# endif
2047# ifdef SIGPTY
2048 sys_siglist[SIGPTY] = "PTY I/O interrupt";
2049# endif
2050# ifdef SIGPWR
2051 sys_siglist[SIGPWR] = "Power-fail restart";
2052# endif
2053# ifdef SIGQUIT
2054 sys_siglist[SIGQUIT] = "Quit";
2055# endif
2056# ifdef SIGRETRACT
2057 sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode";
2058# endif
2059# ifdef SIGSAK
2060 sys_siglist[SIGSAK] = "Secure attention";
2061# endif
2062# ifdef SIGSEGV
2063 sys_siglist[SIGSEGV] = "Segmentation violation";
2064# endif
2065# ifdef SIGSOUND
2066 sys_siglist[SIGSOUND] = "Sound completed";
2067# endif
2068# ifdef SIGSTOP
2069 sys_siglist[SIGSTOP] = "Stopped (signal)";
2070# endif
2071# ifdef SIGSTP
2072 sys_siglist[SIGSTP] = "Stopped (user)";
2073# endif
2074# ifdef SIGSYS
2075 sys_siglist[SIGSYS] = "Bad argument to system call";
2076# endif
2077# ifdef SIGTERM
2078 sys_siglist[SIGTERM] = "Terminated";
2079# endif
2080# ifdef SIGTHAW
2081 sys_siglist[SIGTHAW] = "SIGTHAW";
2082# endif
2083# ifdef SIGTRAP
2084 sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
2085# endif
2086# ifdef SIGTSTP
2087 sys_siglist[SIGTSTP] = "Stopped (user)";
2088# endif
2089# ifdef SIGTTIN
2090 sys_siglist[SIGTTIN] = "Stopped (tty input)";
2091# endif
2092# ifdef SIGTTOU
2093 sys_siglist[SIGTTOU] = "Stopped (tty output)";
2094# endif
2095# ifdef SIGURG
2096 sys_siglist[SIGURG] = "Urgent I/O condition";
2097# endif
2098# ifdef SIGUSR1
2099 sys_siglist[SIGUSR1] = "User defined signal 1";
2100# endif
2101# ifdef SIGUSR2
2102 sys_siglist[SIGUSR2] = "User defined signal 2";
2103# endif
2104# ifdef SIGVTALRM
2105 sys_siglist[SIGVTALRM] = "Virtual timer expired";
2106# endif
2107# ifdef SIGWAITING
2108 sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
2109# endif
2110# ifdef SIGWINCH
2111 sys_siglist[SIGWINCH] = "Window size changed";
2112# endif
2113# ifdef SIGWIND
2114 sys_siglist[SIGWIND] = "SIGWIND";
2115# endif
2116# ifdef SIGXCPU
2117 sys_siglist[SIGXCPU] = "CPU time limit exceeded";
2118# endif
2119# ifdef SIGXFSZ
2120 sys_siglist[SIGXFSZ] = "File size limit exceeded";
2121# endif
2122 }
2123#endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
2124}
2125\f
2126#ifndef HAVE_RANDOM
2127#ifdef random
2128#define HAVE_RANDOM
2129#endif
2130#endif
2131
2132/* Figure out how many bits the system's random number generator uses.
2133 `random' and `lrand48' are assumed to return 31 usable bits.
2134 BSD `rand' returns a 31 bit value but the low order bits are unusable;
2135 so we'll shift it and treat it like the 15-bit USG `rand'. */
2136
2137#ifndef RAND_BITS
2138# ifdef HAVE_RANDOM
2139# define RAND_BITS 31
2140# else /* !HAVE_RANDOM */
2141# ifdef HAVE_LRAND48
2142# define RAND_BITS 31
2143# define random lrand48
2144# else /* !HAVE_LRAND48 */
2145# define RAND_BITS 15
2146# if RAND_MAX == 32767
2147# define random rand
2148# else /* RAND_MAX != 32767 */
2149# if RAND_MAX == 2147483647
2150# define random() (rand () >> 16)
2151# else /* RAND_MAX != 2147483647 */
2152# ifdef USG
2153# define random rand
2154# else
2155# define random() (rand () >> 16)
2156# endif /* !USG */
2157# endif /* RAND_MAX != 2147483647 */
2158# endif /* RAND_MAX != 32767 */
2159# endif /* !HAVE_LRAND48 */
2160# endif /* !HAVE_RANDOM */
2161#endif /* !RAND_BITS */
2162
2163void
2164seed_random (long int arg)
2165{
2166#ifdef HAVE_RANDOM
2167 srandom ((unsigned int)arg);
2168#else
2169# ifdef HAVE_LRAND48
2170 srand48 (arg);
2171# else
2172 srand ((unsigned int)arg);
2173# endif
2174#endif
2175}
2176
2177/*
2178 * Build a full Emacs-sized word out of whatever we've got.
2179 * This suffices even for a 64-bit architecture with a 15-bit rand.
2180 */
2181long
2182get_random (void)
2183{
2184 long val = random ();
2185#if VALBITS > RAND_BITS
2186 val = (val << RAND_BITS) ^ random ();
2187#if VALBITS > 2*RAND_BITS
2188 val = (val << RAND_BITS) ^ random ();
2189#if VALBITS > 3*RAND_BITS
2190 val = (val << RAND_BITS) ^ random ();
2191#if VALBITS > 4*RAND_BITS
2192 val = (val << RAND_BITS) ^ random ();
2193#endif /* need at least 5 */
2194#endif /* need at least 4 */
2195#endif /* need at least 3 */
2196#endif /* need at least 2 */
2197 return val & ((1L << VALBITS) - 1);
2198}
2199
2200#ifndef HAVE_STRERROR
2201#ifndef WINDOWSNT
2202char *
2203strerror (errnum)
2204 int errnum;
2205{
2206 extern char *sys_errlist[];
2207 extern int sys_nerr;
2208
2209 if (errnum >= 0 && errnum < sys_nerr)
2210 return sys_errlist[errnum];
2211 return (char *) "Unknown error";
2212}
2213#endif /* not WINDOWSNT */
2214#endif /* ! HAVE_STRERROR */
2215\f
2216int
2217emacs_open (const char *path, int oflag, int mode)
2218{
2219 register int rtnval;
2220
2221 while ((rtnval = open (path, oflag, mode)) == -1
2222 && (errno == EINTR))
2223 QUIT;
2224 return (rtnval);
2225}
2226
2227int
2228emacs_close (int fd)
2229{
2230 int did_retry = 0;
2231 register int rtnval;
2232
2233 while ((rtnval = close (fd)) == -1
2234 && (errno == EINTR))
2235 did_retry = 1;
2236
2237 /* If close is interrupted SunOS 4.1 may or may not have closed the
2238 file descriptor. If it did the second close will fail with
2239 errno = EBADF. That means we have succeeded. */
2240 if (rtnval == -1 && did_retry && errno == EBADF)
2241 return 0;
2242
2243 return rtnval;
2244}
2245
2246int
2247emacs_read (int fildes, char *buf, unsigned int nbyte)
2248{
2249 register int rtnval;
2250
2251 while ((rtnval = read (fildes, buf, nbyte)) == -1
2252 && (errno == EINTR))
2253 QUIT;
2254 return (rtnval);
2255}
2256
2257int
2258emacs_write (int fildes, const char *buf, unsigned int nbyte)
2259{
2260 register int rtnval, bytes_written;
2261
2262 bytes_written = 0;
2263
2264 while (nbyte > 0)
2265 {
2266 rtnval = write (fildes, buf, nbyte);
2267
2268 if (rtnval == -1)
2269 {
2270 if (errno == EINTR)
2271 {
2272#ifdef SYNC_INPUT
2273 /* I originally used `QUIT' but that might causes files to
2274 be truncated if you hit C-g in the middle of it. --Stef */
2275 process_pending_signals ();
2276#endif
2277 continue;
2278 }
2279 else
2280 return (bytes_written ? bytes_written : -1);
2281 }
2282
2283 buf += rtnval;
2284 nbyte -= rtnval;
2285 bytes_written += rtnval;
2286 }
2287 return (bytes_written);
2288}
2289\f
2290#ifdef USG
2291/*
2292 * All of the following are for USG.
2293 *
2294 * On USG systems the system calls are INTERRUPTIBLE by signals
2295 * that the user program has elected to catch. Thus the system call
2296 * must be retried in these cases. To handle this without massive
2297 * changes in the source code, we remap the standard system call names
2298 * to names for our own functions in sysdep.c that do the system call
2299 * with retries. Actually, for portability reasons, it is good
2300 * programming practice, as this example shows, to limit all actual
2301 * system calls to a single occurrence in the source. Sure, this
2302 * adds an extra level of function call overhead but it is almost
2303 * always negligible. Fred Fish, Unisoft Systems Inc.
2304 */
2305
2306/*
2307 * Warning, this function may not duplicate 4.2 action properly
2308 * under error conditions.
2309 */
2310
2311#ifndef MAXPATHLEN
2312/* In 4.1, param.h fails to define this. */
2313#define MAXPATHLEN 1024
2314#endif
2315
2316#ifndef HAVE_GETWD
2317
2318char *
2319getwd (char *pathname)
2320{
2321 char *npath, *spath;
2322 extern char *getcwd (char *, size_t);
2323
2324 BLOCK_INPUT; /* getcwd uses malloc */
2325 spath = npath = getcwd ((char *) 0, MAXPATHLEN);
2326 if (spath == 0)
2327 {
2328 UNBLOCK_INPUT;
2329 return spath;
2330 }
2331 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2332 up to first slash. Should be harmless on other systems. */
2333 while (*npath && *npath != '/')
2334 npath++;
2335 strcpy (pathname, npath);
2336 free (spath); /* getcwd uses malloc */
2337 UNBLOCK_INPUT;
2338 return pathname;
2339}
2340
2341#endif /* HAVE_GETWD */
2342
2343/*
2344 * Emulate rename using unlink/link. Note that this is
2345 * only partially correct. Also, doesn't enforce restriction
2346 * that files be of same type (regular->regular, dir->dir, etc).
2347 */
2348
2349#ifndef HAVE_RENAME
2350
2351int
2352rename (const char *from, const char *to)
2353{
2354 if (access (from, 0) == 0)
2355 {
2356 unlink (to);
2357 if (link (from, to) == 0)
2358 if (unlink (from) == 0)
2359 return (0);
2360 }
2361 return (-1);
2362}
2363
2364#endif
2365
2366
2367#if defined(HPUX) && !defined(HAVE_PERROR)
2368
2369/* HPUX curses library references perror, but as far as we know
2370 it won't be called. Anyway this definition will do for now. */
2371
2372void
2373perror (void)
2374{
2375}
2376#endif /* HPUX and not HAVE_PERROR */
2377
2378#ifndef HAVE_DUP2
2379
2380/*
2381 * Emulate BSD dup2. First close newd if it already exists.
2382 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2383 * until we are, then close the unsuccessful ones.
2384 */
2385
2386int
2387dup2 (int oldd, int newd)
2388{
2389 register int fd, ret;
2390
2391 emacs_close (newd);
2392
2393#ifdef F_DUPFD
2394 return fcntl (oldd, F_DUPFD, newd);
2395#else
2396 fd = dup (old);
2397 if (fd == -1)
2398 return -1;
2399 if (fd == new)
2400 return new;
2401 ret = dup2 (old,new);
2402 emacs_close (fd);
2403 return ret;
2404#endif
2405}
2406
2407#endif /* not HAVE_DUP2 */
2408
2409/*
2410 * Gettimeofday. Simulate as much as possible. Only accurate
2411 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2412 * Only needed when subprocesses are defined.
2413 */
2414
2415#ifndef HAVE_GETTIMEOFDAY
2416#ifdef HAVE_TIMEVAL
2417
2418/* ARGSUSED */
2419int
2420gettimeofday (struct timeval *tp, struct timezone *tzp)
2421{
2422 extern long time (long);
2423
2424 tp->tv_sec = time ((long *)0);
2425 tp->tv_usec = 0;
2426 if (tzp != 0)
2427 tzp->tz_minuteswest = -1;
2428 return 0;
2429}
2430
2431#endif
2432#endif /* !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL */
2433
2434/*
2435 * This function will go away as soon as all the stubs fixed. (fnf)
2436 */
2437
2438void
2439croak (char *badfunc)
2440{
2441 printf ("%s not yet implemented\r\n", badfunc);
2442 reset_all_sys_modes ();
2443 exit (1);
2444}
2445
2446#endif /* USG */
2447\f
2448/* Directory routines for systems that don't have them. */
2449
2450#ifdef SYSV_SYSTEM_DIR
2451
2452#include <dirent.h>
2453
2454#if !defined (HAVE_CLOSEDIR)
2455
2456int
2457closedir (DIR *dirp /* stream from opendir */)
2458{
2459 int rtnval;
2460
2461 rtnval = emacs_close (dirp->dd_fd);
2462 xfree ((char *) dirp);
2463
2464 return rtnval;
2465}
2466#endif /* not HAVE_CLOSEDIR */
2467#endif /* SYSV_SYSTEM_DIR */
2468
2469\f
2470int
2471set_file_times (const char *filename, EMACS_TIME atime, EMACS_TIME mtime)
2472{
2473#ifdef HAVE_UTIMES
2474 struct timeval tv[2];
2475 tv[0] = atime;
2476 tv[1] = mtime;
2477 return utimes (filename, tv);
2478#else /* not HAVE_UTIMES */
2479 struct utimbuf utb;
2480 utb.actime = EMACS_SECS (atime);
2481 utb.modtime = EMACS_SECS (mtime);
2482 return utime (filename, &utb);
2483#endif /* not HAVE_UTIMES */
2484}
2485\f
2486/* mkdir and rmdir functions, for systems which don't have them. */
2487
2488#ifndef HAVE_MKDIR
2489/*
2490 * Written by Robert Rother, Mariah Corporation, August 1985.
2491 *
2492 * If you want it, it's yours. All I ask in return is that if you
2493 * figure out how to do this in a Bourne Shell script you send me
2494 * a copy.
2495 * sdcsvax!rmr or rmr@uscd
2496 *
2497 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
2498 * subroutine. 11Mar86; hoptoad!gnu
2499 *
2500 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
2501 * subroutine didn't return EEXIST. It does now.
2502 */
2503
2504/*
2505 * Make a directory.
2506 */
2507int
2508mkdir (char *dpath, int dmode)
2509{
2510 int cpid, status, fd;
2511 struct stat statbuf;
2512
2513 if (stat (dpath, &statbuf) == 0)
2514 {
2515 errno = EEXIST; /* Stat worked, so it already exists */
2516 return -1;
2517 }
2518
2519 /* If stat fails for a reason other than non-existence, return error */
2520 if (errno != ENOENT)
2521 return -1;
2522
2523 synch_process_alive = 1;
2524 switch (cpid = fork ())
2525 {
2526
2527 case -1: /* Error in fork */
2528 return (-1); /* Errno is set already */
2529
2530 case 0: /* Child process */
2531 /*
2532 * Cheap hack to set mode of new directory. Since this
2533 * child process is going away anyway, we zap its umask.
2534 * FIXME, this won't suffice to set SUID, SGID, etc. on this
2535 * directory. Does anybody care?
2536 */
2537 status = umask (0); /* Get current umask */
2538 status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
2539 fd = emacs_open ("/dev/null", O_RDWR, 0);
2540 if (fd >= 0)
2541 {
2542 dup2 (fd, 0);
2543 dup2 (fd, 1);
2544 dup2 (fd, 2);
2545 }
2546 execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
2547 _exit (-1); /* Can't exec /bin/mkdir */
2548
2549 default: /* Parent process */
2550 wait_for_termination (cpid);
2551 }
2552
2553 if (synch_process_death != 0 || synch_process_retcode != 0
2554 || synch_process_termsig != 0)
2555 {
2556 errno = EIO; /* We don't know why, but */
2557 return -1; /* /bin/mkdir failed */
2558 }
2559
2560 return 0;
2561}
2562#endif /* not HAVE_MKDIR */
2563
2564#ifndef HAVE_RMDIR
2565int
2566rmdir (char *dpath)
2567{
2568 int cpid, status, fd;
2569 struct stat statbuf;
2570
2571 if (stat (dpath, &statbuf) != 0)
2572 {
2573 /* Stat just set errno. We don't have to */
2574 return -1;
2575 }
2576
2577 synch_process_alive = 1;
2578 switch (cpid = fork ())
2579 {
2580
2581 case -1: /* Error in fork */
2582 return (-1); /* Errno is set already */
2583
2584 case 0: /* Child process */
2585 fd = emacs_open ("/dev/null", O_RDWR, 0);
2586 if (fd >= 0)
2587 {
2588 dup2 (fd, 0);
2589 dup2 (fd, 1);
2590 dup2 (fd, 2);
2591 }
2592 execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
2593 _exit (-1); /* Can't exec /bin/rmdir */
2594
2595 default: /* Parent process */
2596 wait_for_termination (cpid);
2597 }
2598
2599 if (synch_process_death != 0 || synch_process_retcode != 0
2600 || synch_process_termsig != 0)
2601 {
2602 errno = EIO; /* We don't know why, but */
2603 return -1; /* /bin/rmdir failed */
2604 }
2605
2606 return 0;
2607}
2608#endif /* !HAVE_RMDIR */
2609
2610\f
2611#ifndef HAVE_MEMSET
2612void *
2613memset (void *b, int n, size_t length)
2614{
2615 unsigned char *p = b;
2616 while (length-- > 0)
2617 *p++ = n;
2618 return b;
2619}
2620#endif /* !HAVE_MEMSET */
2621
2622#ifndef HAVE_MEMCPY
2623void *
2624memcpy (void *b1, void *b2, size_t length)
2625{
2626 unsigned char *p1 = b1, *p2 = b2;
2627 while (length-- > 0)
2628 *p1++ = *p2++;
2629 return b1;
2630}
2631#endif /* !HAVE_MEMCPY */
2632
2633#ifndef HAVE_MEMMOVE
2634void *
2635memmove (void *b1, void *b2, size_t length)
2636{
2637 unsigned char *p1 = b1, *p2 = b2;
2638 if (p1 < p2 || p1 >= p2 + length)
2639 while (length-- > 0)
2640 *p1++ = *p2++;
2641 else
2642 {
2643 p1 += length;
2644 p2 += length;
2645 while (length-- > 0)
2646 *--p1 = *--p2;
2647 }
2648 return b1;
2649}
2650#endif /* !HAVE_MEMCPY */
2651
2652#ifndef HAVE_MEMCMP
2653int
2654memcmp (void *b1, void *b2, size_t length)
2655{
2656 unsigned char *p1 = b1, *p2 = b2;
2657 while (length-- > 0)
2658 if (*p1++ != *p2++)
2659 return p1[-1] < p2[-1] ? -1 : 1;
2660 return 0;
2661}
2662#endif /* !HAVE_MEMCMP */
2663\f
2664#ifndef HAVE_STRSIGNAL
2665char *
2666strsignal (int code)
2667{
2668 char *signame = 0;
2669
2670 if (0 <= code && code < NSIG)
2671 {
2672 /* Cast to suppress warning if the table has const char *. */
2673 signame = (char *) sys_siglist[code];
2674 }
2675
2676 return signame;
2677}
2678#endif /* HAVE_STRSIGNAL */
2679\f
2680#ifdef HAVE_TERMIOS
2681/* For make-serial-process */
2682int
2683serial_open (char *port)
2684{
2685 int fd = -1;
2686
2687 fd = emacs_open ((char*) port,
2688 O_RDWR
2689#ifdef O_NONBLOCK
2690 | O_NONBLOCK
2691#else
2692 | O_NDELAY
2693#endif
2694#ifdef O_NOCTTY
2695 | O_NOCTTY
2696#endif
2697 , 0);
2698 if (fd < 0)
2699 {
2700 error ("Could not open %s: %s",
2701 port, emacs_strerror (errno));
2702 }
2703#ifdef TIOCEXCL
2704 ioctl (fd, TIOCEXCL, (char *) 0);
2705#endif
2706
2707 return fd;
2708}
2709#endif /* TERMIOS */
2710
2711#ifdef HAVE_TERMIOS
2712
2713#if !defined (HAVE_CFMAKERAW)
2714/* Workaround for targets which are missing cfmakeraw. */
2715/* Pasted from man page. */
2716static void
2717cfmakeraw (struct termios *termios_p)
2718{
2719 termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
2720 termios_p->c_oflag &= ~OPOST;
2721 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
2722 termios_p->c_cflag &= ~(CSIZE|PARENB);
2723 termios_p->c_cflag |= CS8;
2724}
2725#endif /* !defined (HAVE_CFMAKERAW */
2726
2727#if !defined (HAVE_CFSETSPEED)
2728/* Workaround for targets which are missing cfsetspeed. */
2729static int
2730cfsetspeed (struct termios *termios_p, speed_t vitesse)
2731{
2732 return (cfsetispeed (termios_p, vitesse)
2733 + cfsetospeed (termios_p, vitesse));
2734}
2735#endif
2736
2737/* For serial-process-configure */
2738void
2739serial_configure (struct Lisp_Process *p,
2740 Lisp_Object contact)
2741{
2742 Lisp_Object childp2 = Qnil;
2743 Lisp_Object tem = Qnil;
2744 struct termios attr;
2745 int err = -1;
2746 char summary[4] = "???"; /* This usually becomes "8N1". */
2747
2748 childp2 = Fcopy_sequence (p->childp);
2749
2750 /* Read port attributes and prepare default configuration. */
2751 err = tcgetattr (p->outfd, &attr);
2752 if (err != 0)
2753 error ("tcgetattr() failed: %s", emacs_strerror (errno));
2754 cfmakeraw (&attr);
2755#if defined (CLOCAL)
2756 attr.c_cflag |= CLOCAL;
2757#endif
2758#if defined (CREAD)
2759 attr.c_cflag |= CREAD;
2760#endif
2761
2762 /* Configure speed. */
2763 if (!NILP (Fplist_member (contact, QCspeed)))
2764 tem = Fplist_get (contact, QCspeed);
2765 else
2766 tem = Fplist_get (p->childp, QCspeed);
2767 CHECK_NUMBER (tem);
2768 err = cfsetspeed (&attr, XINT (tem));
2769 if (err != 0)
2770 error ("cfsetspeed(%d) failed: %s", XINT (tem), emacs_strerror (errno));
2771 childp2 = Fplist_put (childp2, QCspeed, tem);
2772
2773 /* Configure bytesize. */
2774 if (!NILP (Fplist_member (contact, QCbytesize)))
2775 tem = Fplist_get (contact, QCbytesize);
2776 else
2777 tem = Fplist_get (p->childp, QCbytesize);
2778 if (NILP (tem))
2779 tem = make_number (8);
2780 CHECK_NUMBER (tem);
2781 if (XINT (tem) != 7 && XINT (tem) != 8)
2782 error (":bytesize must be nil (8), 7, or 8");
2783 summary[0] = XINT (tem) + '0';
2784#if defined (CSIZE) && defined (CS7) && defined (CS8)
2785 attr.c_cflag &= ~CSIZE;
2786 attr.c_cflag |= ((XINT (tem) == 7) ? CS7 : CS8);
2787#else
2788 /* Don't error on bytesize 8, which should be set by cfmakeraw. */
2789 if (XINT (tem) != 8)
2790 error ("Bytesize cannot be changed");
2791#endif
2792 childp2 = Fplist_put (childp2, QCbytesize, tem);
2793
2794 /* Configure parity. */
2795 if (!NILP (Fplist_member (contact, QCparity)))
2796 tem = Fplist_get (contact, QCparity);
2797 else
2798 tem = Fplist_get (p->childp, QCparity);
2799 if (!NILP (tem) && !EQ (tem, Qeven) && !EQ (tem, Qodd))
2800 error (":parity must be nil (no parity), `even', or `odd'");
2801#if defined (PARENB) && defined (PARODD) && defined (IGNPAR) && defined (INPCK)
2802 attr.c_cflag &= ~(PARENB | PARODD);
2803 attr.c_iflag &= ~(IGNPAR | INPCK);
2804 if (NILP (tem))
2805 {
2806 summary[1] = 'N';
2807 }
2808 else if (EQ (tem, Qeven))
2809 {
2810 summary[1] = 'E';
2811 attr.c_cflag |= PARENB;
2812 attr.c_iflag |= (IGNPAR | INPCK);
2813 }
2814 else if (EQ (tem, Qodd))
2815 {
2816 summary[1] = 'O';
2817 attr.c_cflag |= (PARENB | PARODD);
2818 attr.c_iflag |= (IGNPAR | INPCK);
2819 }
2820#else
2821 /* Don't error on no parity, which should be set by cfmakeraw. */
2822 if (!NILP (tem))
2823 error ("Parity cannot be configured");
2824#endif
2825 childp2 = Fplist_put (childp2, QCparity, tem);
2826
2827 /* Configure stopbits. */
2828 if (!NILP (Fplist_member (contact, QCstopbits)))
2829 tem = Fplist_get (contact, QCstopbits);
2830 else
2831 tem = Fplist_get (p->childp, QCstopbits);
2832 if (NILP (tem))
2833 tem = make_number (1);
2834 CHECK_NUMBER (tem);
2835 if (XINT (tem) != 1 && XINT (tem) != 2)
2836 error (":stopbits must be nil (1 stopbit), 1, or 2");
2837 summary[2] = XINT (tem) + '0';
2838#if defined (CSTOPB)
2839 attr.c_cflag &= ~CSTOPB;
2840 if (XINT (tem) == 2)
2841 attr.c_cflag |= CSTOPB;
2842#else
2843 /* Don't error on 1 stopbit, which should be set by cfmakeraw. */
2844 if (XINT (tem) != 1)
2845 error ("Stopbits cannot be configured");
2846#endif
2847 childp2 = Fplist_put (childp2, QCstopbits, tem);
2848
2849 /* Configure flowcontrol. */
2850 if (!NILP (Fplist_member (contact, QCflowcontrol)))
2851 tem = Fplist_get (contact, QCflowcontrol);
2852 else
2853 tem = Fplist_get (p->childp, QCflowcontrol);
2854 if (!NILP (tem) && !EQ (tem, Qhw) && !EQ (tem, Qsw))
2855 error (":flowcontrol must be nil (no flowcontrol), `hw', or `sw'");
2856#if defined (CRTSCTS)
2857 attr.c_cflag &= ~CRTSCTS;
2858#endif
2859#if defined (CNEW_RTSCTS)
2860 attr.c_cflag &= ~CNEW_RTSCTS;
2861#endif
2862#if defined (IXON) && defined (IXOFF)
2863 attr.c_iflag &= ~(IXON | IXOFF);
2864#endif
2865 if (NILP (tem))
2866 {
2867 /* Already configured. */
2868 }
2869 else if (EQ (tem, Qhw))
2870 {
2871#if defined (CRTSCTS)
2872 attr.c_cflag |= CRTSCTS;
2873#elif defined (CNEW_RTSCTS)
2874 attr.c_cflag |= CNEW_RTSCTS;
2875#else
2876 error ("Hardware flowcontrol (RTS/CTS) not supported");
2877#endif
2878 }
2879 else if (EQ (tem, Qsw))
2880 {
2881#if defined (IXON) && defined (IXOFF)
2882 attr.c_iflag |= (IXON | IXOFF);
2883#else
2884 error ("Software flowcontrol (XON/XOFF) not supported");
2885#endif
2886 }
2887 childp2 = Fplist_put (childp2, QCflowcontrol, tem);
2888
2889 /* Activate configuration. */
2890 err = tcsetattr (p->outfd, TCSANOW, &attr);
2891 if (err != 0)
2892 error ("tcsetattr() failed: %s", emacs_strerror (errno));
2893
2894 childp2 = Fplist_put (childp2, QCsummary, build_string (summary));
2895 p->childp = childp2;
2896
2897}
2898#endif /* TERMIOS */
2899\f
2900/* System depended enumeration of and access to system processes a-la ps(1). */
2901
2902#ifdef HAVE_PROCFS
2903
2904/* Process enumeration and access via /proc. */
2905
2906Lisp_Object
2907list_system_processes (void)
2908{
2909 Lisp_Object procdir, match, proclist, next;
2910 struct gcpro gcpro1, gcpro2;
2911 register Lisp_Object tail;
2912
2913 GCPRO2 (procdir, match);
2914 /* For every process on the system, there's a directory in the
2915 "/proc" pseudo-directory whose name is the numeric ID of that
2916 process. */
2917 procdir = build_string ("/proc");
2918 match = build_string ("[0-9]+");
2919 proclist = directory_files_internal (procdir, Qnil, match, Qt, 0, Qnil);
2920
2921 /* `proclist' gives process IDs as strings. Destructively convert
2922 each string into a number. */
2923 for (tail = proclist; CONSP (tail); tail = next)
2924 {
2925 next = XCDR (tail);
2926 XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil));
2927 }
2928 UNGCPRO;
2929
2930 /* directory_files_internal returns the files in reverse order; undo
2931 that. */
2932 proclist = Fnreverse (proclist);
2933 return proclist;
2934}
2935
2936/* The WINDOWSNT implementation is in w32.c.
2937 The MSDOS implementation is in dosfns.c. */
2938#elif !defined (WINDOWSNT) && !defined (MSDOS)
2939
2940Lisp_Object
2941list_system_processes (void)
2942{
2943 return Qnil;
2944}
2945
2946#endif /* !defined (WINDOWSNT) */
2947
2948#ifdef GNU_LINUX
2949static void
2950time_from_jiffies (unsigned long long tval, long hz,
2951 time_t *sec, unsigned *usec)
2952{
2953 unsigned long long ullsec;
2954
2955 *sec = tval / hz;
2956 ullsec = *sec;
2957 tval -= ullsec * hz;
2958 /* Careful: if HZ > 1 million, then integer division by it yields zero. */
2959 if (hz <= 1000000)
2960 *usec = tval * 1000000 / hz;
2961 else
2962 *usec = tval / (hz / 1000000);
2963}
2964
2965static Lisp_Object
2966ltime_from_jiffies (unsigned long long tval, long hz)
2967{
2968 time_t sec;
2969 unsigned usec;
2970
2971 time_from_jiffies (tval, hz, &sec, &usec);
2972
2973 return list3 (make_number ((sec >> 16) & 0xffff),
2974 make_number (sec & 0xffff),
2975 make_number (usec));
2976}
2977
2978static void
2979get_up_time (time_t *sec, unsigned *usec)
2980{
2981 FILE *fup;
2982
2983 *sec = *usec = 0;
2984
2985 BLOCK_INPUT;
2986 fup = fopen ("/proc/uptime", "r");
2987
2988 if (fup)
2989 {
2990 double uptime, idletime;
2991
2992 /* The numbers in /proc/uptime use C-locale decimal point, but
2993 we already set ourselves to the C locale (see `fixup_locale'
2994 in emacs.c). */
2995 if (2 <= fscanf (fup, "%lf %lf", &uptime, &idletime))
2996 {
2997 *sec = uptime;
2998 *usec = (uptime - *sec) * 1000000;
2999 }
3000 fclose (fup);
3001 }
3002 UNBLOCK_INPUT;
3003}
3004
3005#define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
3006#define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12))
3007
3008static Lisp_Object
3009procfs_ttyname (int rdev)
3010{
3011 FILE *fdev = NULL;
3012 char name[PATH_MAX];
3013
3014 BLOCK_INPUT;
3015 fdev = fopen ("/proc/tty/drivers", "r");
3016
3017 if (fdev)
3018 {
3019 unsigned major;
3020 unsigned long minor_beg, minor_end;
3021 char minor[25]; /* 2 32-bit numbers + dash */
3022 char *endp;
3023
3024 while (!feof (fdev) && !ferror (fdev))
3025 {
3026 if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor)
3027 && major == MAJOR (rdev))
3028 {
3029 minor_beg = strtoul (minor, &endp, 0);
3030 if (*endp == '\0')
3031 minor_end = minor_beg;
3032 else if (*endp == '-')
3033 minor_end = strtoul (endp + 1, &endp, 0);
3034 else
3035 continue;
3036
3037 if (MINOR (rdev) >= minor_beg && MINOR (rdev) <= minor_end)
3038 {
3039 sprintf (name + strlen (name), "%u", MINOR (rdev));
3040 break;
3041 }
3042 }
3043 }
3044 fclose (fdev);
3045 }
3046 UNBLOCK_INPUT;
3047 return build_string (name);
3048}
3049
3050static unsigned long
3051procfs_get_total_memory (void)
3052{
3053 FILE *fmem = NULL;
3054 unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
3055
3056 BLOCK_INPUT;
3057 fmem = fopen ("/proc/meminfo", "r");
3058
3059 if (fmem)
3060 {
3061 unsigned long entry_value;
3062 char entry_name[20]; /* the longest I saw is 13+1 */
3063
3064 while (!feof (fmem) && !ferror (fmem))
3065 {
3066 if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value)
3067 && strcmp (entry_name, "MemTotal:") == 0)
3068 {
3069 retval = entry_value;
3070 break;
3071 }
3072 }
3073 fclose (fmem);
3074 }
3075 UNBLOCK_INPUT;
3076 return retval;
3077}
3078
3079Lisp_Object
3080system_process_attributes (Lisp_Object pid)
3081{
3082 char procfn[PATH_MAX], fn[PATH_MAX];
3083 struct stat st;
3084 struct passwd *pw;
3085 struct group *gr;
3086 long clocks_per_sec;
3087 char *procfn_end;
3088 char procbuf[1025], *p, *q;
3089 int fd;
3090 ssize_t nread;
3091 const char *cmd = NULL;
3092 char *cmdline = NULL;
3093 size_t cmdsize = 0, cmdline_size;
3094 unsigned char c;
3095 int proc_id, ppid, uid, gid, pgrp, sess, tty, tpgid, thcount;
3096 unsigned long long utime, stime, cutime, cstime, start;
3097 long priority, nice, rss;
3098 unsigned long minflt, majflt, cminflt, cmajflt, vsize;
3099 time_t sec;
3100 unsigned usec;
3101 EMACS_TIME tnow, tstart, tboot, telapsed;
3102 double pcpu, pmem;
3103 Lisp_Object attrs = Qnil;
3104 Lisp_Object cmd_str, decoded_cmd, tem;
3105 struct gcpro gcpro1, gcpro2;
3106 EMACS_INT uid_eint, gid_eint;
3107
3108 CHECK_NUMBER_OR_FLOAT (pid);
3109 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
3110 sprintf (procfn, "/proc/%u", proc_id);
3111 if (stat (procfn, &st) < 0)
3112 return attrs;
3113
3114 GCPRO2 (attrs, decoded_cmd);
3115
3116 /* euid egid */
3117 uid = st.st_uid;
3118 /* Use of EMACS_INT stops GCC whining about limited range of data type. */
3119 uid_eint = uid;
3120 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs);
3121 BLOCK_INPUT;
3122 pw = getpwuid (uid);
3123 UNBLOCK_INPUT;
3124 if (pw)
3125 attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
3126
3127 gid = st.st_gid;
3128 gid_eint = gid;
3129 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs);
3130 BLOCK_INPUT;
3131 gr = getgrgid (gid);
3132 UNBLOCK_INPUT;
3133 if (gr)
3134 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3135
3136 strcpy (fn, procfn);
3137 procfn_end = fn + strlen (fn);
3138 strcpy (procfn_end, "/stat");
3139 fd = emacs_open (fn, O_RDONLY, 0);
3140 if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof (procbuf) - 1)) > 0)
3141 {
3142 procbuf[nread] = '\0';
3143 p = procbuf;
3144
3145 p = strchr (p, '(');
3146 if (p != NULL)
3147 {
3148 q = strrchr (p + 1, ')');
3149 /* comm */
3150 if (q != NULL)
3151 {
3152 cmd = p + 1;
3153 cmdsize = q - cmd;
3154 }
3155 }
3156 else
3157 q = NULL;
3158 if (cmd == NULL)
3159 {
3160 cmd = "???";
3161 cmdsize = 3;
3162 }
3163 /* Command name is encoded in locale-coding-system; decode it. */
3164 cmd_str = make_unibyte_string (cmd, cmdsize);
3165 decoded_cmd = code_convert_string_norecord (cmd_str,
3166 Vlocale_coding_system, 0);
3167 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3168
3169 if (q)
3170 {
3171 EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint;
3172 p = q + 2;
3173 /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */
3174 sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld",
3175 &c, &ppid, &pgrp, &sess, &tty, &tpgid,
3176 &minflt, &cminflt, &majflt, &cmajflt,
3177 &utime, &stime, &cutime, &cstime,
3178 &priority, &nice, &thcount, &start, &vsize, &rss);
3179 {
3180 char state_str[2];
3181
3182 state_str[0] = c;
3183 state_str[1] = '\0';
3184 tem = build_string (state_str);
3185 attrs = Fcons (Fcons (Qstate, tem), attrs);
3186 }
3187 /* Stops GCC whining about limited range of data type. */
3188 ppid_eint = ppid;
3189 pgrp_eint = pgrp;
3190 sess_eint = sess;
3191 tpgid_eint = tpgid;
3192 thcount_eint = thcount;
3193 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid_eint)), attrs);
3194 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp_eint)), attrs);
3195 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess_eint)), attrs);
3196 attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs);
3197 attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs);
3198 attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs);
3199 attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs);
3200 attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs);
3201 attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs);
3202 clocks_per_sec = sysconf (_SC_CLK_TCK);
3203 if (clocks_per_sec < 0)
3204 clocks_per_sec = 100;
3205 attrs = Fcons (Fcons (Qutime,
3206 ltime_from_jiffies (utime, clocks_per_sec)),
3207 attrs);
3208 attrs = Fcons (Fcons (Qstime,
3209 ltime_from_jiffies (stime, clocks_per_sec)),
3210 attrs);
3211 attrs = Fcons (Fcons (Qtime,
3212 ltime_from_jiffies (stime+utime, clocks_per_sec)),
3213 attrs);
3214 attrs = Fcons (Fcons (Qcutime,
3215 ltime_from_jiffies (cutime, clocks_per_sec)),
3216 attrs);
3217 attrs = Fcons (Fcons (Qcstime,
3218 ltime_from_jiffies (cstime, clocks_per_sec)),
3219 attrs);
3220 attrs = Fcons (Fcons (Qctime,
3221 ltime_from_jiffies (cstime+cutime, clocks_per_sec)),
3222 attrs);
3223 attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs);
3224 attrs = Fcons (Fcons (Qnice, make_number (nice)), attrs);
3225 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs);
3226 EMACS_GET_TIME (tnow);
3227 get_up_time (&sec, &usec);
3228 EMACS_SET_SECS (telapsed, sec);
3229 EMACS_SET_USECS (telapsed, usec);
3230 EMACS_SUB_TIME (tboot, tnow, telapsed);
3231 time_from_jiffies (start, clocks_per_sec, &sec, &usec);
3232 EMACS_SET_SECS (tstart, sec);
3233 EMACS_SET_USECS (tstart, usec);
3234 EMACS_ADD_TIME (tstart, tboot, tstart);
3235 attrs = Fcons (Fcons (Qstart,
3236 list3 (make_number
3237 ((EMACS_SECS (tstart) >> 16) & 0xffff),
3238 make_number
3239 (EMACS_SECS (tstart) & 0xffff),
3240 make_number
3241 (EMACS_USECS (tstart)))),
3242 attrs);
3243 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs);
3244 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs);
3245 EMACS_SUB_TIME (telapsed, tnow, tstart);
3246 attrs = Fcons (Fcons (Qetime,
3247 list3 (make_number
3248 ((EMACS_SECS (telapsed) >> 16) & 0xffff),
3249 make_number
3250 (EMACS_SECS (telapsed) & 0xffff),
3251 make_number
3252 (EMACS_USECS (telapsed)))),
3253 attrs);
3254 time_from_jiffies (utime + stime, clocks_per_sec, &sec, &usec);
3255 pcpu = (sec + usec / 1000000.0) / (EMACS_SECS (telapsed) + EMACS_USECS (telapsed) / 1000000.0);
3256 if (pcpu > 1.0)
3257 pcpu = 1.0;
3258 attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs);
3259 pmem = 4.0 * 100 * rss / procfs_get_total_memory ();
3260 if (pmem > 100)
3261 pmem = 100;
3262 attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
3263 }
3264 }
3265 if (fd >= 0)
3266 emacs_close (fd);
3267
3268 /* args */
3269 strcpy (procfn_end, "/cmdline");
3270 fd = emacs_open (fn, O_RDONLY, 0);
3271 if (fd >= 0)
3272 {
3273 for (cmdline_size = 0; emacs_read (fd, &c, 1) == 1; cmdline_size++)
3274 {
3275 if (isspace (c) || c == '\\')
3276 cmdline_size++; /* for later quoting, see below */
3277 }
3278 if (cmdline_size)
3279 {
3280 cmdline = xmalloc (cmdline_size + 1);
3281 lseek (fd, 0L, SEEK_SET);
3282 cmdline[0] = '\0';
3283 if ((nread = read (fd, cmdline, cmdline_size)) >= 0)
3284 cmdline[nread++] = '\0';
3285 else
3286 {
3287 /* Assigning zero to `nread' makes us skip the following
3288 two loops, assign zero to cmdline_size, and enter the
3289 following `if' clause that handles unknown command
3290 lines. */
3291 nread = 0;
3292 }
3293 /* We don't want trailing null characters. */
3294 for (p = cmdline + nread - 1; p > cmdline && !*p; p--)
3295 nread--;
3296 for (p = cmdline; p < cmdline + nread; p++)
3297 {
3298 /* Escape-quote whitespace and backslashes. */
3299 if (isspace (*p) || *p == '\\')
3300 {
3301 memmove (p + 1, p, nread - (p - cmdline));
3302 nread++;
3303 *p++ = '\\';
3304 }
3305 else if (*p == '\0')
3306 *p = ' ';
3307 }
3308 cmdline_size = nread;
3309 }
3310 if (!cmdline_size)
3311 {
3312 if (!cmd)
3313 cmd = "???";
3314 if (!cmdsize)
3315 cmdsize = strlen (cmd);
3316 cmdline_size = cmdsize + 2;
3317 cmdline = xmalloc (cmdline_size + 1);
3318 strcpy (cmdline, "[");
3319 strcat (strncat (cmdline, cmd, cmdsize), "]");
3320 }
3321 emacs_close (fd);
3322 /* Command line is encoded in locale-coding-system; decode it. */
3323 cmd_str = make_unibyte_string (cmdline, cmdline_size);
3324 decoded_cmd = code_convert_string_norecord (cmd_str,
3325 Vlocale_coding_system, 0);
3326 xfree (cmdline);
3327 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3328 }
3329
3330 UNGCPRO;
3331 return attrs;
3332}
3333
3334#elif defined (SOLARIS2) && defined (HAVE_PROCFS)
3335
3336/* The <procfs.h> header does not like to be included if _LP64 is defined and
3337 __FILE_OFFSET_BITS == 64. This is an ugly workaround that. */
3338#if !defined (_LP64) && defined (_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
3339#define PROCFS_FILE_OFFSET_BITS_HACK 1
3340#undef _FILE_OFFSET_BITS
3341#else
3342#define PROCFS_FILE_OFFSET_BITS_HACK 0
3343#endif
3344
3345#include <procfs.h>
3346
3347#if PROCFS_FILE_OFFSET_BITS_HACK == 1
3348#define _FILE_OFFSET_BITS 64
3349#endif /* PROCFS_FILE_OFFSET_BITS_HACK == 1 */
3350
3351Lisp_Object
3352system_process_attributes (Lisp_Object pid)
3353{
3354 char procfn[PATH_MAX], fn[PATH_MAX];
3355 struct stat st;
3356 struct passwd *pw;
3357 struct group *gr;
3358 char *procfn_end;
3359 struct psinfo pinfo;
3360 int fd;
3361 ssize_t nread;
3362 int proc_id, uid, gid;
3363 Lisp_Object attrs = Qnil;
3364 Lisp_Object decoded_cmd, tem;
3365 struct gcpro gcpro1, gcpro2;
3366 EMACS_INT uid_eint, gid_eint;
3367
3368 CHECK_NUMBER_OR_FLOAT (pid);
3369 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
3370 sprintf (procfn, "/proc/%u", proc_id);
3371 if (stat (procfn, &st) < 0)
3372 return attrs;
3373
3374 GCPRO2 (attrs, decoded_cmd);
3375
3376 /* euid egid */
3377 uid = st.st_uid;
3378 /* Use of EMACS_INT stops GCC whining about limited range of data type. */
3379 uid_eint = uid;
3380 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs);
3381 BLOCK_INPUT;
3382 pw = getpwuid (uid);
3383 UNBLOCK_INPUT;
3384 if (pw)
3385 attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
3386
3387 gid = st.st_gid;
3388 gid_eint = gid;
3389 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs);
3390 BLOCK_INPUT;
3391 gr = getgrgid (gid);
3392 UNBLOCK_INPUT;
3393 if (gr)
3394 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3395
3396 strcpy (fn, procfn);
3397 procfn_end = fn + strlen (fn);
3398 strcpy (procfn_end, "/psinfo");
3399 fd = emacs_open (fn, O_RDONLY, 0);
3400 if (fd >= 0
3401 && (nread = read (fd, (char*)&pinfo, sizeof (struct psinfo)) > 0))
3402 {
3403 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs);
3404 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs);
3405 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs);
3406
3407 {
3408 char state_str[2];
3409 state_str[0] = pinfo.pr_lwp.pr_sname;
3410 state_str[1] = '\0';
3411 tem = build_string (state_str);
3412 attrs = Fcons (Fcons (Qstate, tem), attrs);
3413 }
3414
3415 /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
3416 need to get a string from it. */
3417
3418 /* FIXME: missing: Qtpgid */
3419
3420 /* FIXME: missing:
3421 Qminflt
3422 Qmajflt
3423 Qcminflt
3424 Qcmajflt
3425
3426 Qutime
3427 Qcutime
3428 Qstime
3429 Qcstime
3430 Are they available? */
3431
3432 attrs = Fcons (Fcons (Qtime,
3433 list3 (make_number (pinfo.pr_time.tv_sec >> 16),
3434 make_number (pinfo.pr_time.tv_sec & 0xffff),
3435 make_number (pinfo.pr_time.tv_nsec))),
3436 attrs);
3437
3438 attrs = Fcons (Fcons (Qctime,
3439 list3 (make_number (pinfo.pr_ctime.tv_sec >> 16),
3440 make_number (pinfo.pr_ctime.tv_sec & 0xffff),
3441 make_number (pinfo.pr_ctime.tv_nsec))),
3442 attrs);
3443
3444 attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
3445 attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
3446 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs);
3447
3448 attrs = Fcons (Fcons (Qstart,
3449 list3 (make_number (pinfo.pr_start.tv_sec >> 16),
3450 make_number (pinfo.pr_start.tv_sec & 0xffff),
3451 make_number (pinfo.pr_start.tv_nsec))),
3452 attrs);
3453 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs);
3454 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs);
3455
3456 /* pr_pctcpu and pr_pctmem are encoded as a fixed point 16 bit number in [0 ... 1]. */
3457 attrs = Fcons (Fcons (Qpcpu, (pinfo.pr_pctcpu * 100.0) / (double)0x8000), attrs);
3458 attrs = Fcons (Fcons (Qpmem, (pinfo.pr_pctmem * 100.0) / (double)0x8000), attrs);
3459
3460 decoded_cmd
3461 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_fname,
3462 strlen (pinfo.pr_fname)),
3463 Vlocale_coding_system, 0);
3464 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3465 decoded_cmd
3466 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_psargs,
3467 strlen (pinfo.pr_psargs)),
3468 Vlocale_coding_system, 0);
3469 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3470 }
3471
3472 if (fd >= 0)
3473 emacs_close (fd);
3474
3475 UNGCPRO;
3476 return attrs;
3477}
3478
3479/* The WINDOWSNT implementation is in w32.c.
3480 The MSDOS implementation is in dosfns.c. */
3481#elif !defined (WINDOWSNT) && !defined (MSDOS)
3482
3483Lisp_Object
3484system_process_attributes (Lisp_Object pid)
3485{
3486 return Qnil;
3487}
3488
3489#endif /* !defined (WINDOWSNT) */
3490
3491
3492/* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
3493 (do not change this comment) */