make the minibuffer mutex recursive.
[emacs.git] / src / sysdep.c
blob48343701823efa0950b04f409ea887ad2965cdb5
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 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include <ctype.h>
26 #include <signal.h>
27 #include <stdio.h>
28 #include <setjmp.h>
29 #ifdef HAVE_PWD_H
30 #include <pwd.h>
31 #include <grp.h>
32 #endif /* HAVE_PWD_H */
33 #ifdef HAVE_LIMITS_H
34 #include <limits.h>
35 #endif /* HAVE_LIMITS_H */
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39 #ifdef HAVE_ALLOCA_H
40 #include <alloca.h>
41 #endif /* HAVE_ALLOCA_H */
43 #include "lisp.h"
44 /* Including stdlib.h isn't necessarily enough to get srandom
45 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
47 /* The w32 build defines select stuff in w32.h, which is included by
48 sys/select.h (included below). */
49 #ifndef WINDOWSNT
50 #include "sysselect.h"
51 #endif
53 #include "blockinput.h"
55 #ifdef WINDOWSNT
56 #define read sys_read
57 #define write sys_write
58 #include <windows.h>
59 #ifndef NULL
60 #define NULL 0
61 #endif
62 #endif /* not WINDOWSNT */
64 /* Does anyone other than VMS need this? */
65 #ifndef fwrite
66 #define sys_fwrite fwrite
67 #else
68 #undef fwrite
69 #endif
71 #include <sys/types.h>
72 #include <sys/stat.h>
73 #include <errno.h>
75 #ifdef HAVE_SETPGID
76 #if !defined (USG) || defined (BSD_PGRPS)
77 #undef setpgrp
78 #define setpgrp setpgid
79 #endif
80 #endif
82 /* Get SI_SRPC_DOMAIN, if it is available. */
83 #ifdef HAVE_SYS_SYSTEMINFO_H
84 #include <sys/systeminfo.h>
85 #endif
87 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
88 #include <dos.h>
89 #include "dosfns.h"
90 #include "msdos.h"
91 #include <sys/param.h>
93 #if __DJGPP__ > 1
94 extern int etext;
95 extern unsigned start __asm__ ("start");
96 #endif
97 #endif
99 #ifndef USE_CRT_DLL
100 #ifndef errno
101 extern int errno;
102 #endif
103 #endif
105 #include <sys/file.h>
107 #ifdef HAVE_FCNTL_H
108 #include <fcntl.h>
109 #endif
111 #ifndef MSDOS
112 #include <sys/ioctl.h>
113 #endif
115 #include "systty.h"
116 #include "syswait.h"
118 #if defined (USG)
119 #include <sys/utsname.h>
120 #include <memory.h>
121 #endif /* USG */
123 extern int quit_char;
125 #include "keyboard.h"
126 #include "frame.h"
127 #include "window.h"
128 #include "termhooks.h"
129 #include "termchar.h"
130 #include "termopts.h"
131 #include "dispextern.h"
132 #include "process.h"
133 #include "cm.h" /* for reset_sys_modes */
135 /* For serial_configure and serial_open. */
136 extern Lisp_Object QCport, QCspeed, QCprocess;
137 extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
138 extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
140 #ifdef WINDOWSNT
141 #include <direct.h>
142 /* In process.h which conflicts with the local copy. */
143 #define _P_WAIT 0
144 int _cdecl _spawnlp (int, const char *, const char *, ...);
145 int _cdecl _getpid (void);
146 extern char *getwd (char *);
147 #endif
149 #include "syssignal.h"
150 #include "systime.h"
151 #ifdef HAVE_UTIME_H
152 #include <utime.h>
153 #endif
155 #ifndef HAVE_UTIMES
156 #ifndef HAVE_STRUCT_UTIMBUF
157 /* We want to use utime rather than utimes, but we couldn't find the
158 structure declaration. We'll use the traditional one. */
159 struct utimbuf {
160 long actime;
161 long modtime;
163 #endif
164 #endif
166 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
167 #ifndef LPASS8
168 #define LPASS8 0
169 #endif
171 static const int baud_convert[] =
173 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
174 1800, 2400, 4800, 9600, 19200, 38400
177 #ifdef HAVE_SPEED_T
178 #include <termios.h>
179 #else
180 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
181 #else
182 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
183 #include <termios.h>
184 #endif
185 #endif
186 #endif
188 int emacs_ospeed;
190 void croak P_ ((char *)) NO_RETURN;
192 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
194 SIGMASKTYPE sigprocmask_set;
197 #if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
199 /* Return the current working directory. Returns NULL on errors.
200 Any other returned value must be freed with free. This is used
201 only when get_current_dir_name is not defined on the system. */
202 char*
203 get_current_dir_name ()
205 char *buf;
206 char *pwd;
207 struct stat dotstat, pwdstat;
208 /* If PWD is accurate, use it instead of calling getwd. PWD is
209 sometimes a nicer name, and using it may avoid a fatal error if a
210 parent directory is searchable but not readable. */
211 if ((pwd = getenv ("PWD")) != 0
212 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
213 && stat (pwd, &pwdstat) == 0
214 && stat (".", &dotstat) == 0
215 && dotstat.st_ino == pwdstat.st_ino
216 && dotstat.st_dev == pwdstat.st_dev
217 #ifdef MAXPATHLEN
218 && strlen (pwd) < MAXPATHLEN
219 #endif
222 buf = (char *) malloc (strlen (pwd) + 1);
223 if (!buf)
224 return NULL;
225 strcpy (buf, pwd);
227 #ifdef HAVE_GETCWD
228 else
230 size_t buf_size = 1024;
231 buf = (char *) malloc (buf_size);
232 if (!buf)
233 return NULL;
234 for (;;)
236 if (getcwd (buf, buf_size) == buf)
237 break;
238 if (errno != ERANGE)
240 int tmp_errno = errno;
241 free (buf);
242 errno = tmp_errno;
243 return NULL;
245 buf_size *= 2;
246 buf = (char *) realloc (buf, buf_size);
247 if (!buf)
248 return NULL;
251 #else
252 else
254 /* We need MAXPATHLEN here. */
255 buf = (char *) malloc (MAXPATHLEN + 1);
256 if (!buf)
257 return NULL;
258 if (getwd (buf) == NULL)
260 int tmp_errno = errno;
261 free (buf);
262 errno = tmp_errno;
263 return NULL;
266 #endif
267 return buf;
269 #endif
272 /* Discard pending input on all input descriptors. */
274 void
275 discard_tty_input ()
277 #ifndef WINDOWSNT
278 struct emacs_tty buf;
280 if (noninteractive)
281 return;
283 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
284 while (dos_keyread () != -1)
286 #else /* not MSDOS */
288 struct tty_display_info *tty;
289 for (tty = tty_list; tty; tty = tty->next)
291 if (tty->input) /* Is the device suspended? */
293 EMACS_GET_TTY (fileno (tty->input), &buf);
294 EMACS_SET_TTY (fileno (tty->input), &buf, 0);
298 #endif /* not MSDOS */
299 #endif /* not WINDOWSNT */
303 #ifdef SIGTSTP
305 /* Arrange for character C to be read as the next input from
306 the terminal.
307 XXX What if we have multiple ttys?
310 void
311 stuff_char (char c)
313 if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
314 return;
316 /* Should perhaps error if in batch mode */
317 #ifdef TIOCSTI
318 ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
319 #else /* no TIOCSTI */
320 error ("Cannot stuff terminal input characters in this version of Unix");
321 #endif /* no TIOCSTI */
324 #endif /* SIGTSTP */
326 void
327 init_baud_rate (int fd)
329 if (noninteractive)
330 emacs_ospeed = 0;
331 else
333 #ifdef DOS_NT
334 emacs_ospeed = 15;
335 #else /* not DOS_NT */
336 #ifdef HAVE_TERMIOS
337 struct termios sg;
339 sg.c_cflag = B9600;
340 tcgetattr (fd, &sg);
341 emacs_ospeed = cfgetospeed (&sg);
342 #else /* not TERMIOS */
343 #ifdef HAVE_TERMIO
344 struct termio sg;
346 sg.c_cflag = B9600;
347 #ifdef HAVE_TCATTR
348 tcgetattr (fd, &sg);
349 #else
350 ioctl (fd, TCGETA, &sg);
351 #endif
352 emacs_ospeed = sg.c_cflag & CBAUD;
353 #else /* neither TERMIOS nor TERMIO */
354 struct sgttyb sg;
356 sg.sg_ospeed = B9600;
357 if (ioctl (fd, TIOCGETP, &sg) < 0)
358 abort ();
359 emacs_ospeed = sg.sg_ospeed;
360 #endif /* not HAVE_TERMIO */
361 #endif /* not HAVE_TERMIOS */
362 #endif /* not DOS_NT */
365 baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
366 ? baud_convert[emacs_ospeed] : 9600);
367 if (baud_rate == 0)
368 baud_rate = 1200;
372 /*ARGSUSED*/
373 void
374 set_exclusive_use (fd)
375 int fd;
377 #ifdef FIOCLEX
378 ioctl (fd, FIOCLEX, 0);
379 #endif
380 /* Ok to do nothing if this feature does not exist */
383 #ifndef subprocesses
385 wait_without_blocking ()
387 #ifdef BSD_SYSTEM
388 wait3 (0, WNOHANG | WUNTRACED, 0);
389 #else
390 croak ("wait_without_blocking");
391 #endif
392 synch_process_alive = 0;
395 #endif /* not subprocesses */
397 int wait_debugging; /* Set nonzero to make following function work under dbx
398 (at least for bsd). */
400 SIGTYPE
401 wait_for_termination_signal ()
404 /* Wait for subprocess with process id `pid' to terminate and
405 make sure it will get eliminated (not remain forever as a zombie) */
407 void
408 wait_for_termination (pid)
409 int pid;
411 while (1)
413 #ifdef subprocesses
414 #if defined (BSD_SYSTEM) || defined (HPUX)
415 /* Note that kill returns -1 even if the process is just a zombie now.
416 But inevitably a SIGCHLD interrupt should be generated
417 and child_sig will do wait3 and make the process go away. */
418 /* There is some indication that there is a bug involved with
419 termination of subprocesses, perhaps involving a kernel bug too,
420 but no idea what it is. Just as a hunch we signal SIGCHLD to see
421 if that causes the problem to go away or get worse. */
422 sigsetmask (sigmask (SIGCHLD));
423 if (0 > kill (pid, 0))
425 sigsetmask (SIGEMPTYMASK);
426 kill (getpid (), SIGCHLD);
427 break;
429 if (wait_debugging)
430 sleep (1);
431 else
432 sigpause (SIGEMPTYMASK);
433 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
434 #ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */
435 int status;
436 int w;
437 /* XXX: can I replace this code without problems? --giuseppe
439 sigblock (sigmask (SIGCHLD));
440 errno = 0;
441 if (kill (pid, 0) == -1 && errno == ESRCH)
443 sigunblock (sigmask (SIGCHLD));
444 break;
447 sigsuspend (&empty_mask);
449 w = waitpid (pid, &status, WUNTRACED | WCONTINUED);
450 if (w == -1 || WIFEXITED (w))
451 break;
452 #else /* not POSIX_SIGNALS */
453 #ifdef HAVE_SYSV_SIGPAUSE
454 sighold (SIGCHLD);
455 if (0 > kill (pid, 0))
457 sigrelse (SIGCHLD);
458 break;
460 sigpause (SIGCHLD);
461 #else /* not HAVE_SYSV_SIGPAUSE */
462 #ifdef WINDOWSNT
463 wait (0);
464 break;
465 #else /* not WINDOWSNT */
466 if (0 > kill (pid, 0))
467 break;
468 /* Using sleep instead of pause avoids timing error.
469 If the inferior dies just before the sleep,
470 we lose just one second. */
471 sleep (1);
472 #endif /* not WINDOWSNT */
473 #endif /* not HAVE_SYSV_SIGPAUSE */
474 #endif /* not POSIX_SIGNALS */
475 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
476 #else /* not subprocesses */
477 #if __DJGPP__ > 1
478 break;
479 #else /* not __DJGPP__ > 1 */
480 if (kill (pid, 0) < 0)
481 break;
482 wait (0);
483 #endif /* not __DJGPP__ > 1*/
484 #endif /* not subprocesses */
488 #ifdef subprocesses
491 * flush any pending output
492 * (may flush input as well; it does not matter the way we use it)
495 void
496 flush_pending_output (channel)
497 int channel;
499 #ifdef HAVE_TERMIOS
500 /* If we try this, we get hit with SIGTTIN, because
501 the child's tty belongs to the child's pgrp. */
502 #else
503 #ifdef TCFLSH
504 ioctl (channel, TCFLSH, 1);
505 #else
506 #ifdef TIOCFLUSH
507 int zero = 0;
508 /* 3rd arg should be ignored
509 but some 4.2 kernels actually want the address of an int
510 and nonzero means something different. */
511 ioctl (channel, TIOCFLUSH, &zero);
512 #endif
513 #endif
514 #endif
517 /* Set up the terminal at the other end of a pseudo-terminal that
518 we will be controlling an inferior through.
519 It should not echo or do line-editing, since that is done
520 in Emacs. No padding needed for insertion into an Emacs buffer. */
522 void
523 child_setup_tty (out)
524 int out;
526 #ifndef DOS_NT
527 struct emacs_tty s;
529 EMACS_GET_TTY (out, &s);
531 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
532 s.main.c_oflag |= OPOST; /* Enable output postprocessing */
533 s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */
534 #ifdef NLDLY
535 /* http://lists.gnu.org/archive/html/emacs-devel/2008-05/msg00406.html
536 Some versions of GNU Hurd do not have FFDLY? */
537 #ifdef FFDLY
538 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
539 /* No output delays */
540 #else
541 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY);
542 /* No output delays */
543 #endif
544 #endif
545 s.main.c_lflag &= ~ECHO; /* Disable echo */
546 s.main.c_lflag |= ISIG; /* Enable signals */
547 #ifdef IUCLC
548 s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */
549 #endif
550 #ifdef ISTRIP
551 s.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
552 #endif
553 #ifdef OLCUC
554 s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */
555 #endif
556 s.main.c_oflag &= ~TAB3; /* Disable tab expansion */
557 s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
558 s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */
559 s.main.c_cc[VEOF] = 04; /* insure that EOF is Control-D */
560 s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
561 s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
563 #ifdef HPUX
564 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
565 #endif /* HPUX */
567 #ifdef SIGNALS_VIA_CHARACTERS
568 /* the QUIT and INTR character are used in process_send_signal
569 so set them here to something useful. */
570 if (s.main.c_cc[VQUIT] == CDISABLE)
571 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
572 if (s.main.c_cc[VINTR] == CDISABLE)
573 s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
574 #endif /* not SIGNALS_VIA_CHARACTERS */
576 #ifdef AIX
577 /* AIX enhanced edit loses NULs, so disable it */
578 #ifndef IBMR2AIX
579 s.main.c_line = 0;
580 s.main.c_iflag &= ~ASCEDIT;
581 #endif
582 /* Also, PTY overloads NUL and BREAK.
583 don't ignore break, but don't signal either, so it looks like NUL. */
584 s.main.c_iflag &= ~IGNBRK;
585 s.main.c_iflag &= ~BRKINT;
586 /* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
587 unconditionally. Then a SIGNALS_VIA_CHARACTERS conditional
588 would force it to 0377. That looks like duplicated code. */
589 s.main.c_cc[VEOL] = CDISABLE;
590 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
591 #endif /* AIX */
593 #else /* not HAVE_TERMIO */
595 s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE
596 | CBREAK | TANDEM);
597 s.main.sg_flags |= LPASS8;
598 s.main.sg_erase = 0377;
599 s.main.sg_kill = 0377;
600 s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */
602 #endif /* not HAVE_TERMIO */
604 EMACS_SET_TTY (out, &s, 0);
606 #endif /* not DOS_NT */
609 #endif /* subprocesses */
611 /* Record a signal code and the handler for it. */
612 struct save_signal
614 int code;
615 SIGTYPE (*handler) P_ ((int));
618 static void save_signal_handlers P_ ((struct save_signal *));
619 static void restore_signal_handlers P_ ((struct save_signal *));
621 /* Suspend the Emacs process; give terminal to its superior. */
623 void
624 sys_suspend ()
626 #if defined (SIGTSTP) && !defined (MSDOS)
629 int pgrp = EMACS_GETPGRP (0);
630 EMACS_KILLPG (pgrp, SIGTSTP);
633 #else /* No SIGTSTP */
634 /* On a system where suspending is not implemented,
635 instead fork a subshell and let it talk directly to the terminal
636 while we wait. */
637 sys_subshell ();
639 #endif /* no SIGTSTP */
642 /* Fork a subshell. */
644 void
645 sys_subshell ()
647 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
648 int st;
649 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
650 #endif
651 int pid;
652 struct save_signal saved_handlers[5];
653 Lisp_Object dir;
654 unsigned char *str = 0;
655 int len;
657 saved_handlers[0].code = SIGINT;
658 saved_handlers[1].code = SIGQUIT;
659 saved_handlers[2].code = SIGTERM;
660 #ifdef SIGIO
661 saved_handlers[3].code = SIGIO;
662 saved_handlers[4].code = 0;
663 #else
664 saved_handlers[3].code = 0;
665 #endif
667 /* Mentioning current_buffer->buffer would mean including buffer.h,
668 which somehow wedges the hp compiler. So instead... */
670 dir = intern ("default-directory");
671 if (NILP (Fboundp (dir)))
672 goto xyzzy;
673 dir = Fsymbol_value (dir);
674 if (!STRINGP (dir))
675 goto xyzzy;
677 dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
678 str = (unsigned char *) alloca (SCHARS (dir) + 2);
679 len = SCHARS (dir);
680 bcopy (SDATA (dir), str, len);
681 if (str[len - 1] != '/') str[len++] = '/';
682 str[len] = 0;
683 xyzzy:
685 #ifdef DOS_NT
686 pid = 0;
687 #if __DJGPP__ > 1
688 save_signal_handlers (saved_handlers);
689 synch_process_alive = 1;
690 #endif /* __DJGPP__ > 1 */
691 #else
692 pid = vfork ();
693 if (pid == -1)
694 error ("Can't spawn subshell");
695 #endif
697 if (pid == 0)
699 char *sh = 0;
701 #ifdef DOS_NT /* MW, Aug 1993 */
702 getwd (oldwd);
703 if (sh == 0)
704 sh = (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
705 #endif
706 if (sh == 0)
707 sh = (char *) egetenv ("SHELL");
708 if (sh == 0)
709 sh = "sh";
711 /* Use our buffer's default directory for the subshell. */
712 if (str)
713 chdir ((char *) str);
715 #ifdef subprocesses
716 close_process_descs (); /* Close Emacs's pipes/ptys */
717 #endif
719 #ifdef SET_EMACS_PRIORITY
721 extern EMACS_INT emacs_priority;
723 if (emacs_priority < 0)
724 nice (-emacs_priority);
726 #endif
728 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
730 char *epwd = getenv ("PWD");
731 char old_pwd[MAXPATHLEN+1+4];
733 /* If PWD is set, pass it with corrected value. */
734 if (epwd)
736 strcpy (old_pwd, epwd);
737 if (str[len - 1] == '/')
738 str[len - 1] = '\0';
739 setenv ("PWD", str, 1);
741 st = system (sh);
742 chdir (oldwd);
743 if (epwd)
744 putenv (old_pwd); /* restore previous value */
746 #else /* not MSDOS */
747 #ifdef WINDOWSNT
748 /* Waits for process completion */
749 pid = _spawnlp (_P_WAIT, sh, sh, NULL);
750 chdir (oldwd);
751 if (pid == -1)
752 write (1, "Can't execute subshell", 22);
753 #else /* not WINDOWSNT */
754 execlp (sh, sh, (char *) 0);
755 write (1, "Can't execute subshell", 22);
756 _exit (1);
757 #endif /* not WINDOWSNT */
758 #endif /* not MSDOS */
761 /* Do this now if we did not do it before. */
762 #if !defined (MSDOS) || __DJGPP__ == 1
763 save_signal_handlers (saved_handlers);
764 synch_process_alive = 1;
765 #endif
767 #ifndef DOS_NT
768 wait_for_termination (pid);
769 #endif
770 restore_signal_handlers (saved_handlers);
771 synch_process_alive = 0;
774 static void
775 save_signal_handlers (saved_handlers)
776 struct save_signal *saved_handlers;
778 while (saved_handlers->code)
780 saved_handlers->handler
781 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers->code, SIG_IGN);
782 saved_handlers++;
786 static void
787 restore_signal_handlers (saved_handlers)
788 struct save_signal *saved_handlers;
790 while (saved_handlers->code)
792 signal (saved_handlers->code, saved_handlers->handler);
793 saved_handlers++;
797 #ifndef SIGIO
798 /* If SIGIO is broken, don't do anything. */
799 void
800 init_sigio (int fd)
804 void
805 reset_sigio (int fd)
809 void
810 request_sigio (void)
814 void
815 unrequest_sigio (void)
819 #else
820 #ifdef F_SETFL
822 int old_fcntl_flags[MAXDESC];
824 void
825 init_sigio (fd)
826 int fd;
828 #ifdef FASYNC
829 old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
830 fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC);
831 #endif
832 interrupts_deferred = 0;
835 void
836 reset_sigio (fd)
837 int fd;
839 #ifdef FASYNC
840 fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
841 #endif
844 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
845 /* XXX Uhm, FASYNC is not used anymore here. */
846 /* XXX Yeah, but you need it for SIGIO, don't you? */
848 void
849 request_sigio ()
851 if (noninteractive)
852 return;
854 #ifdef SIGWINCH
855 sigunblock (sigmask (SIGWINCH));
856 #endif
857 sigunblock (sigmask (SIGIO));
859 interrupts_deferred = 0;
862 void
863 unrequest_sigio (void)
865 if (noninteractive)
866 return;
868 #if 0 /* XXX What's wrong with blocking SIGIO under X? */
869 if (x_display_list)
870 return;
871 #endif
873 #ifdef SIGWINCH
874 sigblock (sigmask (SIGWINCH));
875 #endif
876 sigblock (sigmask (SIGIO));
877 interrupts_deferred = 1;
880 #else /* no FASYNC */
881 #ifndef MSDOS
883 void
884 request_sigio ()
886 if (noninteractive || read_socket_hook)
887 return;
889 croak ("request_sigio");
892 void
893 unrequest_sigio ()
895 if (noninteractive || read_socket_hook)
896 return;
898 croak ("unrequest_sigio");
901 #endif /* MSDOS */
902 #endif /* FASYNC */
903 #endif /* F_SETFL */
904 #endif /* SIGIO */
906 /* Saving and restoring the process group of Emacs's terminal. */
908 #ifdef BSD_PGRPS
910 /* The process group of which Emacs was a member when it initially
911 started.
913 If Emacs was in its own process group (i.e. inherited_pgroup ==
914 getpid ()), then we know we're running under a shell with job
915 control (Emacs would never be run as part of a pipeline).
916 Everything is fine.
918 If Emacs was not in its own process group, then we know we're
919 running under a shell (or a caller) that doesn't know how to
920 separate itself from Emacs (like sh). Emacs must be in its own
921 process group in order to receive SIGIO correctly. In this
922 situation, we put ourselves in our own pgroup, forcibly set the
923 tty's pgroup to our pgroup, and make sure to restore and reinstate
924 the tty's pgroup just like any other terminal setting. If
925 inherited_group was not the tty's pgroup, then we'll get a
926 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
927 it goes foreground in the future, which is what should happen.
929 This variable is initialized in emacs.c. */
930 int inherited_pgroup;
932 /* Split off the foreground process group to Emacs alone. When we are
933 in the foreground, but not started in our own process group,
934 redirect the tty device handle FD to point to our own process
935 group. We need to be in our own process group to receive SIGIO
936 properly. */
937 static void
938 narrow_foreground_group (int fd)
940 int me = getpid ();
942 setpgrp (0, inherited_pgroup);
943 #if 0
944 /* XXX inherited_pgroup should not be zero here, but GTK seems to
945 mess this up. */
946 if (! inherited_pgroup)
947 abort (); /* Should not happen. */
948 #endif
949 if (inherited_pgroup != me)
950 EMACS_SET_TTY_PGRP (fd, &me); /* XXX This only works on the controlling tty. */
951 setpgrp (0, me);
954 /* Set the tty to our original foreground group. */
955 static void
956 widen_foreground_group (int fd)
958 if (inherited_pgroup != getpid ())
959 EMACS_SET_TTY_PGRP (fd, &inherited_pgroup);
960 setpgrp (0, inherited_pgroup);
963 #endif /* BSD_PGRPS */
965 /* Getting and setting emacs_tty structures. */
967 /* Set *TC to the parameters associated with the terminal FD.
968 Return zero if all's well, or -1 if we ran into an error we
969 couldn't deal with. */
971 emacs_get_tty (fd, settings)
972 int fd;
973 struct emacs_tty *settings;
975 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
976 #ifdef HAVE_TCATTR
977 /* We have those nifty POSIX tcmumbleattr functions. */
978 bzero (&settings->main, sizeof (settings->main));
979 if (tcgetattr (fd, &settings->main) < 0)
980 return -1;
982 #else
983 #ifdef HAVE_TERMIO
984 /* The SYSV-style interface? */
985 if (ioctl (fd, TCGETA, &settings->main) < 0)
986 return -1;
988 #else
989 #ifndef DOS_NT
990 /* I give up - I hope you have the BSD ioctls. */
991 if (ioctl (fd, TIOCGETP, &settings->main) < 0)
992 return -1;
993 #endif /* not DOS_NT */
994 #endif
995 #endif
997 /* Suivant - Do we have to get struct ltchars data? */
998 #ifdef HAVE_LTCHARS
999 if (ioctl (fd, TIOCGLTC, &settings->ltchars) < 0)
1000 return -1;
1001 #endif
1003 /* How about a struct tchars and a wordful of lmode bits? */
1004 #ifdef HAVE_TCHARS
1005 if (ioctl (fd, TIOCGETC, &settings->tchars) < 0
1006 || ioctl (fd, TIOCLGET, &settings->lmode) < 0)
1007 return -1;
1008 #endif
1010 /* We have survived the tempest. */
1011 return 0;
1015 /* Set the parameters of the tty on FD according to the contents of
1016 *SETTINGS. If FLUSHP is non-zero, we discard input.
1017 Return 0 if all went well, and -1 if anything failed. */
1020 emacs_set_tty (fd, settings, flushp)
1021 int fd;
1022 struct emacs_tty *settings;
1023 int flushp;
1025 /* Set the primary parameters - baud rate, character size, etcetera. */
1026 #ifdef HAVE_TCATTR
1027 int i;
1028 /* We have those nifty POSIX tcmumbleattr functions.
1029 William J. Smith <wjs@wiis.wang.com> writes:
1030 "POSIX 1003.1 defines tcsetattr to return success if it was
1031 able to perform any of the requested actions, even if some
1032 of the requested actions could not be performed.
1033 We must read settings back to ensure tty setup properly.
1034 AIX requires this to keep tty from hanging occasionally." */
1035 /* This make sure that we don't loop indefinitely in here. */
1036 for (i = 0 ; i < 10 ; i++)
1037 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
1039 if (errno == EINTR)
1040 continue;
1041 else
1042 return -1;
1044 else
1046 struct termios new;
1048 bzero (&new, sizeof (new));
1049 /* Get the current settings, and see if they're what we asked for. */
1050 tcgetattr (fd, &new);
1051 /* We cannot use memcmp on the whole structure here because under
1052 * aix386 the termios structure has some reserved field that may
1053 * not be filled in.
1055 if ( new.c_iflag == settings->main.c_iflag
1056 && new.c_oflag == settings->main.c_oflag
1057 && new.c_cflag == settings->main.c_cflag
1058 && new.c_lflag == settings->main.c_lflag
1059 && memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
1060 break;
1061 else
1062 continue;
1065 #else
1066 #ifdef HAVE_TERMIO
1067 /* The SYSV-style interface? */
1068 if (ioctl (fd, flushp ? TCSETAF : TCSETAW, &settings->main) < 0)
1069 return -1;
1071 #else
1072 #ifndef DOS_NT
1073 /* I give up - I hope you have the BSD ioctls. */
1074 if (ioctl (fd, (flushp) ? TIOCSETP : TIOCSETN, &settings->main) < 0)
1075 return -1;
1076 #endif /* not DOS_NT */
1078 #endif
1079 #endif
1081 /* Suivant - Do we have to get struct ltchars data? */
1082 #ifdef HAVE_LTCHARS
1083 if (ioctl (fd, TIOCSLTC, &settings->ltchars) < 0)
1084 return -1;
1085 #endif
1087 /* How about a struct tchars and a wordful of lmode bits? */
1088 #ifdef HAVE_TCHARS
1089 if (ioctl (fd, TIOCSETC, &settings->tchars) < 0
1090 || ioctl (fd, TIOCLSET, &settings->lmode) < 0)
1091 return -1;
1092 #endif
1094 /* We have survived the tempest. */
1095 return 0;
1100 #ifdef F_SETOWN
1101 int old_fcntl_owner[MAXDESC];
1102 #endif /* F_SETOWN */
1104 /* This may also be defined in stdio,
1105 but if so, this does no harm,
1106 and using the same name avoids wasting the other one's space. */
1108 #if defined (USG)
1109 unsigned char _sobuf[BUFSIZ+8];
1110 #else
1111 char _sobuf[BUFSIZ];
1112 #endif
1114 #ifdef HAVE_LTCHARS
1115 static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
1116 #endif
1117 #ifdef HAVE_TCHARS
1118 static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
1119 #endif
1121 /* Initialize the terminal mode on all tty devices that are currently
1122 open. */
1124 void
1125 init_all_sys_modes (void)
1127 struct tty_display_info *tty;
1128 for (tty = tty_list; tty; tty = tty->next)
1129 init_sys_modes (tty);
1132 /* Initialize the terminal mode on the given tty device. */
1134 void
1135 init_sys_modes (tty_out)
1136 struct tty_display_info *tty_out;
1138 struct emacs_tty tty;
1140 Vtty_erase_char = Qnil;
1142 if (noninteractive)
1143 return;
1145 if (!tty_out->output)
1146 return; /* The tty is suspended. */
1148 #ifdef BSD_PGRPS
1149 #if 0
1150 /* read_socket_hook is not global anymore. I think doing this
1151 unconditionally will not cause any problems. */
1152 if (! read_socket_hook && EQ (Vinitial_window_system, Qnil))
1153 #endif
1154 narrow_foreground_group (fileno (tty_out->input));
1155 #endif
1157 if (! tty_out->old_tty)
1158 tty_out->old_tty = (struct emacs_tty *) xmalloc (sizeof (struct emacs_tty));
1160 EMACS_GET_TTY (fileno (tty_out->input), tty_out->old_tty);
1162 tty = *tty_out->old_tty;
1164 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1165 XSETINT (Vtty_erase_char, tty.main.c_cc[VERASE]);
1167 tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
1168 tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
1169 #ifdef INLCR /* I'm just being cautious,
1170 since I can't check how widespread INLCR is--rms. */
1171 tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
1172 #endif
1173 #ifdef ISTRIP
1174 tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
1175 #endif
1176 tty.main.c_lflag &= ~ECHO; /* Disable echo */
1177 tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */
1178 #ifdef IEXTEN
1179 tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
1180 #endif
1181 tty.main.c_lflag |= ISIG; /* Enable signals */
1182 if (tty_out->flow_control)
1184 tty.main.c_iflag |= IXON; /* Enable start/stop output control */
1185 #ifdef IXANY
1186 tty.main.c_iflag &= ~IXANY;
1187 #endif /* IXANY */
1189 else
1190 tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
1191 tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
1192 on output */
1193 tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */
1194 #ifdef CS8
1195 if (tty_out->meta_key)
1197 tty.main.c_cflag |= CS8; /* allow 8th bit on input */
1198 tty.main.c_cflag &= ~PARENB;/* Don't check parity */
1200 #endif
1201 if (tty_out->input == stdin)
1203 tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
1204 /* Set up C-g for both SIGQUIT and SIGINT.
1205 We don't know which we will get, but we handle both alike
1206 so which one it really gives us does not matter. */
1207 tty.main.c_cc[VQUIT] = quit_char;
1209 else
1211 /* We normally don't get interrupt or quit signals from tty
1212 devices other than our controlling terminal; therefore,
1213 we must handle C-g as normal input. Unfortunately, this
1214 means that the interrupt and quit feature must be
1215 disabled on secondary ttys, or we would not even see the
1216 keypress.
1218 Note that even though emacsclient could have special code
1219 to pass SIGINT to Emacs, we should _not_ enable
1220 interrupt/quit keys for emacsclient frames. This means
1221 that we can't break out of loops in C code from a
1222 secondary tty frame, but we can always decide what
1223 display the C-g came from, which is more important from a
1224 usability point of view. (Consider the case when two
1225 people work together using the same Emacs instance.) */
1226 tty.main.c_cc[VINTR] = CDISABLE;
1227 tty.main.c_cc[VQUIT] = CDISABLE;
1229 tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
1230 tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
1231 #ifdef VSWTCH
1232 tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
1233 of C-z */
1234 #endif /* VSWTCH */
1236 #if defined (__mips__) || defined (HAVE_TCATTR)
1237 #ifdef VSUSP
1238 tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
1239 #endif /* VSUSP */
1240 #ifdef V_DSUSP
1241 tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
1242 #endif /* V_DSUSP */
1243 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1244 tty.main.c_cc[VDSUSP] = CDISABLE;
1245 #endif /* VDSUSP */
1246 #ifdef VLNEXT
1247 tty.main.c_cc[VLNEXT] = CDISABLE;
1248 #endif /* VLNEXT */
1249 #ifdef VREPRINT
1250 tty.main.c_cc[VREPRINT] = CDISABLE;
1251 #endif /* VREPRINT */
1252 #ifdef VWERASE
1253 tty.main.c_cc[VWERASE] = CDISABLE;
1254 #endif /* VWERASE */
1255 #ifdef VDISCARD
1256 tty.main.c_cc[VDISCARD] = CDISABLE;
1257 #endif /* VDISCARD */
1259 if (tty_out->flow_control)
1261 #ifdef VSTART
1262 tty.main.c_cc[VSTART] = '\021';
1263 #endif /* VSTART */
1264 #ifdef VSTOP
1265 tty.main.c_cc[VSTOP] = '\023';
1266 #endif /* VSTOP */
1268 else
1270 #ifdef VSTART
1271 tty.main.c_cc[VSTART] = CDISABLE;
1272 #endif /* VSTART */
1273 #ifdef VSTOP
1274 tty.main.c_cc[VSTOP] = CDISABLE;
1275 #endif /* VSTOP */
1277 #endif /* mips or HAVE_TCATTR */
1279 #ifdef AIX
1280 #ifndef IBMR2AIX
1281 /* AIX enhanced edit loses NULs, so disable it. */
1282 tty.main.c_line = 0;
1283 tty.main.c_iflag &= ~ASCEDIT;
1284 #else
1285 tty.main.c_cc[VSTRT] = CDISABLE;
1286 tty.main.c_cc[VSTOP] = CDISABLE;
1287 tty.main.c_cc[VSUSP] = CDISABLE;
1288 tty.main.c_cc[VDSUSP] = CDISABLE;
1289 #endif /* IBMR2AIX */
1290 if (tty_out->flow_control)
1292 #ifdef VSTART
1293 tty.main.c_cc[VSTART] = '\021';
1294 #endif /* VSTART */
1295 #ifdef VSTOP
1296 tty.main.c_cc[VSTOP] = '\023';
1297 #endif /* VSTOP */
1299 /* Also, PTY overloads NUL and BREAK.
1300 don't ignore break, but don't signal either, so it looks like NUL.
1301 This really serves a purpose only if running in an XTERM window
1302 or via TELNET or the like, but does no harm elsewhere. */
1303 tty.main.c_iflag &= ~IGNBRK;
1304 tty.main.c_iflag &= ~BRKINT;
1305 #endif
1306 #else /* if not HAVE_TERMIO */
1307 #ifndef DOS_NT
1308 XSETINT (Vtty_erase_char, tty.main.sg_erase);
1309 tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS);
1310 if (meta_key)
1311 tty.main.sg_flags |= ANYP;
1312 tty.main.sg_flags |= interrupt_input ? RAW : CBREAK;
1313 #endif /* not DOS_NT */
1314 #endif /* not HAVE_TERMIO */
1316 /* If going to use CBREAK mode, we must request C-g to interrupt
1317 and turn off start and stop chars, etc. If not going to use
1318 CBREAK mode, do this anyway so as to turn off local flow
1319 control for user coming over network on 4.2; in this case,
1320 only t_stopc and t_startc really matter. */
1321 #ifndef HAVE_TERMIO
1322 #ifdef HAVE_TCHARS
1323 /* Note: if not using CBREAK mode, it makes no difference how we
1324 set this */
1325 tty.tchars = new_tchars;
1326 tty.tchars.t_intrc = quit_char;
1327 if (tty_out->flow_control)
1329 tty.tchars.t_startc = '\021';
1330 tty.tchars.t_stopc = '\023';
1333 tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | tty_out->old_tty.lmode;
1335 #endif /* HAVE_TCHARS */
1336 #endif /* not HAVE_TERMIO */
1338 #ifdef HAVE_LTCHARS
1339 tty.ltchars = new_ltchars;
1340 #endif /* HAVE_LTCHARS */
1341 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1342 if (!tty_out->term_initted)
1343 internal_terminal_init ();
1344 dos_ttraw (tty_out);
1345 #endif
1347 EMACS_SET_TTY (fileno (tty_out->input), &tty, 0);
1349 /* This code added to insure that, if flow-control is not to be used,
1350 we have an unlocked terminal at the start. */
1352 #ifdef TCXONC
1353 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
1354 #endif
1355 #ifdef TIOCSTART
1356 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
1357 #endif
1359 #if defined (HAVE_TERMIOS) || defined (HPUX)
1360 #ifdef TCOON
1361 if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
1362 #endif
1363 #endif
1365 #ifdef F_SETFL
1366 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1367 if (interrupt_input)
1369 old_fcntl_owner[fileno (tty_out->input)] =
1370 fcntl (fileno (tty_out->input), F_GETOWN, 0);
1371 fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
1372 init_sigio (fileno (tty_out->input));
1373 #ifdef HAVE_GPM
1374 if (gpm_tty == tty_out)
1376 /* Arrange for mouse events to give us SIGIO signals. */
1377 fcntl (gpm_fd, F_SETOWN, getpid ());
1378 fcntl (gpm_fd, F_SETFL, fcntl (gpm_fd, F_GETFL, 0) | O_NONBLOCK);
1379 init_sigio (gpm_fd);
1381 #endif /* HAVE_GPM */
1383 #endif /* F_GETOWN */
1384 #endif /* F_SETFL */
1386 #ifdef _IOFBF
1387 /* This symbol is defined on recent USG systems.
1388 Someone says without this call USG won't really buffer the file
1389 even with a call to setbuf. */
1390 setvbuf (tty_out->output, (char *) _sobuf, _IOFBF, sizeof _sobuf);
1391 #else
1392 setbuf (tty_out->output, (char *) _sobuf);
1393 #endif
1395 if (tty_out->terminal->set_terminal_modes_hook)
1396 tty_out->terminal->set_terminal_modes_hook (tty_out->terminal);
1398 if (!tty_out->term_initted)
1400 Lisp_Object tail, frame;
1401 FOR_EACH_FRAME (tail, frame)
1403 /* XXX This needs to be revised. */
1404 if (FRAME_TERMCAP_P (XFRAME (frame))
1405 && FRAME_TTY (XFRAME (frame)) == tty_out)
1406 init_frame_faces (XFRAME (frame));
1410 if (tty_out->term_initted && no_redraw_on_reenter)
1412 /* XXX This seems wrong on multi-tty. */
1413 if (display_completed)
1414 direct_output_forward_char (0);
1416 else
1418 Lisp_Object tail, frame;
1419 frame_garbaged = 1;
1420 FOR_EACH_FRAME (tail, frame)
1422 if ((FRAME_TERMCAP_P (XFRAME (frame))
1423 || FRAME_MSDOS_P (XFRAME (frame)))
1424 && FRAME_TTY (XFRAME (frame)) == tty_out)
1425 FRAME_GARBAGED_P (XFRAME (frame)) = 1;
1429 tty_out->term_initted = 1;
1432 /* Return nonzero if safe to use tabs in output.
1433 At the time this is called, init_sys_modes has not been done yet. */
1436 tabs_safe_p (int fd)
1438 struct emacs_tty etty;
1440 EMACS_GET_TTY (fd, &etty);
1441 return EMACS_TTY_TABS_OK (&etty);
1444 /* Get terminal size from system.
1445 Store number of lines into *HEIGHTP and width into *WIDTHP.
1446 We store 0 if there's no valid information. */
1448 void
1449 get_tty_size (int fd, int *widthp, int *heightp)
1452 #ifdef TIOCGWINSZ
1454 /* BSD-style. */
1455 struct winsize size;
1457 if (ioctl (fd, TIOCGWINSZ, &size) == -1)
1458 *widthp = *heightp = 0;
1459 else
1461 *widthp = size.ws_col;
1462 *heightp = size.ws_row;
1465 #else
1466 #ifdef TIOCGSIZE
1468 /* SunOS - style. */
1469 struct ttysize size;
1471 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1472 *widthp = *heightp = 0;
1473 else
1475 *widthp = size.ts_cols;
1476 *heightp = size.ts_lines;
1479 #else
1480 #ifdef MSDOS
1481 *widthp = ScreenCols ();
1482 *heightp = ScreenRows ();
1483 #else /* system doesn't know size */
1484 *widthp = 0;
1485 *heightp = 0;
1486 #endif
1487 #endif /* not SunOS-style */
1488 #endif /* not BSD-style */
1491 /* Set the logical window size associated with descriptor FD
1492 to HEIGHT and WIDTH. This is used mainly with ptys. */
1495 set_window_size (fd, height, width)
1496 int fd, height, width;
1498 #ifdef TIOCSWINSZ
1500 /* BSD-style. */
1501 struct winsize size;
1502 size.ws_row = height;
1503 size.ws_col = width;
1505 if (ioctl (fd, TIOCSWINSZ, &size) == -1)
1506 return 0; /* error */
1507 else
1508 return 1;
1510 #else
1511 #ifdef TIOCSSIZE
1513 /* SunOS - style. */
1514 struct ttysize size;
1515 size.ts_lines = height;
1516 size.ts_cols = width;
1518 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1519 return 0;
1520 else
1521 return 1;
1522 #else
1523 return -1;
1524 #endif /* not SunOS-style */
1525 #endif /* not BSD-style */
1530 /* Prepare all terminal devices for exiting Emacs. */
1532 void
1533 reset_all_sys_modes (void)
1535 struct tty_display_info *tty;
1536 for (tty = tty_list; tty; tty = tty->next)
1537 reset_sys_modes (tty);
1540 /* Prepare the terminal for closing it; move the cursor to the
1541 bottom of the frame, turn off interrupt-driven I/O, etc. */
1543 void
1544 reset_sys_modes (tty_out)
1545 struct tty_display_info *tty_out;
1547 if (noninteractive)
1549 fflush (stdout);
1550 return;
1552 if (!tty_out->term_initted)
1553 return;
1555 if (!tty_out->output)
1556 return; /* The tty is suspended. */
1558 /* Go to and clear the last line of the terminal. */
1560 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1562 /* Code adapted from tty_clear_end_of_line. */
1563 if (tty_out->TS_clr_line)
1565 emacs_tputs (tty_out, tty_out->TS_clr_line, 1, cmputc);
1567 else
1568 { /* have to do it the hard way */
1569 int i;
1570 tty_turn_off_insert (tty_out);
1572 for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
1574 fputc (' ', tty_out->output);
1578 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
1579 fflush (tty_out->output);
1581 if (tty_out->terminal->reset_terminal_modes_hook)
1582 tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
1584 #ifdef BSD_SYSTEM
1585 /* Avoid possible loss of output when changing terminal modes. */
1586 fsync (fileno (tty_out->output));
1587 #endif
1589 #ifdef F_SETFL
1590 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1591 if (interrupt_input)
1593 reset_sigio (fileno (tty_out->input));
1594 fcntl (fileno (tty_out->input), F_SETOWN,
1595 old_fcntl_owner[fileno (tty_out->input)]);
1597 #endif /* F_SETOWN */
1598 #ifdef O_NDELAY
1599 fcntl (fileno (tty_out->input), F_SETFL,
1600 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NDELAY);
1601 #endif
1602 #endif /* F_SETFL */
1604 if (tty_out->old_tty)
1605 while (EMACS_SET_TTY (fileno (tty_out->input),
1606 tty_out->old_tty, 0) < 0 && errno == EINTR)
1609 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1610 dos_ttcooked ();
1611 #endif
1613 #ifdef BSD_PGRPS
1614 widen_foreground_group (fileno (tty_out->input));
1615 #endif
1618 #ifdef HAVE_PTYS
1620 /* Set up the proper status flags for use of a pty. */
1622 void
1623 setup_pty (fd)
1624 int fd;
1626 /* I'm told that TOICREMOTE does not mean control chars
1627 "can't be sent" but rather that they don't have
1628 input-editing or signaling effects.
1629 That should be good, because we have other ways
1630 to do those things in Emacs.
1631 However, telnet mode seems not to work on 4.2.
1632 So TIOCREMOTE is turned off now. */
1634 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1635 will hang. In particular, the "timeout" feature (which
1636 causes a read to return if there is no data available)
1637 does this. Also it is known that telnet mode will hang
1638 in such a way that Emacs must be stopped (perhaps this
1639 is the same problem).
1641 If TIOCREMOTE is turned off, then there is a bug in
1642 hp-ux which sometimes loses data. Apparently the
1643 code which blocks the master process when the internal
1644 buffer fills up does not work. Other than this,
1645 though, everything else seems to work fine.
1647 Since the latter lossage is more benign, we may as well
1648 lose that way. -- cph */
1649 #ifdef FIONBIO
1650 #if defined(UNIX98_PTYS)
1652 int on = 1;
1653 ioctl (fd, FIONBIO, &on);
1655 #endif
1656 #endif
1658 #endif /* HAVE_PTYS */
1660 #if !defined(CANNOT_DUMP) || !defined(SYSTEM_MALLOC)
1661 /* Some systems that cannot dump also cannot implement these. */
1664 * Return the address of the start of the text segment prior to
1665 * doing an unexec. After unexec the return value is undefined.
1666 * See crt0.c for further explanation and _start.
1670 #if !(defined (__NetBSD__) && defined (__ELF__))
1671 #ifndef HAVE_TEXT_START
1672 char *
1673 start_of_text ()
1675 #ifdef TEXT_START
1676 return ((char *) TEXT_START);
1677 #else
1678 extern int _start ();
1679 return ((char *) _start);
1680 #endif /* TEXT_START */
1682 #endif /* not HAVE_TEXT_START */
1683 #endif
1686 * Return the address of the start of the data segment prior to
1687 * doing an unexec. After unexec the return value is undefined.
1688 * See crt0.c for further information and definition of data_start.
1690 * Apparently, on BSD systems this is etext at startup. On
1691 * USG systems (swapping) this is highly mmu dependent and
1692 * is also dependent on whether or not the program is running
1693 * with shared text. Generally there is a (possibly large)
1694 * gap between end of text and start of data with shared text.
1696 * On Uniplus+ systems with shared text, data starts at a
1697 * fixed address. Each port (from a given oem) is generally
1698 * different, and the specific value of the start of data can
1699 * be obtained via the UniPlus+ specific "uvar" system call,
1700 * however the method outlined in crt0.c seems to be more portable.
1702 * Probably what will have to happen when a USG unexec is available,
1703 * at least on UniPlus, is temacs will have to be made unshared so
1704 * that text and data are contiguous. Then once loadup is complete,
1705 * unexec will produce a shared executable where the data can be
1706 * at the normal shared text boundary and the startofdata variable
1707 * will be patched by unexec to the correct value.
1711 #ifndef start_of_data
1712 char *
1713 start_of_data ()
1715 #ifdef DATA_START
1716 return ((char *) DATA_START);
1717 #else
1718 #ifdef ORDINARY_LINK
1720 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1721 * data_start isn't defined. We take the address of environ, which
1722 * is known to live at or near the start of the system crt0.c, and
1723 * we don't sweat the handful of bytes that might lose.
1725 extern char **environ;
1727 return ((char *) &environ);
1728 #else
1729 extern int data_start;
1730 return ((char *) &data_start);
1731 #endif /* ORDINARY_LINK */
1732 #endif /* DATA_START */
1734 #endif /* start_of_data */
1735 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1737 /* init_system_name sets up the string for the Lisp function
1738 system-name to return. */
1740 extern Lisp_Object impl_Vsystem_name;
1742 #ifdef HAVE_SOCKETS
1743 #include <sys/socket.h>
1744 #include <netdb.h>
1745 #endif /* HAVE_SOCKETS */
1747 #ifdef TRY_AGAIN
1748 #ifndef HAVE_H_ERRNO
1749 extern int h_errno;
1750 #endif
1751 #endif /* TRY_AGAIN */
1753 void
1754 init_system_name ()
1756 #ifndef HAVE_GETHOSTNAME
1757 struct utsname uts;
1758 uname (&uts);
1759 Vsystem_name = build_string (uts.nodename);
1760 #else /* HAVE_GETHOSTNAME */
1761 unsigned int hostname_size = 256;
1762 char *hostname = (char *) alloca (hostname_size);
1764 /* Try to get the host name; if the buffer is too short, try
1765 again. Apparently, the only indication gethostname gives of
1766 whether the buffer was large enough is the presence or absence
1767 of a '\0' in the string. Eech. */
1768 for (;;)
1770 gethostname (hostname, hostname_size - 1);
1771 hostname[hostname_size - 1] = '\0';
1773 /* Was the buffer large enough for the '\0'? */
1774 if (strlen (hostname) < hostname_size - 1)
1775 break;
1777 hostname_size <<= 1;
1778 hostname = (char *) alloca (hostname_size);
1780 #ifdef HAVE_SOCKETS
1781 /* Turn the hostname into the official, fully-qualified hostname.
1782 Don't do this if we're going to dump; this can confuse system
1783 libraries on some machines and make the dumped emacs core dump. */
1784 #ifndef CANNOT_DUMP
1785 if (initialized)
1786 #endif /* not CANNOT_DUMP */
1787 if (! index (hostname, '.'))
1789 int count;
1790 #ifdef HAVE_GETADDRINFO
1791 struct addrinfo *res;
1792 struct addrinfo hints;
1793 int ret;
1795 memset (&hints, 0, sizeof(hints));
1796 hints.ai_socktype = SOCK_STREAM;
1797 hints.ai_flags = AI_CANONNAME;
1799 for (count = 0;; count++)
1801 if ((ret = getaddrinfo (hostname, NULL, &hints, &res)) == 0
1802 || ret != EAI_AGAIN)
1803 break;
1805 if (count >= 5)
1806 break;
1807 Fsleep_for (make_number (1), Qnil);
1810 if (ret == 0)
1812 struct addrinfo *it = res;
1813 while (it)
1815 char *fqdn = it->ai_canonname;
1816 if (fqdn && index (fqdn, '.')
1817 && strcmp (fqdn, "localhost.localdomain") != 0)
1818 break;
1819 it = it->ai_next;
1821 if (it)
1823 hostname = alloca (strlen (it->ai_canonname) + 1);
1824 strcpy (hostname, it->ai_canonname);
1826 freeaddrinfo (res);
1828 #else /* !HAVE_GETADDRINFO */
1829 struct hostent *hp;
1830 for (count = 0;; count++)
1833 #ifdef TRY_AGAIN
1834 h_errno = 0;
1835 #endif
1836 hp = gethostbyname (hostname);
1837 #ifdef TRY_AGAIN
1838 if (! (hp == 0 && h_errno == TRY_AGAIN))
1839 #endif
1841 break;
1843 if (count >= 5)
1844 break;
1845 Fsleep_for (make_number (1), Qnil);
1848 if (hp)
1850 char *fqdn = (char *) hp->h_name;
1852 if (!index (fqdn, '.'))
1854 /* We still don't have a fully qualified domain name.
1855 Try to find one in the list of alternate names */
1856 char **alias = hp->h_aliases;
1857 while (*alias
1858 && (!index (*alias, '.')
1859 || !strcmp (*alias, "localhost.localdomain")))
1860 alias++;
1861 if (*alias)
1862 fqdn = *alias;
1864 hostname = fqdn;
1866 #endif /* !HAVE_GETADDRINFO */
1868 #endif /* HAVE_SOCKETS */
1869 Vsystem_name = build_string (hostname);
1870 #endif /* HAVE_GETHOSTNAME */
1872 unsigned char *p;
1873 for (p = SDATA (Vsystem_name); *p; p++)
1874 if (*p == ' ' || *p == '\t')
1875 *p = '-';
1879 #ifndef MSDOS
1880 #if !defined (HAVE_SELECT)
1882 #include "sysselect.h"
1883 #undef select
1885 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
1886 /* Cause explanatory error message at compile time,
1887 since the select emulation is not good enough for X. */
1888 int *x = &x_windows_lose_if_no_select_system_call;
1889 #endif
1891 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1892 * Only checks read descriptors.
1894 /* How long to wait between checking fds in select */
1895 #define SELECT_PAUSE 1
1896 int select_alarmed;
1898 /* For longjmp'ing back to read_input_waiting. */
1900 jmp_buf read_alarm_throw;
1902 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1903 The read_socket_hook function sets this to 1 while it is waiting. */
1905 int read_alarm_should_throw;
1907 SIGTYPE
1908 select_alarm ()
1910 select_alarmed = 1;
1911 signal (SIGALRM, SIG_IGN);
1912 SIGNAL_THREAD_CHECK (SIGALRM);
1913 if (read_alarm_should_throw)
1914 longjmp (read_alarm_throw, 1);
1917 #ifndef WINDOWSNT
1918 /* Only rfds are checked. */
1920 sys_select (nfds, rfds, wfds, efds, timeout)
1921 int nfds;
1922 SELECT_TYPE *rfds, *wfds, *efds;
1923 EMACS_TIME *timeout;
1925 /* XXX This needs to be updated for multi-tty support. Is there
1926 anybody who needs to emulate select these days? */
1927 int ravail = 0;
1928 SELECT_TYPE orfds;
1929 int timeoutval;
1930 int *local_timeout;
1931 extern int proc_buffered_char[];
1932 #ifndef subprocesses
1933 int process_tick = 0, update_tick = 0;
1934 #else
1935 extern int process_tick, update_tick;
1936 #endif
1937 unsigned char buf;
1939 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
1940 /* If we're using X, then the native select will work; we only need the
1941 emulation for non-X usage. */
1942 if (!NILP (Vinitial_window_system))
1943 return select (nfds, rfds, wfds, efds, timeout);
1944 #endif
1945 timeoutval = timeout ? EMACS_SECS (*timeout) : 100000;
1946 local_timeout = &timeoutval;
1947 FD_ZERO (&orfds);
1948 if (rfds)
1950 orfds = *rfds;
1951 FD_ZERO (rfds);
1953 if (wfds)
1954 FD_ZERO (wfds);
1955 if (efds)
1956 FD_ZERO (efds);
1958 /* If we are looking only for the terminal, with no timeout,
1959 just read it and wait -- that's more efficient. */
1960 if (*local_timeout == 100000 && process_tick == update_tick
1961 && FD_ISSET (0, &orfds))
1963 int fd;
1964 for (fd = 1; fd < nfds; ++fd)
1965 if (FD_ISSET (fd, &orfds))
1966 goto hardway;
1967 if (! detect_input_pending ())
1968 read_input_waiting ();
1969 FD_SET (0, rfds);
1970 return 1;
1973 hardway:
1974 /* Once a second, till the timer expires, check all the flagged read
1975 * descriptors to see if any input is available. If there is some then
1976 * set the corresponding bit in the return copy of rfds.
1978 while (1)
1980 register int to_check, fd;
1982 if (rfds)
1984 for (to_check = nfds, fd = 0; --to_check >= 0; fd++)
1986 if (FD_ISSET (fd, &orfds))
1988 int avail = 0, status = 0;
1990 if (fd == 0)
1991 avail = detect_input_pending (); /* Special keyboard handler */
1992 else
1994 #ifdef FIONREAD
1995 status = ioctl (fd, FIONREAD, &avail);
1996 #else /* no FIONREAD */
1997 /* Hoping it will return -1 if nothing available
1998 or 0 if all 0 chars requested are read. */
1999 if (proc_buffered_char[fd] >= 0)
2000 avail = 1;
2001 else
2003 avail = read (fd, &buf, 1);
2004 if (avail > 0)
2005 proc_buffered_char[fd] = buf;
2007 #endif /* no FIONREAD */
2009 if (status >= 0 && avail > 0)
2011 FD_SET (fd, rfds);
2012 ravail++;
2017 if (*local_timeout == 0 || ravail != 0 || process_tick != update_tick)
2018 break;
2020 turn_on_atimers (0);
2021 signal (SIGALRM, select_alarm);
2022 select_alarmed = 0;
2023 alarm (SELECT_PAUSE);
2025 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2026 while (select_alarmed == 0 && *local_timeout != 0
2027 && process_tick == update_tick)
2029 /* If we are interested in terminal input,
2030 wait by reading the terminal.
2031 That makes instant wakeup for terminal input at least. */
2032 if (FD_ISSET (0, &orfds))
2034 read_input_waiting ();
2035 if (detect_input_pending ())
2036 select_alarmed = 1;
2038 else
2039 pause ();
2041 (*local_timeout) -= SELECT_PAUSE;
2043 /* Reset the old alarm if there was one. */
2044 turn_on_atimers (1);
2046 if (*local_timeout == 0) /* Stop on timer being cleared */
2047 break;
2049 return ravail;
2051 #endif /* not WINDOWSNT */
2053 /* Read keyboard input into the standard buffer,
2054 waiting for at least one character. */
2056 void
2057 read_input_waiting ()
2059 /* XXX This needs to be updated for multi-tty support. Is there
2060 anybody who needs to emulate select these days? */
2061 int nread, i;
2062 extern int quit_char;
2064 if (read_socket_hook)
2066 struct input_event hold_quit;
2068 EVENT_INIT (hold_quit);
2069 hold_quit.kind = NO_EVENT;
2071 read_alarm_should_throw = 0;
2072 if (! setjmp (read_alarm_throw))
2073 nread = (*read_socket_hook) (0, 1, &hold_quit);
2074 else
2075 nread = -1;
2077 if (hold_quit.kind != NO_EVENT)
2078 kbd_buffer_store_event (&hold_quit);
2080 else
2082 struct input_event e;
2083 char buf[3];
2084 nread = read (fileno (stdin), buf, 1);
2085 EVENT_INIT (e);
2087 /* Scan the chars for C-g and store them in kbd_buffer. */
2088 e.kind = ASCII_KEYSTROKE_EVENT;
2089 e.frame_or_window = selected_frame;
2090 e.modifiers = 0;
2091 for (i = 0; i < nread; i++)
2093 /* Convert chars > 0177 to meta events if desired.
2094 We do this under the same conditions that read_avail_input does. */
2095 if (read_socket_hook == 0)
2097 /* If the user says she has a meta key, then believe her. */
2098 if (meta_key == 1 && (buf[i] & 0x80))
2099 e.modifiers = meta_modifier;
2100 if (meta_key != 2)
2101 buf[i] &= ~0x80;
2104 XSETINT (e.code, buf[i]);
2105 kbd_buffer_store_event (&e);
2106 /* Don't look at input that follows a C-g too closely.
2107 This reduces lossage due to autorepeat on C-g. */
2108 if (buf[i] == quit_char)
2109 break;
2114 #if !defined (HAVE_SELECT)
2115 #define select sys_select
2116 #endif
2118 #endif /* not HAVE_SELECT */
2119 #endif /* not MSDOS */
2121 /* POSIX signals support - DJB */
2122 /* Anyone with POSIX signals should have ANSI C declarations */
2124 #ifdef POSIX_SIGNALS
2126 sigset_t empty_mask, full_mask;
2128 signal_handler_t
2129 sys_signal (int signal_number, signal_handler_t action)
2131 struct sigaction new_action, old_action;
2132 sigemptyset (&new_action.sa_mask);
2133 new_action.sa_handler = action;
2134 new_action.sa_flags = 0;
2135 #if defined (SA_RESTART)
2136 /* Emacs mostly works better with restartable system services. If this
2137 flag exists, we probably want to turn it on here.
2138 However, on some systems this resets the timeout of `select'
2139 which means that `select' never finishes if it keeps getting signals.
2140 BROKEN_SA_RESTART is defined on those systems. */
2141 /* It's not clear why the comment above says "mostly works better". --Stef
2142 When SYNC_INPUT is set, we don't want SA_RESTART because we need to poll
2143 for pending input so we need long-running syscalls to be interrupted
2144 after a signal that sets the interrupt_input_pending flag. */
2145 /* Non-interactive keyboard input goes through stdio, where we always
2146 want restartable system calls. */
2147 # if defined (BROKEN_SA_RESTART) || defined(SYNC_INPUT)
2148 if (noninteractive)
2149 # endif
2150 new_action.sa_flags = SA_RESTART;
2151 #endif
2152 sigaction (signal_number, &new_action, &old_action);
2153 return (old_action.sa_handler);
2156 #ifndef __GNUC__
2157 /* If we're compiling with GCC, we don't need this function, since it
2158 can be written as a macro. */
2159 sigset_t
2160 sys_sigmask (int sig)
2162 sigset_t mask;
2163 sigemptyset (&mask);
2164 sigaddset (&mask, sig);
2165 return mask;
2167 #endif
2169 /* I'd like to have these guys return pointers to the mask storage in here,
2170 but there'd be trouble if the code was saving multiple masks. I'll be
2171 safe and pass the structure. It normally won't be more than 2 bytes
2172 anyhow. - DJB */
2174 sigset_t
2175 sys_sigblock (sigset_t new_mask)
2177 sigset_t old_mask;
2178 sigprocmask (SIG_BLOCK, &new_mask, &old_mask);
2179 return (old_mask);
2182 sigset_t
2183 sys_sigunblock (sigset_t new_mask)
2185 sigset_t old_mask;
2186 sigprocmask (SIG_UNBLOCK, &new_mask, &old_mask);
2187 return (old_mask);
2190 sigset_t
2191 sys_sigsetmask (sigset_t new_mask)
2193 sigset_t old_mask;
2194 sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
2195 return (old_mask);
2198 #endif /* POSIX_SIGNALS */
2200 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2201 static char *my_sys_siglist[NSIG];
2202 # ifdef sys_siglist
2203 # undef sys_siglist
2204 # endif
2205 # define sys_siglist my_sys_siglist
2206 #endif
2208 void
2209 init_signals ()
2211 #ifdef POSIX_SIGNALS
2212 sigemptyset (&empty_mask);
2213 sigfillset (&full_mask);
2214 #endif
2216 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2217 if (! initialized)
2219 # ifdef SIGABRT
2220 sys_siglist[SIGABRT] = "Aborted";
2221 # endif
2222 # ifdef SIGAIO
2223 sys_siglist[SIGAIO] = "LAN I/O interrupt";
2224 # endif
2225 # ifdef SIGALRM
2226 sys_siglist[SIGALRM] = "Alarm clock";
2227 # endif
2228 # ifdef SIGBUS
2229 sys_siglist[SIGBUS] = "Bus error";
2230 # endif
2231 # ifdef SIGCLD
2232 sys_siglist[SIGCLD] = "Child status changed";
2233 # endif
2234 # ifdef SIGCHLD
2235 sys_siglist[SIGCHLD] = "Child status changed";
2236 # endif
2237 # ifdef SIGCONT
2238 sys_siglist[SIGCONT] = "Continued";
2239 # endif
2240 # ifdef SIGDANGER
2241 sys_siglist[SIGDANGER] = "Swap space dangerously low";
2242 # endif
2243 # ifdef SIGDGNOTIFY
2244 sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
2245 # endif
2246 # ifdef SIGEMT
2247 sys_siglist[SIGEMT] = "Emulation trap";
2248 # endif
2249 # ifdef SIGFPE
2250 sys_siglist[SIGFPE] = "Arithmetic exception";
2251 # endif
2252 # ifdef SIGFREEZE
2253 sys_siglist[SIGFREEZE] = "SIGFREEZE";
2254 # endif
2255 # ifdef SIGGRANT
2256 sys_siglist[SIGGRANT] = "Monitor mode granted";
2257 # endif
2258 # ifdef SIGHUP
2259 sys_siglist[SIGHUP] = "Hangup";
2260 # endif
2261 # ifdef SIGILL
2262 sys_siglist[SIGILL] = "Illegal instruction";
2263 # endif
2264 # ifdef SIGINT
2265 sys_siglist[SIGINT] = "Interrupt";
2266 # endif
2267 # ifdef SIGIO
2268 sys_siglist[SIGIO] = "I/O possible";
2269 # endif
2270 # ifdef SIGIOINT
2271 sys_siglist[SIGIOINT] = "I/O intervention required";
2272 # endif
2273 # ifdef SIGIOT
2274 sys_siglist[SIGIOT] = "IOT trap";
2275 # endif
2276 # ifdef SIGKILL
2277 sys_siglist[SIGKILL] = "Killed";
2278 # endif
2279 # ifdef SIGLOST
2280 sys_siglist[SIGLOST] = "Resource lost";
2281 # endif
2282 # ifdef SIGLWP
2283 sys_siglist[SIGLWP] = "SIGLWP";
2284 # endif
2285 # ifdef SIGMSG
2286 sys_siglist[SIGMSG] = "Monitor mode data available";
2287 # endif
2288 # ifdef SIGPHONE
2289 sys_siglist[SIGWIND] = "SIGPHONE";
2290 # endif
2291 # ifdef SIGPIPE
2292 sys_siglist[SIGPIPE] = "Broken pipe";
2293 # endif
2294 # ifdef SIGPOLL
2295 sys_siglist[SIGPOLL] = "Pollable event occurred";
2296 # endif
2297 # ifdef SIGPROF
2298 sys_siglist[SIGPROF] = "Profiling timer expired";
2299 # endif
2300 # ifdef SIGPTY
2301 sys_siglist[SIGPTY] = "PTY I/O interrupt";
2302 # endif
2303 # ifdef SIGPWR
2304 sys_siglist[SIGPWR] = "Power-fail restart";
2305 # endif
2306 # ifdef SIGQUIT
2307 sys_siglist[SIGQUIT] = "Quit";
2308 # endif
2309 # ifdef SIGRETRACT
2310 sys_siglist[SIGRETRACT] = "Need to relinguish monitor mode";
2311 # endif
2312 # ifdef SIGSAK
2313 sys_siglist[SIGSAK] = "Secure attention";
2314 # endif
2315 # ifdef SIGSEGV
2316 sys_siglist[SIGSEGV] = "Segmentation violation";
2317 # endif
2318 # ifdef SIGSOUND
2319 sys_siglist[SIGSOUND] = "Sound completed";
2320 # endif
2321 # ifdef SIGSTOP
2322 sys_siglist[SIGSTOP] = "Stopped (signal)";
2323 # endif
2324 # ifdef SIGSTP
2325 sys_siglist[SIGSTP] = "Stopped (user)";
2326 # endif
2327 # ifdef SIGSYS
2328 sys_siglist[SIGSYS] = "Bad argument to system call";
2329 # endif
2330 # ifdef SIGTERM
2331 sys_siglist[SIGTERM] = "Terminated";
2332 # endif
2333 # ifdef SIGTHAW
2334 sys_siglist[SIGTHAW] = "SIGTHAW";
2335 # endif
2336 # ifdef SIGTRAP
2337 sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
2338 # endif
2339 # ifdef SIGTSTP
2340 sys_siglist[SIGTSTP] = "Stopped (user)";
2341 # endif
2342 # ifdef SIGTTIN
2343 sys_siglist[SIGTTIN] = "Stopped (tty input)";
2344 # endif
2345 # ifdef SIGTTOU
2346 sys_siglist[SIGTTOU] = "Stopped (tty output)";
2347 # endif
2348 # ifdef SIGURG
2349 sys_siglist[SIGURG] = "Urgent I/O condition";
2350 # endif
2351 # ifdef SIGUSR1
2352 sys_siglist[SIGUSR1] = "User defined signal 1";
2353 # endif
2354 # ifdef SIGUSR2
2355 sys_siglist[SIGUSR2] = "User defined signal 2";
2356 # endif
2357 # ifdef SIGVTALRM
2358 sys_siglist[SIGVTALRM] = "Virtual timer expired";
2359 # endif
2360 # ifdef SIGWAITING
2361 sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
2362 # endif
2363 # ifdef SIGWINCH
2364 sys_siglist[SIGWINCH] = "Window size changed";
2365 # endif
2366 # ifdef SIGWIND
2367 sys_siglist[SIGWIND] = "SIGWIND";
2368 # endif
2369 # ifdef SIGXCPU
2370 sys_siglist[SIGXCPU] = "CPU time limit exceeded";
2371 # endif
2372 # ifdef SIGXFSZ
2373 sys_siglist[SIGXFSZ] = "File size limit exceeded";
2374 # endif
2376 #endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
2379 #ifndef HAVE_RANDOM
2380 #ifdef random
2381 #define HAVE_RANDOM
2382 #endif
2383 #endif
2385 /* Figure out how many bits the system's random number generator uses.
2386 `random' and `lrand48' are assumed to return 31 usable bits.
2387 BSD `rand' returns a 31 bit value but the low order bits are unusable;
2388 so we'll shift it and treat it like the 15-bit USG `rand'. */
2390 #ifndef RAND_BITS
2391 # ifdef HAVE_RANDOM
2392 # define RAND_BITS 31
2393 # else /* !HAVE_RANDOM */
2394 # ifdef HAVE_LRAND48
2395 # define RAND_BITS 31
2396 # define random lrand48
2397 # else /* !HAVE_LRAND48 */
2398 # define RAND_BITS 15
2399 # if RAND_MAX == 32767
2400 # define random rand
2401 # else /* RAND_MAX != 32767 */
2402 # if RAND_MAX == 2147483647
2403 # define random() (rand () >> 16)
2404 # else /* RAND_MAX != 2147483647 */
2405 # ifdef USG
2406 # define random rand
2407 # else
2408 # define random() (rand () >> 16)
2409 # endif /* !USG */
2410 # endif /* RAND_MAX != 2147483647 */
2411 # endif /* RAND_MAX != 32767 */
2412 # endif /* !HAVE_LRAND48 */
2413 # endif /* !HAVE_RANDOM */
2414 #endif /* !RAND_BITS */
2416 void
2417 seed_random (arg)
2418 long arg;
2420 #ifdef HAVE_RANDOM
2421 srandom ((unsigned int)arg);
2422 #else
2423 # ifdef HAVE_LRAND48
2424 srand48 (arg);
2425 # else
2426 srand ((unsigned int)arg);
2427 # endif
2428 #endif
2432 * Build a full Emacs-sized word out of whatever we've got.
2433 * This suffices even for a 64-bit architecture with a 15-bit rand.
2435 long
2436 get_random ()
2438 long val = random ();
2439 #if VALBITS > RAND_BITS
2440 val = (val << RAND_BITS) ^ random ();
2441 #if VALBITS > 2*RAND_BITS
2442 val = (val << RAND_BITS) ^ random ();
2443 #if VALBITS > 3*RAND_BITS
2444 val = (val << RAND_BITS) ^ random ();
2445 #if VALBITS > 4*RAND_BITS
2446 val = (val << RAND_BITS) ^ random ();
2447 #endif /* need at least 5 */
2448 #endif /* need at least 4 */
2449 #endif /* need at least 3 */
2450 #endif /* need at least 2 */
2451 return val & ((1L << VALBITS) - 1);
2454 #ifndef HAVE_STRERROR
2455 #ifndef WINDOWSNT
2456 char *
2457 strerror (errnum)
2458 int errnum;
2460 extern char *sys_errlist[];
2461 extern int sys_nerr;
2463 if (errnum >= 0 && errnum < sys_nerr)
2464 return sys_errlist[errnum];
2465 return (char *) "Unknown error";
2467 #endif /* not WINDOWSNT */
2468 #endif /* ! HAVE_STRERROR */
2471 emacs_open (path, oflag, mode)
2472 const char *path;
2473 int oflag, mode;
2475 register int rtnval;
2477 while ((rtnval = open (path, oflag, mode)) == -1
2478 && (errno == EINTR))
2479 QUIT;
2480 return (rtnval);
2484 emacs_close (fd)
2485 int fd;
2487 int did_retry = 0;
2488 register int rtnval;
2490 while ((rtnval = close (fd)) == -1
2491 && (errno == EINTR))
2492 did_retry = 1;
2494 /* If close is interrupted SunOS 4.1 may or may not have closed the
2495 file descriptor. If it did the second close will fail with
2496 errno = EBADF. That means we have succeeded. */
2497 if (rtnval == -1 && did_retry && errno == EBADF)
2498 return 0;
2500 return rtnval;
2504 emacs_read (fildes, buf, nbyte)
2505 int fildes;
2506 char *buf;
2507 unsigned int nbyte;
2509 register int rtnval;
2511 while ((rtnval = read (fildes, buf, nbyte)) == -1
2512 && (errno == EINTR))
2513 QUIT;
2514 return (rtnval);
2518 emacs_write (fildes, buf, nbyte)
2519 int fildes;
2520 const char *buf;
2521 unsigned int nbyte;
2523 register int rtnval, bytes_written;
2525 bytes_written = 0;
2527 while (nbyte > 0)
2529 rtnval = write (fildes, buf, nbyte);
2531 if (rtnval == -1)
2533 if (errno == EINTR)
2535 #ifdef SYNC_INPUT
2536 /* I originally used `QUIT' but that might causes files to
2537 be truncated if you hit C-g in the middle of it. --Stef */
2538 process_pending_signals ();
2539 #endif
2540 continue;
2542 else
2543 return (bytes_written ? bytes_written : -1);
2546 buf += rtnval;
2547 nbyte -= rtnval;
2548 bytes_written += rtnval;
2550 return (bytes_written);
2553 #ifdef USG
2555 * All of the following are for USG.
2557 * On USG systems the system calls are INTERRUPTIBLE by signals
2558 * that the user program has elected to catch. Thus the system call
2559 * must be retried in these cases. To handle this without massive
2560 * changes in the source code, we remap the standard system call names
2561 * to names for our own functions in sysdep.c that do the system call
2562 * with retries. Actually, for portability reasons, it is good
2563 * programming practice, as this example shows, to limit all actual
2564 * system calls to a single occurrence in the source. Sure, this
2565 * adds an extra level of function call overhead but it is almost
2566 * always negligible. Fred Fish, Unisoft Systems Inc.
2570 * Warning, this function may not duplicate 4.2 action properly
2571 * under error conditions.
2574 #ifndef MAXPATHLEN
2575 /* In 4.1, param.h fails to define this. */
2576 #define MAXPATHLEN 1024
2577 #endif
2579 #ifndef HAVE_GETWD
2581 char *
2582 getwd (pathname)
2583 char *pathname;
2585 char *npath, *spath;
2586 extern char *getcwd ();
2588 BLOCK_INPUT; /* getcwd uses malloc */
2589 spath = npath = getcwd ((char *) 0, MAXPATHLEN);
2590 if (spath == 0)
2592 UNBLOCK_INPUT;
2593 return spath;
2595 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2596 up to first slash. Should be harmless on other systems. */
2597 while (*npath && *npath != '/')
2598 npath++;
2599 strcpy (pathname, npath);
2600 free (spath); /* getcwd uses malloc */
2601 UNBLOCK_INPUT;
2602 return pathname;
2605 #endif /* HAVE_GETWD */
2608 * Emulate rename using unlink/link. Note that this is
2609 * only partially correct. Also, doesn't enforce restriction
2610 * that files be of same type (regular->regular, dir->dir, etc).
2613 #ifndef HAVE_RENAME
2615 rename (from, to)
2616 const char *from;
2617 const char *to;
2619 if (access (from, 0) == 0)
2621 unlink (to);
2622 if (link (from, to) == 0)
2623 if (unlink (from) == 0)
2624 return (0);
2626 return (-1);
2629 #endif
2632 #if defined(HPUX) && !defined(HAVE_PERROR)
2634 /* HPUX curses library references perror, but as far as we know
2635 it won't be called. Anyway this definition will do for now. */
2637 perror ()
2640 #endif /* HPUX and not HAVE_PERROR */
2642 #ifndef HAVE_DUP2
2645 * Emulate BSD dup2. First close newd if it already exists.
2646 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2647 * until we are, then close the unsuccessful ones.
2650 dup2 (oldd, newd)
2651 int oldd;
2652 int newd;
2654 register int fd, ret;
2656 emacs_close (newd);
2658 #ifdef F_DUPFD
2659 return fcntl (oldd, F_DUPFD, newd);
2660 #else
2661 fd = dup (old);
2662 if (fd == -1)
2663 return -1;
2664 if (fd == new)
2665 return new;
2666 ret = dup2 (old,new);
2667 emacs_close (fd);
2668 return ret;
2669 #endif
2672 #endif /* not HAVE_DUP2 */
2675 * Gettimeofday. Simulate as much as possible. Only accurate
2676 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2677 * Only needed when subprocesses are defined.
2680 #ifdef subprocesses
2681 #ifndef HAVE_GETTIMEOFDAY
2682 #ifdef HAVE_TIMEVAL
2684 /* ARGSUSED */
2686 gettimeofday (tp, tzp)
2687 struct timeval *tp;
2688 struct timezone *tzp;
2690 extern long time ();
2692 tp->tv_sec = time ((long *)0);
2693 tp->tv_usec = 0;
2694 if (tzp != 0)
2695 tzp->tz_minuteswest = -1;
2696 return 0;
2699 #endif
2700 #endif
2701 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL */
2704 * This function will go away as soon as all the stubs fixed. (fnf)
2707 void
2708 croak (badfunc)
2709 char *badfunc;
2711 printf ("%s not yet implemented\r\n", badfunc);
2712 reset_all_sys_modes ();
2713 exit (1);
2716 #endif /* USG */
2718 /* Directory routines for systems that don't have them. */
2720 #ifdef SYSV_SYSTEM_DIR
2722 #include <dirent.h>
2724 #if !defined (HAVE_CLOSEDIR)
2727 closedir (DIR *dirp /* stream from opendir */)
2729 int rtnval;
2731 rtnval = emacs_close (dirp->dd_fd);
2733 /* Some systems (like Solaris) allocate the buffer and the DIR all
2734 in one block. Why in the world are we freeing this ourselves
2735 anyway? */
2736 #if ! defined (SOLARIS2)
2737 xfree ((char *) dirp->dd_buf); /* directory block defined in <dirent.h> */
2738 #endif
2739 xfree ((char *) dirp);
2741 return rtnval;
2743 #endif /* not HAVE_CLOSEDIR */
2744 #endif /* SYSV_SYSTEM_DIR */
2748 set_file_times (filename, atime, mtime)
2749 const char *filename;
2750 EMACS_TIME atime, mtime;
2752 #ifdef HAVE_UTIMES
2753 struct timeval tv[2];
2754 tv[0] = atime;
2755 tv[1] = mtime;
2756 return utimes (filename, tv);
2757 #else /* not HAVE_UTIMES */
2758 struct utimbuf utb;
2759 utb.actime = EMACS_SECS (atime);
2760 utb.modtime = EMACS_SECS (mtime);
2761 return utime (filename, &utb);
2762 #endif /* not HAVE_UTIMES */
2765 /* mkdir and rmdir functions, for systems which don't have them. */
2767 #ifndef HAVE_MKDIR
2769 * Written by Robert Rother, Mariah Corporation, August 1985.
2771 * If you want it, it's yours. All I ask in return is that if you
2772 * figure out how to do this in a Bourne Shell script you send me
2773 * a copy.
2774 * sdcsvax!rmr or rmr@uscd
2776 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
2777 * subroutine. 11Mar86; hoptoad!gnu
2779 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
2780 * subroutine didn't return EEXIST. It does now.
2784 * Make a directory.
2787 mkdir (dpath, dmode)
2788 char *dpath;
2789 int dmode;
2791 int cpid, status, fd;
2792 struct stat statbuf;
2794 if (stat (dpath, &statbuf) == 0)
2796 errno = EEXIST; /* Stat worked, so it already exists */
2797 return -1;
2800 /* If stat fails for a reason other than non-existence, return error */
2801 if (errno != ENOENT)
2802 return -1;
2804 synch_process_alive = 1;
2805 switch (cpid = fork ())
2808 case -1: /* Error in fork */
2809 return (-1); /* Errno is set already */
2811 case 0: /* Child process */
2813 * Cheap hack to set mode of new directory. Since this
2814 * child process is going away anyway, we zap its umask.
2815 * FIXME, this won't suffice to set SUID, SGID, etc. on this
2816 * directory. Does anybody care?
2818 status = umask (0); /* Get current umask */
2819 status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
2820 fd = emacs_open ("/dev/null", O_RDWR, 0);
2821 if (fd >= 0)
2823 dup2 (fd, 0);
2824 dup2 (fd, 1);
2825 dup2 (fd, 2);
2827 execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
2828 _exit (-1); /* Can't exec /bin/mkdir */
2830 default: /* Parent process */
2831 wait_for_termination (cpid);
2834 if (synch_process_death != 0 || synch_process_retcode != 0
2835 || synch_process_termsig != 0)
2837 errno = EIO; /* We don't know why, but */
2838 return -1; /* /bin/mkdir failed */
2841 return 0;
2843 #endif /* not HAVE_MKDIR */
2845 #ifndef HAVE_RMDIR
2847 rmdir (dpath)
2848 char *dpath;
2850 int cpid, status, fd;
2851 struct stat statbuf;
2853 if (stat (dpath, &statbuf) != 0)
2855 /* Stat just set errno. We don't have to */
2856 return -1;
2859 synch_process_alive = 1;
2860 switch (cpid = fork ())
2863 case -1: /* Error in fork */
2864 return (-1); /* Errno is set already */
2866 case 0: /* Child process */
2867 fd = emacs_open ("/dev/null", O_RDWR, 0);
2868 if (fd >= 0)
2870 dup2 (fd, 0);
2871 dup2 (fd, 1);
2872 dup2 (fd, 2);
2874 execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
2875 _exit (-1); /* Can't exec /bin/rmdir */
2877 default: /* Parent process */
2878 wait_for_termination (cpid);
2881 if (synch_process_death != 0 || synch_process_retcode != 0
2882 || synch_process_termsig != 0)
2884 errno = EIO; /* We don't know why, but */
2885 return -1; /* /bin/rmdir failed */
2888 return 0;
2890 #endif /* !HAVE_RMDIR */
2893 #ifndef BSTRING
2895 #ifndef bzero
2897 void
2898 bzero (b, length)
2899 register char *b;
2900 register int length;
2902 while (length-- > 0)
2903 *b++ = 0;
2906 #endif /* no bzero */
2907 #endif /* BSTRING */
2909 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
2910 #undef bcopy
2912 /* Saying `void' requires a declaration, above, where bcopy is used
2913 and that declaration causes pain for systems where bcopy is a macro. */
2914 bcopy (b1, b2, length)
2915 register char *b1;
2916 register char *b2;
2917 register int length;
2919 while (length-- > 0)
2920 *b2++ = *b1++;
2922 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
2924 #ifndef BSTRING
2925 #ifndef bcmp
2927 bcmp (b1, b2, length) /* This could be a macro! */
2928 register char *b1;
2929 register char *b2;
2930 register int length;
2932 while (length-- > 0)
2933 if (*b1++ != *b2++)
2934 return 1;
2936 return 0;
2938 #endif /* no bcmp */
2939 #endif /* not BSTRING */
2941 #ifndef HAVE_STRSIGNAL
2942 char *
2943 strsignal (code)
2944 int code;
2946 char *signame = 0;
2948 if (0 <= code && code < NSIG)
2950 /* Cast to suppress warning if the table has const char *. */
2951 signame = (char *) sys_siglist[code];
2954 return signame;
2956 #endif /* HAVE_STRSIGNAL */
2958 #ifdef HAVE_TERMIOS
2959 /* For make-serial-process */
2960 int serial_open (char *port)
2962 int fd = -1;
2964 fd = emacs_open ((char*) port,
2965 O_RDWR
2966 #ifdef O_NONBLOCK
2967 | O_NONBLOCK
2968 #else
2969 | O_NDELAY
2970 #endif
2971 #ifdef O_NOCTTY
2972 | O_NOCTTY
2973 #endif
2974 , 0);
2975 if (fd < 0)
2977 error ("Could not open %s: %s",
2978 port, emacs_strerror (errno));
2980 #ifdef TIOCEXCL
2981 ioctl (fd, TIOCEXCL, (char *) 0);
2982 #endif
2984 return fd;
2986 #endif /* TERMIOS */
2988 #ifdef HAVE_TERMIOS
2990 #if !defined (HAVE_CFMAKERAW)
2991 /* Workaround for targets which are missing cfmakeraw. */
2992 /* Pasted from man page. */
2993 static void cfmakeraw (struct termios *termios_p)
2995 termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
2996 termios_p->c_oflag &= ~OPOST;
2997 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
2998 termios_p->c_cflag &= ~(CSIZE|PARENB);
2999 termios_p->c_cflag |= CS8;
3001 #endif /* !defined (HAVE_CFMAKERAW */
3003 #if !defined (HAVE_CFSETSPEED)
3004 /* Workaround for targets which are missing cfsetspeed. */
3005 static int cfsetspeed (struct termios *termios_p, speed_t vitesse)
3007 return (cfsetispeed (termios_p, vitesse)
3008 + cfsetospeed (termios_p, vitesse));
3010 #endif
3012 /* For serial-process-configure */
3013 void
3014 serial_configure (struct Lisp_Process *p,
3015 Lisp_Object contact)
3017 Lisp_Object childp2 = Qnil;
3018 Lisp_Object tem = Qnil;
3019 struct termios attr;
3020 int err = -1;
3021 char summary[4] = "???"; /* This usually becomes "8N1". */
3023 childp2 = Fcopy_sequence (p->childp);
3025 /* Read port attributes and prepare default configuration. */
3026 err = tcgetattr (p->outfd, &attr);
3027 if (err != 0)
3028 error ("tcgetattr() failed: %s", emacs_strerror (errno));
3029 cfmakeraw (&attr);
3030 #if defined (CLOCAL)
3031 attr.c_cflag |= CLOCAL;
3032 #endif
3033 #if defined (CREAD)
3034 attr.c_cflag |= CREAD;
3035 #endif
3037 /* Configure speed. */
3038 if (!NILP (Fplist_member (contact, QCspeed)))
3039 tem = Fplist_get (contact, QCspeed);
3040 else
3041 tem = Fplist_get (p->childp, QCspeed);
3042 CHECK_NUMBER (tem);
3043 err = cfsetspeed (&attr, XINT (tem));
3044 if (err != 0)
3045 error ("cfsetspeed(%d) failed: %s", XINT (tem), emacs_strerror (errno));
3046 childp2 = Fplist_put (childp2, QCspeed, tem);
3048 /* Configure bytesize. */
3049 if (!NILP (Fplist_member (contact, QCbytesize)))
3050 tem = Fplist_get (contact, QCbytesize);
3051 else
3052 tem = Fplist_get (p->childp, QCbytesize);
3053 if (NILP (tem))
3054 tem = make_number (8);
3055 CHECK_NUMBER (tem);
3056 if (XINT (tem) != 7 && XINT (tem) != 8)
3057 error (":bytesize must be nil (8), 7, or 8");
3058 summary[0] = XINT(tem) + '0';
3059 #if defined (CSIZE) && defined (CS7) && defined (CS8)
3060 attr.c_cflag &= ~CSIZE;
3061 attr.c_cflag |= ((XINT (tem) == 7) ? CS7 : CS8);
3062 #else
3063 /* Don't error on bytesize 8, which should be set by cfmakeraw. */
3064 if (XINT (tem) != 8)
3065 error ("Bytesize cannot be changed");
3066 #endif
3067 childp2 = Fplist_put (childp2, QCbytesize, tem);
3069 /* Configure parity. */
3070 if (!NILP (Fplist_member (contact, QCparity)))
3071 tem = Fplist_get (contact, QCparity);
3072 else
3073 tem = Fplist_get (p->childp, QCparity);
3074 if (!NILP (tem) && !EQ (tem, Qeven) && !EQ (tem, Qodd))
3075 error (":parity must be nil (no parity), `even', or `odd'");
3076 #if defined (PARENB) && defined (PARODD) && defined (IGNPAR) && defined (INPCK)
3077 attr.c_cflag &= ~(PARENB | PARODD);
3078 attr.c_iflag &= ~(IGNPAR | INPCK);
3079 if (NILP (tem))
3081 summary[1] = 'N';
3083 else if (EQ (tem, Qeven))
3085 summary[1] = 'E';
3086 attr.c_cflag |= PARENB;
3087 attr.c_iflag |= (IGNPAR | INPCK);
3089 else if (EQ (tem, Qodd))
3091 summary[1] = 'O';
3092 attr.c_cflag |= (PARENB | PARODD);
3093 attr.c_iflag |= (IGNPAR | INPCK);
3095 #else
3096 /* Don't error on no parity, which should be set by cfmakeraw. */
3097 if (!NILP (tem))
3098 error ("Parity cannot be configured");
3099 #endif
3100 childp2 = Fplist_put (childp2, QCparity, tem);
3102 /* Configure stopbits. */
3103 if (!NILP (Fplist_member (contact, QCstopbits)))
3104 tem = Fplist_get (contact, QCstopbits);
3105 else
3106 tem = Fplist_get (p->childp, QCstopbits);
3107 if (NILP (tem))
3108 tem = make_number (1);
3109 CHECK_NUMBER (tem);
3110 if (XINT (tem) != 1 && XINT (tem) != 2)
3111 error (":stopbits must be nil (1 stopbit), 1, or 2");
3112 summary[2] = XINT (tem) + '0';
3113 #if defined (CSTOPB)
3114 attr.c_cflag &= ~CSTOPB;
3115 if (XINT (tem) == 2)
3116 attr.c_cflag |= CSTOPB;
3117 #else
3118 /* Don't error on 1 stopbit, which should be set by cfmakeraw. */
3119 if (XINT (tem) != 1)
3120 error ("Stopbits cannot be configured");
3121 #endif
3122 childp2 = Fplist_put (childp2, QCstopbits, tem);
3124 /* Configure flowcontrol. */
3125 if (!NILP (Fplist_member (contact, QCflowcontrol)))
3126 tem = Fplist_get (contact, QCflowcontrol);
3127 else
3128 tem = Fplist_get (p->childp, QCflowcontrol);
3129 if (!NILP (tem) && !EQ (tem, Qhw) && !EQ (tem, Qsw))
3130 error (":flowcontrol must be nil (no flowcontrol), `hw', or `sw'");
3131 #if defined (CRTSCTS)
3132 attr.c_cflag &= ~CRTSCTS;
3133 #endif
3134 #if defined (CNEW_RTSCTS)
3135 attr.c_cflag &= ~CNEW_RTSCTS;
3136 #endif
3137 #if defined (IXON) && defined (IXOFF)
3138 attr.c_iflag &= ~(IXON | IXOFF);
3139 #endif
3140 if (NILP (tem))
3142 /* Already configured. */
3144 else if (EQ (tem, Qhw))
3146 #if defined (CRTSCTS)
3147 attr.c_cflag |= CRTSCTS;
3148 #elif defined (CNEW_RTSCTS)
3149 attr.c_cflag |= CNEW_RTSCTS;
3150 #else
3151 error ("Hardware flowcontrol (RTS/CTS) not supported");
3152 #endif
3154 else if (EQ (tem, Qsw))
3156 #if defined (IXON) && defined (IXOFF)
3157 attr.c_iflag |= (IXON | IXOFF);
3158 #else
3159 error ("Software flowcontrol (XON/XOFF) not supported");
3160 #endif
3162 childp2 = Fplist_put (childp2, QCflowcontrol, tem);
3164 /* Activate configuration. */
3165 err = tcsetattr (p->outfd, TCSANOW, &attr);
3166 if (err != 0)
3167 error ("tcsetattr() failed: %s", emacs_strerror (errno));
3169 childp2 = Fplist_put (childp2, QCsummary, build_string (summary));
3170 p->childp = childp2;
3173 #endif /* TERMIOS */
3175 /* System depended enumeration of and access to system processes a-la ps(1). */
3177 #ifdef HAVE_PROCFS
3179 /* Process enumeration and access via /proc. */
3181 Lisp_Object
3182 list_system_processes ()
3184 Lisp_Object procdir, match, proclist, next;
3185 struct gcpro gcpro1, gcpro2;
3186 register Lisp_Object tail;
3188 GCPRO2 (procdir, match);
3189 /* For every process on the system, there's a directory in the
3190 "/proc" pseudo-directory whose name is the numeric ID of that
3191 process. */
3192 procdir = build_string ("/proc");
3193 match = build_string ("[0-9]+");
3194 proclist = directory_files_internal (procdir, Qnil, match, Qt, 0, Qnil);
3196 /* `proclist' gives process IDs as strings. Destructively convert
3197 each string into a number. */
3198 for (tail = proclist; CONSP (tail); tail = next)
3200 next = XCDR (tail);
3201 XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil));
3203 UNGCPRO;
3205 /* directory_files_internal returns the files in reverse order; undo
3206 that. */
3207 proclist = Fnreverse (proclist);
3208 return proclist;
3211 /* The WINDOWSNT implementation is in w32.c.
3212 The MSDOS implementation is in dosfns.c. */
3213 #elif !defined (WINDOWSNT) && !defined (MSDOS)
3215 Lisp_Object
3216 list_system_processes ()
3218 return Qnil;
3221 #endif /* !defined (WINDOWSNT) */
3223 #ifdef GNU_LINUX
3224 static void
3225 time_from_jiffies (unsigned long long tval, long hz,
3226 time_t *sec, unsigned *usec)
3228 unsigned long long ullsec;
3230 *sec = tval / hz;
3231 ullsec = *sec;
3232 tval -= ullsec * hz;
3233 /* Careful: if HZ > 1 million, then integer division by it yields zero. */
3234 if (hz <= 1000000)
3235 *usec = tval * 1000000 / hz;
3236 else
3237 *usec = tval / (hz / 1000000);
3240 static Lisp_Object
3241 ltime_from_jiffies (unsigned long long tval, long hz)
3243 time_t sec;
3244 unsigned usec;
3246 time_from_jiffies (tval, hz, &sec, &usec);
3248 return list3 (make_number ((sec >> 16) & 0xffff),
3249 make_number (sec & 0xffff),
3250 make_number (usec));
3253 static void
3254 get_up_time (time_t *sec, unsigned *usec)
3256 FILE *fup;
3258 *sec = *usec = 0;
3260 BLOCK_INPUT;
3261 fup = fopen ("/proc/uptime", "r");
3263 if (fup)
3265 double uptime, idletime;
3267 /* The numbers in /proc/uptime use C-locale decimal point, but
3268 we already set ourselves to the C locale (see `fixup_locale'
3269 in emacs.c). */
3270 if (2 <= fscanf (fup, "%lf %lf", &uptime, &idletime))
3272 *sec = uptime;
3273 *usec = (uptime - *sec) * 1000000;
3275 fclose (fup);
3277 UNBLOCK_INPUT;
3280 #define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
3281 #define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12))
3283 static Lisp_Object
3284 procfs_ttyname (int rdev)
3286 FILE *fdev = NULL;
3287 char name[PATH_MAX];
3289 BLOCK_INPUT;
3290 fdev = fopen ("/proc/tty/drivers", "r");
3292 if (fdev)
3294 unsigned major;
3295 unsigned long minor_beg, minor_end;
3296 char minor[25]; /* 2 32-bit numbers + dash */
3297 char *endp;
3299 while (!feof (fdev) && !ferror (fdev))
3301 if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor)
3302 && major == MAJOR (rdev))
3304 minor_beg = strtoul (minor, &endp, 0);
3305 if (*endp == '\0')
3306 minor_end = minor_beg;
3307 else if (*endp == '-')
3308 minor_end = strtoul (endp + 1, &endp, 0);
3309 else
3310 continue;
3312 if (MINOR (rdev) >= minor_beg && MINOR (rdev) <= minor_end)
3314 sprintf (name + strlen (name), "%u", MINOR (rdev));
3315 break;
3319 fclose (fdev);
3321 UNBLOCK_INPUT;
3322 return build_string (name);
3325 static unsigned long
3326 procfs_get_total_memory (void)
3328 FILE *fmem = NULL;
3329 unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
3331 BLOCK_INPUT;
3332 fmem = fopen ("/proc/meminfo", "r");
3334 if (fmem)
3336 unsigned long entry_value;
3337 char entry_name[20]; /* the longest I saw is 13+1 */
3339 while (!feof (fmem) && !ferror (fmem))
3341 if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value)
3342 && strcmp (entry_name, "MemTotal:") == 0)
3344 retval = entry_value;
3345 break;
3348 fclose (fmem);
3350 UNBLOCK_INPUT;
3351 return retval;
3354 Lisp_Object
3355 system_process_attributes (Lisp_Object pid)
3357 char procfn[PATH_MAX], fn[PATH_MAX];
3358 struct stat st;
3359 struct passwd *pw;
3360 struct group *gr;
3361 long clocks_per_sec;
3362 char *procfn_end;
3363 char procbuf[1025], *p, *q;
3364 int fd;
3365 ssize_t nread;
3366 const char *cmd = NULL;
3367 char *cmdline = NULL;
3368 size_t cmdsize = 0, cmdline_size;
3369 unsigned char c;
3370 int proc_id, ppid, uid, gid, pgrp, sess, tty, tpgid, thcount;
3371 unsigned long long utime, stime, cutime, cstime, start;
3372 long priority, nice, rss;
3373 unsigned long minflt, majflt, cminflt, cmajflt, vsize;
3374 time_t sec;
3375 unsigned usec;
3376 EMACS_TIME tnow, tstart, tboot, telapsed,ttotal;
3377 double pcpu, pmem;
3378 Lisp_Object attrs = Qnil;
3379 Lisp_Object cmd_str, decoded_cmd, tem;
3380 struct gcpro gcpro1, gcpro2;
3381 EMACS_INT uid_eint, gid_eint;
3383 CHECK_NUMBER_OR_FLOAT (pid);
3384 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
3385 sprintf (procfn, "/proc/%u", proc_id);
3386 if (stat (procfn, &st) < 0)
3387 return attrs;
3389 GCPRO2 (attrs, decoded_cmd);
3391 /* euid egid */
3392 uid = st.st_uid;
3393 /* Use of EMACS_INT stops GCC whining about limited range of data type. */
3394 uid_eint = uid;
3395 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs);
3396 BLOCK_INPUT;
3397 pw = getpwuid (uid);
3398 UNBLOCK_INPUT;
3399 if (pw)
3400 attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
3402 gid = st.st_gid;
3403 gid_eint = gid;
3404 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs);
3405 BLOCK_INPUT;
3406 gr = getgrgid (gid);
3407 UNBLOCK_INPUT;
3408 if (gr)
3409 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3411 strcpy (fn, procfn);
3412 procfn_end = fn + strlen (fn);
3413 strcpy (procfn_end, "/stat");
3414 fd = emacs_open (fn, O_RDONLY, 0);
3415 if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof(procbuf) - 1)) > 0)
3417 procbuf[nread] = '\0';
3418 p = procbuf;
3420 p = strchr (p, '(');
3421 if (p != NULL)
3423 q = strrchr (p + 1, ')');
3424 /* comm */
3425 if (q != NULL)
3427 cmd = p + 1;
3428 cmdsize = q - cmd;
3431 else
3432 q = NULL;
3433 if (cmd == NULL)
3435 cmd = "???";
3436 cmdsize = 3;
3438 /* Command name is encoded in locale-coding-system; decode it. */
3439 cmd_str = make_unibyte_string (cmd, cmdsize);
3440 decoded_cmd = code_convert_string_norecord (cmd_str,
3441 Vlocale_coding_system, 0);
3442 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3444 if (q)
3446 EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint;
3447 p = q + 2;
3448 /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */
3449 sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld",
3450 &c, &ppid, &pgrp, &sess, &tty, &tpgid,
3451 &minflt, &cminflt, &majflt, &cmajflt,
3452 &utime, &stime, &cutime, &cstime,
3453 &priority, &nice, &thcount, &start, &vsize, &rss);
3455 char state_str[2];
3457 state_str[0] = c;
3458 state_str[1] = '\0';
3459 tem = build_string (state_str);
3460 attrs = Fcons (Fcons (Qstate, tem), attrs);
3462 /* Stops GCC whining about limited range of data type. */
3463 ppid_eint = ppid;
3464 pgrp_eint = pgrp;
3465 sess_eint = sess;
3466 tpgid_eint = tpgid;
3467 thcount_eint = thcount;
3468 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid_eint)), attrs);
3469 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp_eint)), attrs);
3470 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess_eint)), attrs);
3471 attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs);
3472 attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs);
3473 attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs);
3474 attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs);
3475 attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs);
3476 attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs);
3477 clocks_per_sec = sysconf (_SC_CLK_TCK);
3478 if (clocks_per_sec < 0)
3479 clocks_per_sec = 100;
3480 attrs = Fcons (Fcons (Qutime,
3481 ltime_from_jiffies (utime, clocks_per_sec)),
3482 attrs);
3483 attrs = Fcons (Fcons (Qstime,
3484 ltime_from_jiffies (stime, clocks_per_sec)),
3485 attrs);
3486 attrs = Fcons (Fcons (Qtime,
3487 ltime_from_jiffies (stime+utime, clocks_per_sec)),
3488 attrs);
3489 attrs = Fcons (Fcons (Qcutime,
3490 ltime_from_jiffies (cutime, clocks_per_sec)),
3491 attrs);
3492 attrs = Fcons (Fcons (Qcstime,
3493 ltime_from_jiffies (cstime, clocks_per_sec)),
3494 attrs);
3495 attrs = Fcons (Fcons (Qctime,
3496 ltime_from_jiffies (cstime+cutime, clocks_per_sec)),
3497 attrs);
3498 attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs);
3499 attrs = Fcons (Fcons (Qnice, make_number (nice)), attrs);
3500 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs);
3501 EMACS_GET_TIME (tnow);
3502 get_up_time (&sec, &usec);
3503 EMACS_SET_SECS (telapsed, sec);
3504 EMACS_SET_USECS (telapsed, usec);
3505 EMACS_SUB_TIME (tboot, tnow, telapsed);
3506 time_from_jiffies (start, clocks_per_sec, &sec, &usec);
3507 EMACS_SET_SECS (tstart, sec);
3508 EMACS_SET_USECS (tstart, usec);
3509 EMACS_ADD_TIME (tstart, tboot, tstart);
3510 attrs = Fcons (Fcons (Qstart,
3511 list3 (make_number
3512 ((EMACS_SECS (tstart) >> 16) & 0xffff),
3513 make_number
3514 (EMACS_SECS (tstart) & 0xffff),
3515 make_number
3516 (EMACS_USECS (tstart)))),
3517 attrs);
3518 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs);
3519 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs);
3520 EMACS_SUB_TIME (telapsed, tnow, tstart);
3521 attrs = Fcons (Fcons (Qetime,
3522 list3 (make_number
3523 ((EMACS_SECS (telapsed) >> 16) & 0xffff),
3524 make_number
3525 (EMACS_SECS (telapsed) & 0xffff),
3526 make_number
3527 (EMACS_USECS (telapsed)))),
3528 attrs);
3529 time_from_jiffies (utime + stime, clocks_per_sec, &sec, &usec);
3530 pcpu = (sec + usec / 1000000.0) / (EMACS_SECS (telapsed) + EMACS_USECS (telapsed) / 1000000.0);
3531 if (pcpu > 1.0)
3532 pcpu = 1.0;
3533 attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs);
3534 pmem = 4.0 * 100 * rss / procfs_get_total_memory ();
3535 if (pmem > 100)
3536 pmem = 100;
3537 attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
3540 if (fd >= 0)
3541 emacs_close (fd);
3543 /* args */
3544 strcpy (procfn_end, "/cmdline");
3545 fd = emacs_open (fn, O_RDONLY, 0);
3546 if (fd >= 0)
3548 for (cmdline_size = 0; emacs_read (fd, &c, 1) == 1; cmdline_size++)
3550 if (isspace (c) || c == '\\')
3551 cmdline_size++; /* for later quoting, see below */
3553 if (cmdline_size)
3555 cmdline = xmalloc (cmdline_size + 1);
3556 lseek (fd, 0L, SEEK_SET);
3557 cmdline[0] = '\0';
3558 if ((nread = read (fd, cmdline, cmdline_size)) >= 0)
3559 cmdline[nread++] = '\0';
3560 else
3562 /* Assigning zero to `nread' makes us skip the following
3563 two loops, assign zero to cmdline_size, and enter the
3564 following `if' clause that handles unknown command
3565 lines. */
3566 nread = 0;
3568 /* We don't want trailing null characters. */
3569 for (p = cmdline + nread - 1; p > cmdline && !*p; p--)
3570 nread--;
3571 for (p = cmdline; p < cmdline + nread; p++)
3573 /* Escape-quote whitespace and backslashes. */
3574 if (isspace (*p) || *p == '\\')
3576 memmove (p + 1, p, nread - (p - cmdline));
3577 nread++;
3578 *p++ = '\\';
3580 else if (*p == '\0')
3581 *p = ' ';
3583 cmdline_size = nread;
3585 if (!cmdline_size)
3587 if (!cmd)
3588 cmd = "???";
3589 if (!cmdsize)
3590 cmdsize = strlen (cmd);
3591 cmdline_size = cmdsize + 2;
3592 cmdline = xmalloc (cmdline_size + 1);
3593 strcpy (cmdline, "[");
3594 strcat (strncat (cmdline, cmd, cmdsize), "]");
3596 emacs_close (fd);
3597 /* Command line is encoded in locale-coding-system; decode it. */
3598 cmd_str = make_unibyte_string (cmdline, cmdline_size);
3599 decoded_cmd = code_convert_string_norecord (cmd_str,
3600 Vlocale_coding_system, 0);
3601 xfree (cmdline);
3602 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3605 UNGCPRO;
3606 return attrs;
3609 #elif defined (SOLARIS2) && defined (HAVE_PROCFS)
3611 /* The <procfs.h> header does not like to be included if _LP64 is defined and
3612 __FILE_OFFSET_BITS == 64. This is an ugly workaround that. */
3613 #if !defined (_LP64) && defined (_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
3614 #define PROCFS_FILE_OFFSET_BITS_HACK 1
3615 #undef _FILE_OFFSET_BITS
3616 #else
3617 #define PROCFS_FILE_OFFSET_BITS_HACK 0
3618 #endif
3620 #include <procfs.h>
3622 #if PROCFS_FILE_OFFSET_BITS_HACK == 1
3623 #define _FILE_OFFSET_BITS 64
3624 #endif /* PROCFS_FILE_OFFSET_BITS_HACK == 1 */
3626 Lisp_Object
3627 system_process_attributes (Lisp_Object pid)
3629 char procfn[PATH_MAX], fn[PATH_MAX];
3630 struct stat st;
3631 struct passwd *pw;
3632 struct group *gr;
3633 char *procfn_end;
3634 struct psinfo pinfo;
3635 int fd;
3636 ssize_t nread;
3637 int proc_id, uid, gid;
3638 Lisp_Object attrs = Qnil;
3639 Lisp_Object decoded_cmd, tem;
3640 struct gcpro gcpro1, gcpro2;
3641 EMACS_INT uid_eint, gid_eint;
3643 CHECK_NUMBER_OR_FLOAT (pid);
3644 proc_id = FLOATP (pid) ? XFLOAT_DATA (pid) : XINT (pid);
3645 sprintf (procfn, "/proc/%u", proc_id);
3646 if (stat (procfn, &st) < 0)
3647 return attrs;
3649 GCPRO2 (attrs, decoded_cmd);
3651 /* euid egid */
3652 uid = st.st_uid;
3653 /* Use of EMACS_INT stops GCC whining about limited range of data type. */
3654 uid_eint = uid;
3655 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid_eint)), attrs);
3656 BLOCK_INPUT;
3657 pw = getpwuid (uid);
3658 UNBLOCK_INPUT;
3659 if (pw)
3660 attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
3662 gid = st.st_gid;
3663 gid_eint = gid;
3664 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid_eint)), attrs);
3665 BLOCK_INPUT;
3666 gr = getgrgid (gid);
3667 UNBLOCK_INPUT;
3668 if (gr)
3669 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3671 strcpy (fn, procfn);
3672 procfn_end = fn + strlen (fn);
3673 strcpy (procfn_end, "/psinfo");
3674 fd = emacs_open (fn, O_RDONLY, 0);
3675 if (fd >= 0
3676 && (nread = read (fd, (char*)&pinfo, sizeof(struct psinfo)) > 0))
3678 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs);
3679 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs);
3680 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs);
3683 char state_str[2];
3684 state_str[0] = pinfo.pr_lwp.pr_sname;
3685 state_str[1] = '\0';
3686 tem = build_string (state_str);
3687 attrs = Fcons (Fcons (Qstate, tem), attrs);
3690 /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
3691 need to get a string from it. */
3693 /* FIXME: missing: Qtpgid */
3695 /* FIXME: missing:
3696 Qminflt
3697 Qmajflt
3698 Qcminflt
3699 Qcmajflt
3701 Qutime
3702 Qcutime
3703 Qstime
3704 Qcstime
3705 Are they available? */
3707 attrs = Fcons (Fcons (Qtime,
3708 list3 (make_number (pinfo.pr_time.tv_sec >> 16),
3709 make_number (pinfo.pr_time.tv_sec & 0xffff),
3710 make_number (pinfo.pr_time.tv_nsec))),
3711 attrs);
3713 attrs = Fcons (Fcons (Qctime,
3714 list3 (make_number (pinfo.pr_ctime.tv_sec >> 16),
3715 make_number (pinfo.pr_ctime.tv_sec & 0xffff),
3716 make_number (pinfo.pr_ctime.tv_nsec))),
3717 attrs);
3719 attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
3720 attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
3721 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs);
3723 attrs = Fcons (Fcons (Qstart,
3724 list3 (make_number (pinfo.pr_start.tv_sec >> 16),
3725 make_number (pinfo.pr_start.tv_sec & 0xffff),
3726 make_number (pinfo.pr_start.tv_nsec))),
3727 attrs);
3728 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs);
3729 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs);
3731 /* pr_pctcpu and pr_pctmem are encoded as a fixed point 16 bit number in [0 ... 1]. */
3732 attrs = Fcons (Fcons (Qpcpu, (pinfo.pr_pctcpu * 100.0) / (double)0x8000), attrs);
3733 attrs = Fcons (Fcons (Qpmem, (pinfo.pr_pctmem * 100.0) / (double)0x8000), attrs);
3735 decoded_cmd
3736 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_fname,
3737 strlen (pinfo.pr_fname)),
3738 Vlocale_coding_system, 0);
3739 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3740 decoded_cmd
3741 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_psargs,
3742 strlen (pinfo.pr_psargs)),
3743 Vlocale_coding_system, 0);
3744 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3747 if (fd >= 0)
3748 emacs_close (fd);
3750 UNGCPRO;
3751 return attrs;
3754 /* The WINDOWSNT implementation is in w32.c.
3755 The MSDOS implementation is in dosfns.c. */
3756 #elif !defined (WINDOWSNT) && !defined (MSDOS)
3758 Lisp_Object
3759 system_process_attributes (Lisp_Object pid)
3761 return Qnil;
3764 #endif /* !defined (WINDOWSNT) */
3767 /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
3768 (do not change this comment) */