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