Merge from emacs-24; up to 2012-12-19T19:51:40Z!monnier@iro.umontreal.ca
[bpt/emacs.git] / src / sysdep.c
CommitLineData
86a5659e 1/* Interfaces to system-dependent kernel and library entries.
ab422c4d
PE
2 Copyright (C) 1985-1988, 1993-1995, 1999-2013 Free Software
3 Foundation, Inc.
86a5659e
JB
4
5This file is part of GNU Emacs.
6
9ec0b715 7GNU Emacs is free software: you can redistribute it and/or modify
86a5659e 8it under the terms of the GNU General Public License as published by
9ec0b715
GM
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
86a5659e
JB
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
9ec0b715 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
86a5659e 19
4838e624 20#include <config.h>
f162bcc3
PE
21
22#define SYSTIME_INLINE EXTERN_INLINE
23
cf29dd84 24#include <execinfo.h>
5890e9f7 25#include <stdio.h>
06e111a6
DN
26#ifdef HAVE_PWD_H
27#include <pwd.h>
28#include <grp.h>
29#endif /* HAVE_PWD_H */
06e111a6 30#include <limits.h>
d3eb3bfa 31#include <unistd.h>
53934c98 32
620f13b0 33#include <c-ctype.h>
67342916 34#include <ignore-value.h>
d35af63c 35#include <utimens.h>
67342916 36
86a5659e 37#include "lisp.h"
819b8f00 38#include "sysselect.h"
9ac0d9e0 39#include "blockinput.h"
86a5659e 40
7dca65a4
PE
41#ifdef BSD_SYSTEM
42#include <sys/param.h>
b91b7e4d 43#include <sys/sysctl.h>
7dca65a4
PE
44#endif
45
46#ifdef __FreeBSD__
b91b7e4d 47#include <sys/user.h>
d054f3fb 48#include <sys/resource.h>
b91b7e4d
EW
49#include <math.h>
50#endif
51
fe03522b 52#ifdef WINDOWSNT
e15b6288
JR
53#define read sys_read
54#define write sys_write
62aba0d4
FP
55#ifndef STDERR_FILENO
56#define STDERR_FILENO fileno(GetStdHandle(STD_ERROR_HANDLE))
57#endif
fe03522b 58#include <windows.h>
fe03522b
RS
59#endif /* not WINDOWSNT */
60
86a5659e
JB
61#include <sys/types.h>
62#include <sys/stat.h>
63#include <errno.h>
64
b05af5d3
PE
65/* Get SI_SRPC_DOMAIN, if it is available. */
66#ifdef HAVE_SYS_SYSTEMINFO_H
67#include <sys/systeminfo.h>
68#endif
69
207bdbdb 70#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
207bdbdb
RS
71#include "msdos.h"
72#include <sys/param.h>
15614e61 73#endif
207bdbdb 74
bb4bc8e2 75#include <sys/file.h>
bb4bc8e2 76#include <fcntl.h>
86a5659e 77
e04a4e0d 78#include "systty.h"
94c8642a 79#include "syswait.h"
86a5659e 80
a7ebc409 81#ifdef HAVE_SYS_UTSNAME_H
86a5659e 82#include <sys/utsname.h>
86a5659e 83#include <memory.h>
a7ebc409 84#endif /* HAVE_SYS_UTSNAME_H */
86a5659e 85
e36ec798 86#include "keyboard.h"
0137dbf7 87#include "frame.h"
86a5659e
JB
88#include "window.h"
89#include "termhooks.h"
90#include "termchar.h"
91#include "termopts.h"
92#include "dispextern.h"
93#include "process.h"
0a125897 94#include "cm.h" /* for reset_sys_modes */
86a5659e 95
fe03522b
RS
96#ifdef WINDOWSNT
97#include <direct.h>
98/* In process.h which conflicts with the local copy. */
99#define _P_WAIT 0
43db14bb
JB
100int _cdecl _spawnlp (int, const char *, const char *, ...);
101int _cdecl _getpid (void);
fe03522b
RS
102#endif
103
91bac16a
JB
104#include "syssignal.h"
105#include "systime.h"
86a5659e 106
1fa53021
PE
107static int emacs_get_tty (int, struct emacs_tty *);
108static int emacs_set_tty (int, struct emacs_tty *, int);
109
5a16b9bc
PE
110/* ULLONG_MAX is missing on Red Hat Linux 7.3; see Bug#11781. */
111#ifndef ULLONG_MAX
112#define ULLONG_MAX TYPE_MAXIMUM (unsigned long long int)
113#endif
114
ff2e8052
DN
115/* Declare here, including term.h is problematic on some systems. */
116extern void tputs (const char *, int, int (*)(int));
117
91433552 118static const int baud_convert[] =
86a5659e
JB
119 {
120 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
121 1800, 2400, 4800, 9600, 19200, 38400
122 };
86a5659e 123
f78f1a83 124
3480d92b 125#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
f78f1a83 126
b6682dd9 127/* Return the current working directory. Returns NULL on errors.
f78f1a83
EZ
128 Any other returned value must be freed with free. This is used
129 only when get_current_dir_name is not defined on the system. */
130char*
cf84bb53 131get_current_dir_name (void)
f78f1a83
EZ
132{
133 char *buf;
9239d970 134 char *pwd = getenv ("PWD");
f78f1a83 135 struct stat dotstat, pwdstat;
9239d970 136 /* If PWD is accurate, use it instead of calling getcwd. PWD is
f78f1a83
EZ
137 sometimes a nicer name, and using it may avoid a fatal error if a
138 parent directory is searchable but not readable. */
9239d970 139 if (pwd
f78f1a83
EZ
140 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
141 && stat (pwd, &pwdstat) == 0
142 && stat (".", &dotstat) == 0
143 && dotstat.st_ino == pwdstat.st_ino
144 && dotstat.st_dev == pwdstat.st_dev
145#ifdef MAXPATHLEN
146 && strlen (pwd) < MAXPATHLEN
147#endif
148 )
149 {
38182d90 150 buf = malloc (strlen (pwd) + 1);
f78f1a83
EZ
151 if (!buf)
152 return NULL;
153 strcpy (buf, pwd);
154 }
f78f1a83
EZ
155 else
156 {
157 size_t buf_size = 1024;
38182d90 158 buf = malloc (buf_size);
f78f1a83
EZ
159 if (!buf)
160 return NULL;
161 for (;;)
162 {
163 if (getcwd (buf, buf_size) == buf)
164 break;
165 if (errno != ERANGE)
166 {
167 int tmp_errno = errno;
168 free (buf);
169 errno = tmp_errno;
170 return NULL;
171 }
172 buf_size *= 2;
38182d90 173 buf = realloc (buf, buf_size);
f78f1a83
EZ
174 if (!buf)
175 return NULL;
176 }
177 }
f78f1a83
EZ
178 return buf;
179}
180#endif
181
64e971c3 182\f
9628b887 183/* Discard pending input on all input descriptors. */
91bac16a 184
08633194 185void
971de7fb 186discard_tty_input (void)
86a5659e 187{
fe03522b 188#ifndef WINDOWSNT
91bac16a 189 struct emacs_tty buf;
86a5659e
JB
190
191 if (noninteractive)
192 return;
193
fe03522b 194#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
207bdbdb 195 while (dos_keyread () != -1)
fe03522b 196 ;
207bdbdb 197#else /* not MSDOS */
9628b887 198 {
28d7d09f 199 struct tty_display_info *tty;
9628b887
KL
200 for (tty = tty_list; tty; tty = tty->next)
201 {
0b0d3e0b
KL
202 if (tty->input) /* Is the device suspended? */
203 {
12e610e8
DN
204 emacs_get_tty (fileno (tty->input), &buf);
205 emacs_set_tty (fileno (tty->input), &buf, 0);
0b0d3e0b 206 }
9628b887
KL
207 }
208 }
207bdbdb 209#endif /* not MSDOS */
fe03522b 210#endif /* not WINDOWSNT */
86a5659e
JB
211}
212
16c290d8 213\f
86a5659e
JB
214#ifdef SIGTSTP
215
64e971c3 216/* Arrange for character C to be read as the next input from
16c290d8
KL
217 the terminal.
218 XXX What if we have multiple ttys?
219*/
64e971c3 220
dfcf069d 221void
0c2338d8 222stuff_char (char c)
86a5659e 223{
428a555e 224 if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
23dab951
RS
225 return;
226
86a5659e
JB
227/* Should perhaps error if in batch mode */
228#ifdef TIOCSTI
0b0d3e0b 229 ioctl (fileno (CURTTY()->input), TIOCSTI, &c);
86a5659e 230#else /* no TIOCSTI */
71f06467 231 error ("Cannot stuff terminal input characters in this version of Unix");
86a5659e
JB
232#endif /* no TIOCSTI */
233}
234
235#endif /* SIGTSTP */
64e971c3 236\f
08633194 237void
16c290d8 238init_baud_rate (int fd)
86a5659e 239{
4c620157 240 int emacs_ospeed;
67342916 241
86a5659e 242 if (noninteractive)
5bdd7bdd 243 emacs_ospeed = 0;
86a5659e
JB
244 else
245 {
fe03522b 246#ifdef DOS_NT
5bdd7bdd 247 emacs_ospeed = 15;
fe03522b 248#else /* not DOS_NT */
e04a4e0d 249 struct termios sg;
91bac16a 250
71f06467 251 sg.c_cflag = B9600;
16c290d8 252 tcgetattr (fd, &sg);
5bdd7bdd 253 emacs_ospeed = cfgetospeed (&sg);
fe03522b 254#endif /* not DOS_NT */
86a5659e 255 }
177c0ea7 256
5bdd7bdd
GM
257 baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
258 ? baud_convert[emacs_ospeed] : 9600);
86a5659e
JB
259 if (baud_rate == 0)
260 baud_rate = 1200;
261}
262
16c290d8 263\f
86a5659e 264
77defa9a 265#ifndef MSDOS
86a5659e 266
bb5f74ee
PE
267/* Wait for the subprocess with process id CHILD to terminate or change status.
268 CHILD must be a child process that has not been reaped.
269 If STATUS is non-null, store the waitpid-style exit status into *STATUS
270 and tell wait_reading_process_output that it needs to look around.
271 Use waitpid-style OPTIONS when waiting.
272 If INTERRUPTIBLE, this function is interruptible by a signal.
273
274 Return CHILD if successful, 0 if no status is available;
275 the latter is possible only when options & NOHANG. */
276static pid_t
277get_child_status (pid_t child, int *status, int options, bool interruptible)
86a5659e 278{
bb5f74ee
PE
279 pid_t pid;
280
281 /* Invoke waitpid only with a known process ID; do not invoke
282 waitpid with a nonpositive argument. Otherwise, Emacs might
283 reap an unwanted process by mistake. For example, invoking
284 waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
285 so that another thread running glib won't find them. */
286 eassert (0 < child);
287
288 while ((pid = waitpid (child, status, options)) < 0)
86a5659e 289 {
9cdde1e2
PE
290 /* Check that CHILD is a child process that has not been reaped,
291 and that STATUS and OPTIONS are valid. Otherwise abort,
292 as continuing after this internal error could cause Emacs to
293 become confused and kill innocent-victim processes. */
294 if (errno != EINTR)
295 emacs_abort ();
ac3ac859 296
22bae83f
EZ
297 /* Note: the MS-Windows emulation of waitpid calls QUIT
298 internally. */
1ef14cb4
LMI
299 if (interruptible)
300 QUIT;
86a5659e 301 }
86a5659e 302
bb5f74ee
PE
303 /* If successful and status is requested, tell wait_reading_process_output
304 that it needs to wake up and look around. */
305 if (pid && status && input_available_clear_time)
306 *input_available_clear_time = make_emacs_time (0, 0);
e7a6747f 307
bb5f74ee
PE
308 return pid;
309}
310
311/* Wait for the subprocess with process id CHILD to terminate.
312 CHILD must be a child process that has not been reaped.
313 If STATUS is non-null, store the waitpid-style exit status into *STATUS
314 and tell wait_reading_process_output that it needs to look around.
315 If INTERRUPTIBLE, this function is interruptible by a signal. */
e7a6747f 316void
bb5f74ee 317wait_for_termination (pid_t child, int *status, bool interruptible)
e7a6747f 318{
bb5f74ee 319 get_child_status (child, status, 0, interruptible);
e7a6747f
AS
320}
321
bb5f74ee
PE
322/* Report whether the subprocess with process id CHILD has changed status.
323 Termination counts as a change of status.
324 CHILD must be a child process that has not been reaped.
325 If STATUS is non-null, store the waitpid-style exit status into *STATUS
326 and tell wait_reading_process_output that it needs to look around.
327 Use waitpid-style OPTIONS to check status, but do not wait.
328
329 Return CHILD if successful, 0 if no status is available because
330 the process's state has not changed. */
331pid_t
332child_status_changed (pid_t child, int *status, int options)
e7a6747f 333{
bb5f74ee 334 return get_child_status (child, status, WNOHANG | options, 0);
e7a6747f
AS
335}
336
86a5659e
JB
337/*
338 * flush any pending output
339 * (may flush input as well; it does not matter the way we use it)
340 */
177c0ea7 341
08633194 342void
971de7fb 343flush_pending_output (int channel)
86a5659e 344{
9de940b5 345 /* FIXME: maybe this function should be removed */
86a5659e 346}
64e971c3 347\f
86a5659e
JB
348/* Set up the terminal at the other end of a pseudo-terminal that
349 we will be controlling an inferior through.
350 It should not echo or do line-editing, since that is done
351 in Emacs. No padding needed for insertion into an Emacs buffer. */
352
08633194 353void
971de7fb 354child_setup_tty (int out)
86a5659e 355{
77defa9a 356#ifndef WINDOWSNT
91bac16a
JB
357 struct emacs_tty s;
358
12e610e8 359 emacs_get_tty (out, &s);
91bac16a
JB
360 s.main.c_oflag |= OPOST; /* Enable output postprocessing */
361 s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */
9d4e5eea 362#ifdef NLDLY
07cfc4e7
GM
363 /* http://lists.gnu.org/archive/html/emacs-devel/2008-05/msg00406.html
364 Some versions of GNU Hurd do not have FFDLY? */
365#ifdef FFDLY
91bac16a
JB
366 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
367 /* No output delays */
07cfc4e7
GM
368#else
369 s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY);
370 /* No output delays */
371#endif
9d4e5eea 372#endif
91bac16a
JB
373 s.main.c_lflag &= ~ECHO; /* Disable echo */
374 s.main.c_lflag |= ISIG; /* Enable signals */
9d4e5eea
RS
375#ifdef IUCLC
376 s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */
377#endif
f7097b2a
RS
378#ifdef ISTRIP
379 s.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
380#endif
23e4c8be 381#ifdef OLCUC
9d4e5eea
RS
382 s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */
383#endif
f7097b2a 384 s.main.c_oflag &= ~TAB3; /* Disable tab expansion */
1bf96fb5 385 s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */
441f6399
RS
386 s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
387 s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
91bac16a 388
86a5659e 389#ifdef HPUX
91bac16a 390 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
86a5659e 391#endif /* HPUX */
91bac16a 392
dfe598b5
RS
393#ifdef SIGNALS_VIA_CHARACTERS
394 /* the QUIT and INTR character are used in process_send_signal
395 so set them here to something useful. */
fa51fa32 396 if (s.main.c_cc[VQUIT] == CDISABLE)
dfe598b5 397 s.main.c_cc[VQUIT] = '\\'&037; /* Control-\ */
fa51fa32 398 if (s.main.c_cc[VINTR] == CDISABLE)
dfe598b5
RS
399 s.main.c_cc[VINTR] = 'C'&037; /* Control-C */
400#endif /* not SIGNALS_VIA_CHARACTERS */
401
86a5659e 402#ifdef AIX
86a5659e
JB
403 /* Also, PTY overloads NUL and BREAK.
404 don't ignore break, but don't signal either, so it looks like NUL. */
91bac16a
JB
405 s.main.c_iflag &= ~IGNBRK;
406 s.main.c_iflag &= ~BRKINT;
dfe598b5
RS
407 /* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
408 unconditionally. Then a SIGNALS_VIA_CHARACTERS conditional
409 would force it to 0377. That looks like duplicated code. */
91bac16a 410 s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
86a5659e
JB
411#endif /* AIX */
412
aaa0a19a 413 /* We originally enabled ICANON (and set VEOF to 04), and then had
c80e3b4a 414 process.c send additional EOF chars to flush the output when faced
aaa0a19a 415 with long lines, but this leads to weird effects when the
2b0a91e7
SM
416 subprocess has disabled ICANON and ends up seeing those spurious
417 extra EOFs. So we don't send EOFs any more in
aaa0a19a
SM
418 process.c:send_process. First we tried to disable ICANON by
419 default, so if a subsprocess sets up ICANON, it's his problem (or
420 the Elisp package that talks to it) to deal with lines that are
421 too long. But this disables some features, such as the ability
422 to send EOF signals. So we re-enabled ICANON but there is no
423 more "send eof to flush" going on (which is wrong and unportable
424 in itself). The correct way to handle too much output is to
425 buffer what could not be written and then write it again when
426 select returns ok for writing. This has it own set of
427 problems. Write is now asynchronous, is that a problem? How much
428 do we buffer, and what do we do when that limit is reached? */
9a747ba6
JD
429
430 s.main.c_lflag |= ICANON; /* Enable line editing and eof processing */
431 s.main.c_cc[VEOF] = 'D'&037; /* Control-D */
3d15fe78 432#if 0 /* These settings only apply to non-ICANON mode. */
2b0a91e7
SM
433 s.main.c_cc[VMIN] = 1;
434 s.main.c_cc[VTIME] = 0;
aaa0a19a 435#endif
2b0a91e7 436
12e610e8 437 emacs_set_tty (out, &s, 0);
77defa9a 438#endif /* not WINDOWSNT */
86a5659e 439}
57507bf8 440#endif /* not MSDOS */
86a5659e 441
64e971c3 442\f
2fe28299 443/* Record a signal code and the action for it. */
86a5659e
JB
444struct save_signal
445{
446 int code;
2fe28299 447 struct sigaction action;
86a5659e
JB
448};
449
f57e2426
J
450static void save_signal_handlers (struct save_signal *);
451static void restore_signal_handlers (struct save_signal *);
35a05cca 452
86a5659e
JB
453/* Suspend the Emacs process; give terminal to its superior. */
454
08633194 455void
971de7fb 456sys_suspend (void)
86a5659e 457{
d983a10b
PE
458#ifndef DOS_NT
459 kill (0, SIGTSTP);
460#else
86a5659e
JB
461/* On a system where suspending is not implemented,
462 instead fork a subshell and let it talk directly to the terminal
463 while we wait. */
a0932daa
KH
464 sys_subshell ();
465
d983a10b 466#endif
a0932daa
KH
467}
468
469/* Fork a subshell. */
470
08633194 471void
971de7fb 472sys_subshell (void)
a0932daa 473{
ad00c243 474#ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
a0932daa
KH
475 int st;
476 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
477#endif
5fbab051 478 pid_t pid;
bb5f74ee 479 int status;
86a5659e 480 struct save_signal saved_handlers[5];
efa04277 481 Lisp_Object dir;
5e41f65d 482 unsigned char *volatile str_volatile = 0;
7e9123a2 483 unsigned char *str;
efa04277 484 int len;
86a5659e
JB
485
486 saved_handlers[0].code = SIGINT;
487 saved_handlers[1].code = SIGQUIT;
488 saved_handlers[2].code = SIGTERM;
4a4bbad2 489#ifdef USABLE_SIGIO
86a5659e
JB
490 saved_handlers[3].code = SIGIO;
491 saved_handlers[4].code = 0;
492#else
493 saved_handlers[3].code = 0;
494#endif
495
efa04277
RS
496 /* Mentioning current_buffer->buffer would mean including buffer.h,
497 which somehow wedges the hp compiler. So instead... */
498
499 dir = intern ("default-directory");
0e7e7a58 500 if (NILP (Fboundp (dir)))
efa04277
RS
501 goto xyzzy;
502 dir = Fsymbol_value (dir);
914e81a2 503 if (!STRINGP (dir))
efa04277
RS
504 goto xyzzy;
505
506 dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil);
38182d90 507 str_volatile = str = alloca (SCHARS (dir) + 2);
d5db4077 508 len = SCHARS (dir);
72af86bd 509 memcpy (str, SDATA (dir), len);
efa04277
RS
510 if (str[len - 1] != '/') str[len++] = '/';
511 str[len] = 0;
512 xyzzy:
513
ad00c243 514#ifdef DOS_NT
7964ba9e 515 pid = 0;
718ca3cf 516 save_signal_handlers (saved_handlers);
177c0ea7 517#else
efa04277 518 pid = vfork ();
86a5659e
JB
519 if (pid == -1)
520 error ("Can't spawn subshell");
7964ba9e
RS
521#endif
522
86a5659e
JB
523 if (pid == 0)
524 {
8ea90aa3 525 const char *sh = 0;
86a5659e 526
ad00c243 527#ifdef DOS_NT /* MW, Aug 1993 */
9239d970 528 getcwd (oldwd, sizeof oldwd);
7964ba9e 529 if (sh == 0)
83be8524 530 sh = egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
207bdbdb 531#endif
7964ba9e 532 if (sh == 0)
83be8524 533 sh = egetenv ("SHELL");
86a5659e
JB
534 if (sh == 0)
535 sh = "sh";
207bdbdb 536
86a5659e 537 /* Use our buffer's default directory for the subshell. */
5e41f65d 538 str = str_volatile;
32299e33
PE
539 if (str && chdir ((char *) str) != 0)
540 {
541#ifndef DOS_NT
542 ignore_value (write (1, "Can't chdir\n", 12));
543 _exit (1);
544#endif
545 }
efa04277 546
86a5659e 547 close_process_descs (); /* Close Emacs's pipes/ptys */
1593c2fe 548
fe03522b 549#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
c0917202 550 {
48178f9a
EZ
551 char *epwd = getenv ("PWD");
552 char old_pwd[MAXPATHLEN+1+4];
c0917202
EZ
553
554 /* If PWD is set, pass it with corrected value. */
48178f9a 555 if (epwd)
c0917202 556 {
48178f9a 557 strcpy (old_pwd, epwd);
c0917202
EZ
558 if (str[len - 1] == '/')
559 str[len - 1] = '\0';
560 setenv ("PWD", str, 1);
561 }
562 st = system (sh);
32299e33 563 chdir (oldwd); /* FIXME: Do the right thing on chdir failure. */
48178f9a 564 if (epwd)
c0917202
EZ
565 putenv (old_pwd); /* restore previous value */
566 }
207bdbdb 567#else /* not MSDOS */
fe03522b 568#ifdef WINDOWSNT
fe03522b
RS
569 /* Waits for process completion */
570 pid = _spawnlp (_P_WAIT, sh, sh, NULL);
32299e33 571 chdir (oldwd); /* FIXME: Do the right thing on chdir failure. */
fe03522b
RS
572 if (pid == -1)
573 write (1, "Can't execute subshell", 22);
fe03522b 574#else /* not WINDOWSNT */
e120ea40 575 execlp (sh, sh, (char *) 0);
67342916 576 ignore_value (write (1, "Can't execute subshell", 22));
86a5659e 577 _exit (1);
fe03522b 578#endif /* not WINDOWSNT */
207bdbdb 579#endif /* not MSDOS */
86a5659e
JB
580 }
581
718ca3cf 582 /* Do this now if we did not do it before. */
ed68db4d 583#ifndef MSDOS
86a5659e 584 save_signal_handlers (saved_handlers);
718ca3cf
RS
585#endif
586
ad00c243 587#ifndef DOS_NT
bb5f74ee 588 wait_for_termination (pid, &status, 0);
7964ba9e 589#endif
86a5659e 590 restore_signal_handlers (saved_handlers);
86a5659e
JB
591}
592
35a05cca 593static void
971de7fb 594save_signal_handlers (struct save_signal *saved_handlers)
86a5659e
JB
595{
596 while (saved_handlers->code)
597 {
2fe28299
PE
598 struct sigaction action;
599 emacs_sigaction_init (&action, SIG_IGN);
600 sigaction (saved_handlers->code, &action, &saved_handlers->action);
86a5659e
JB
601 saved_handlers++;
602 }
603}
604
35a05cca 605static void
971de7fb 606restore_signal_handlers (struct save_signal *saved_handlers)
86a5659e
JB
607{
608 while (saved_handlers->code)
609 {
2fe28299 610 sigaction (saved_handlers->code, &saved_handlers->action, 0);
86a5659e
JB
611 saved_handlers++;
612 }
613}
614\f
4a4bbad2 615#ifdef USABLE_SIGIO
1fa53021 616static int old_fcntl_flags[MAXDESC];
4a4bbad2 617#endif
86a5659e 618
08633194 619void
971de7fb 620init_sigio (int fd)
86a5659e 621{
4a4bbad2 622#ifdef USABLE_SIGIO
819b8f00
KL
623 old_fcntl_flags[fd] = fcntl (fd, F_GETFL, 0) & ~FASYNC;
624 fcntl (fd, F_SETFL, old_fcntl_flags[fd] | FASYNC);
23dab951 625 interrupts_deferred = 0;
4a4bbad2 626#endif
86a5659e
JB
627}
628
604efe86 629static void
971de7fb 630reset_sigio (int fd)
86a5659e 631{
4a4bbad2 632#ifdef USABLE_SIGIO
819b8f00 633 fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
4d553a13 634#endif
86a5659e
JB
635}
636
08633194 637void
971de7fb 638request_sigio (void)
86a5659e 639{
4a4bbad2 640#ifdef USABLE_SIGIO
2fe28299
PE
641 sigset_t unblocked;
642
6bbba5a6 643 if (noninteractive)
23dab951
RS
644 return;
645
2fe28299 646 sigemptyset (&unblocked);
4a4bbad2 647# ifdef SIGWINCH
2fe28299 648 sigaddset (&unblocked, SIGWINCH);
4a4bbad2 649# endif
2fe28299
PE
650 sigaddset (&unblocked, SIGIO);
651 pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
86a5659e
JB
652
653 interrupts_deferred = 0;
4a4bbad2 654#endif
86a5659e
JB
655}
656
08633194 657void
0a125897 658unrequest_sigio (void)
cf84bb53 659{
4a4bbad2 660#ifdef USABLE_SIGIO
2fe28299
PE
661 sigset_t blocked;
662
6bbba5a6
KL
663 if (noninteractive)
664 return;
665
2fe28299 666 sigemptyset (&blocked);
4a4bbad2 667# ifdef SIGWINCH
2fe28299 668 sigaddset (&blocked, SIGWINCH);
4a4bbad2 669# endif
2fe28299
PE
670 sigaddset (&blocked, SIGIO);
671 pthread_sigmask (SIG_BLOCK, &blocked, 0);
86a5659e 672 interrupts_deferred = 1;
4a4bbad2 673#endif
86a5659e 674}
177c0ea7 675
08633194 676void
4a4bbad2 677ignore_sigio (void)
86a5659e 678{
4a4bbad2
PE
679#ifdef USABLE_SIGIO
680 signal (SIGIO, SIG_IGN);
681#endif
86a5659e 682}
feb67dfe 683
9ae8f997 684\f
322aea6d
PE
685/* Saving and restoring the process group of Emacs's terminal. */
686
687/* The process group of which Emacs was a member when it initially
688 started.
689
690 If Emacs was in its own process group (i.e. inherited_pgroup ==
691 getpid ()), then we know we're running under a shell with job
692 control (Emacs would never be run as part of a pipeline).
693 Everything is fine.
694
695 If Emacs was not in its own process group, then we know we're
696 running under a shell (or a caller) that doesn't know how to
697 separate itself from Emacs (like sh). Emacs must be in its own
698 process group in order to receive SIGIO correctly. In this
699 situation, we put ourselves in our own pgroup, forcibly set the
700 tty's pgroup to our pgroup, and make sure to restore and reinstate
701 the tty's pgroup just like any other terminal setting. If
702 inherited_group was not the tty's pgroup, then we'll get a
703 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
704 it goes foreground in the future, which is what should happen. */
705
706static pid_t inherited_pgroup;
707
708void
709init_foreground_group (void)
710{
dd0333b6 711 pid_t pgrp = getpgrp ();
322aea6d
PE
712 inherited_pgroup = getpid () == pgrp ? 0 : pgrp;
713}
714
b8956427
PE
715/* Block and unblock SIGTTOU. */
716
717void
718block_tty_out_signal (void)
719{
720#ifdef SIGTTOU
721 sigset_t blocked;
722 sigemptyset (&blocked);
723 sigaddset (&blocked, SIGTTOU);
724 pthread_sigmask (SIG_BLOCK, &blocked, 0);
725#endif
726}
727
728void
729unblock_tty_out_signal (void)
730{
731#ifdef SIGTTOU
732 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
733#endif
734}
735
322aea6d
PE
736/* Safely set a controlling terminal FD's process group to PGID.
737 If we are not in the foreground already, POSIX requires tcsetpgrp
738 to deliver a SIGTTOU signal, which would stop us. This is an
739 annoyance, so temporarily ignore the signal.
740
741 In practice, platforms lacking SIGTTOU also lack tcsetpgrp, so
742 skip all this unless SIGTTOU is defined. */
743static void
744tcsetpgrp_without_stopping (int fd, pid_t pgid)
745{
746#ifdef SIGTTOU
322aea6d 747 block_input ();
b8956427 748 block_tty_out_signal ();
322aea6d 749 tcsetpgrp (fd, pgid);
b8956427 750 unblock_tty_out_signal ();
322aea6d
PE
751 unblock_input ();
752#endif
753}
754
755/* Split off the foreground process group to Emacs alone. When we are
756 in the foreground, but not started in our own process group,
757 redirect the tty device handle FD to point to our own process
758 group. FD must be the file descriptor of the controlling tty. */
759static void
760narrow_foreground_group (int fd)
761{
762 if (inherited_pgroup && setpgid (0, 0) == 0)
763 tcsetpgrp_without_stopping (fd, getpid ());
764}
765
766/* Set the tty to our original foreground group. */
767static void
768widen_foreground_group (int fd)
769{
770 if (inherited_pgroup && setpgid (0, inherited_pgroup) == 0)
771 tcsetpgrp_without_stopping (fd, inherited_pgroup);
772}
773\f
68936329
JB
774/* Getting and setting emacs_tty structures. */
775
776/* Set *TC to the parameters associated with the terminal FD.
777 Return zero if all's well, or -1 if we ran into an error we
778 couldn't deal with. */
779int
971de7fb 780emacs_get_tty (int fd, struct emacs_tty *settings)
68936329
JB
781{
782 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
a7ebc409 783#ifndef DOS_NT
68936329 784 /* We have those nifty POSIX tcmumbleattr functions. */
72af86bd 785 memset (&settings->main, 0, sizeof (settings->main));
68936329
JB
786 if (tcgetattr (fd, &settings->main) < 0)
787 return -1;
68936329
JB
788#endif
789
790 /* We have survived the tempest. */
791 return 0;
792}
793
794
795/* Set the parameters of the tty on FD according to the contents of
394049ec 796 *SETTINGS. If FLUSHP is non-zero, we discard input.
68936329 797 Return 0 if all went well, and -1 if anything failed. */
394049ec 798
68936329 799int
971de7fb 800emacs_set_tty (int fd, struct emacs_tty *settings, int flushp)
68936329
JB
801{
802 /* Set the primary parameters - baud rate, character size, etcetera. */
a7ebc409 803#ifndef DOS_NT
e6cc3307 804 int i;
68936329
JB
805 /* We have those nifty POSIX tcmumbleattr functions.
806 William J. Smith <wjs@wiis.wang.com> writes:
c4ea52a6 807 "POSIX 1003.1 defines tcsetattr to return success if it was
68936329
JB
808 able to perform any of the requested actions, even if some
809 of the requested actions could not be performed.
810 We must read settings back to ensure tty setup properly.
811 AIX requires this to keep tty from hanging occasionally." */
eb8c3be9 812 /* This make sure that we don't loop indefinitely in here. */
e6cc3307 813 for (i = 0 ; i < 10 ; i++)
394049ec 814 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, &settings->main) < 0)
68936329
JB
815 {
816 if (errno == EINTR)
817 continue;
818 else
819 return -1;
820 }
821 else
822 {
823 struct termios new;
824
72af86bd 825 memset (&new, 0, sizeof (new));
68936329
JB
826 /* Get the current settings, and see if they're what we asked for. */
827 tcgetattr (fd, &new);
e6cc3307
RS
828 /* We cannot use memcmp on the whole structure here because under
829 * aix386 the termios structure has some reserved field that may
830 * not be filled in.
831 */
832 if ( new.c_iflag == settings->main.c_iflag
833 && new.c_oflag == settings->main.c_oflag
834 && new.c_cflag == settings->main.c_cflag
835 && new.c_lflag == settings->main.c_lflag
c4ea52a6 836 && memcmp (new.c_cc, settings->main.c_cc, NCCS) == 0)
68936329 837 break;
e6cc3307
RS
838 else
839 continue;
68936329 840 }
68936329 841#endif
177c0ea7 842
68936329
JB
843 /* We have survived the tempest. */
844 return 0;
845}
846
847\f
86a5659e
JB
848
849#ifdef F_SETOWN
1fa53021 850static int old_fcntl_owner[MAXDESC];
86a5659e
JB
851#endif /* F_SETOWN */
852
86a5659e
JB
853/* This may also be defined in stdio,
854 but if so, this does no harm,
855 and using the same name avoids wasting the other one's space. */
856
9d9a7716 857#if defined (USG)
86a5659e
JB
858unsigned char _sobuf[BUFSIZ+8];
859#else
860char _sobuf[BUFSIZ];
861#endif
177c0ea7 862
da8e1115
KL
863/* Initialize the terminal mode on all tty devices that are currently
864 open. */
865
08633194 866void
28d440ab
KL
867init_all_sys_modes (void)
868{
28d7d09f 869 struct tty_display_info *tty;
16c290d8 870 for (tty = tty_list; tty; tty = tty->next)
28d440ab 871 init_sys_modes (tty);
28d440ab
KL
872}
873
da8e1115
KL
874/* Initialize the terminal mode on the given tty device. */
875
28d440ab 876void
971de7fb 877init_sys_modes (struct tty_display_info *tty_out)
86a5659e 878{
91bac16a 879 struct emacs_tty tty;
e112cc37 880 Lisp_Object terminal;
91bac16a 881
4ec5cb58
RS
882 Vtty_erase_char = Qnil;
883
86a5659e
JB
884 if (noninteractive)
885 return;
886
0b0d3e0b
KL
887 if (!tty_out->output)
888 return; /* The tty is suspended. */
cf84bb53 889
322aea6d
PE
890 narrow_foreground_group (fileno (tty_out->input));
891
2246281f 892 if (! tty_out->old_tty)
38182d90 893 tty_out->old_tty = xmalloc (sizeof *tty_out->old_tty);
cf84bb53 894
12e610e8 895 emacs_get_tty (fileno (tty_out->input), tty_out->old_tty);
23dab951 896
2246281f 897 tty = *tty_out->old_tty;
86a5659e 898
a7ebc409 899#if !defined (DOS_NT)
2246281f 900 XSETINT (Vtty_erase_char, tty.main.c_cc[VERASE]);
4ec5cb58 901
2246281f
KL
902 tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */
903 tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
7f371164
RS
904#ifdef INLCR /* I'm just being cautious,
905 since I can't check how widespread INLCR is--rms. */
2246281f 906 tty.main.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
7f371164 907#endif
86a5659e 908#ifdef ISTRIP
2246281f 909 tty.main.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
86a5659e 910#endif
2246281f
KL
911 tty.main.c_lflag &= ~ECHO; /* Disable echo */
912 tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */
e2b40c23 913#ifdef IEXTEN
2246281f 914 tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
e2b40c23 915#endif
2246281f
KL
916 tty.main.c_lflag |= ISIG; /* Enable signals */
917 if (tty_out->flow_control)
918 {
919 tty.main.c_iflag |= IXON; /* Enable start/stop output control */
86a5659e 920#ifdef IXANY
2246281f 921 tty.main.c_iflag &= ~IXANY;
86a5659e 922#endif /* IXANY */
2246281f
KL
923 }
924 else
925 tty.main.c_iflag &= ~IXON; /* Disable start/stop output control */
926 tty.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
927 on output */
928 tty.main.c_oflag &= ~TAB3; /* Disable tab expansion */
86a5659e 929#ifdef CS8
2246281f
KL
930 if (tty_out->meta_key)
931 {
932 tty.main.c_cflag |= CS8; /* allow 8th bit on input */
933 tty.main.c_cflag &= ~PARENB;/* Don't check parity */
934 }
86a5659e 935#endif
e112cc37
ET
936
937 XSETTERMINAL(terminal, tty_out->terminal);
938 if (!NILP (Fcontrolling_tty_p (terminal)))
2246281f
KL
939 {
940 tty.main.c_cc[VINTR] = quit_char; /* C-g (usually) gives SIGINT */
941 /* Set up C-g for both SIGQUIT and SIGINT.
942 We don't know which we will get, but we handle both alike
943 so which one it really gives us does not matter. */
944 tty.main.c_cc[VQUIT] = quit_char;
945 }
946 else
947 {
948 /* We normally don't get interrupt or quit signals from tty
949 devices other than our controlling terminal; therefore,
950 we must handle C-g as normal input. Unfortunately, this
951 means that the interrupt and quit feature must be
952 disabled on secondary ttys, or we would not even see the
953 keypress.
cf84bb53 954
2246281f
KL
955 Note that even though emacsclient could have special code
956 to pass SIGINT to Emacs, we should _not_ enable
957 interrupt/quit keys for emacsclient frames. This means
958 that we can't break out of loops in C code from a
959 secondary tty frame, but we can always decide what
960 display the C-g came from, which is more important from a
961 usability point of view. (Consider the case when two
962 people work together using the same Emacs instance.) */
963 tty.main.c_cc[VINTR] = CDISABLE;
964 tty.main.c_cc[VQUIT] = CDISABLE;
965 }
966 tty.main.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
967 tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
86a5659e 968#ifdef VSWTCH
2246281f 969 tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
91bac16a 970 of C-z */
86a5659e 971#endif /* VSWTCH */
cf84bb53 972
86a5659e 973#ifdef VSUSP
a7ebc409 974 tty.main.c_cc[VSUSP] = CDISABLE; /* Turn off handling of C-z. */
86a5659e
JB
975#endif /* VSUSP */
976#ifdef V_DSUSP
a7ebc409 977 tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off handling of C-y. */
86a5659e 978#endif /* V_DSUSP */
e2b40c23 979#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
2246281f 980 tty.main.c_cc[VDSUSP] = CDISABLE;
e2b40c23 981#endif /* VDSUSP */
92c995de 982#ifdef VLNEXT
2246281f 983 tty.main.c_cc[VLNEXT] = CDISABLE;
92c995de
RS
984#endif /* VLNEXT */
985#ifdef VREPRINT
2246281f 986 tty.main.c_cc[VREPRINT] = CDISABLE;
92c995de
RS
987#endif /* VREPRINT */
988#ifdef VWERASE
2246281f 989 tty.main.c_cc[VWERASE] = CDISABLE;
92c995de
RS
990#endif /* VWERASE */
991#ifdef VDISCARD
2246281f 992 tty.main.c_cc[VDISCARD] = CDISABLE;
92c995de 993#endif /* VDISCARD */
c179a6d1 994
2246281f
KL
995 if (tty_out->flow_control)
996 {
421dd92f 997#ifdef VSTART
2246281f 998 tty.main.c_cc[VSTART] = '\021';
421dd92f
RS
999#endif /* VSTART */
1000#ifdef VSTOP
2246281f 1001 tty.main.c_cc[VSTOP] = '\023';
421dd92f 1002#endif /* VSTOP */
2246281f
KL
1003 }
1004 else
1005 {
c179a6d1 1006#ifdef VSTART
2246281f 1007 tty.main.c_cc[VSTART] = CDISABLE;
c179a6d1
RS
1008#endif /* VSTART */
1009#ifdef VSTOP
2246281f 1010 tty.main.c_cc[VSTOP] = CDISABLE;
c179a6d1 1011#endif /* VSTOP */
2246281f 1012 }
c179a6d1 1013
86a5659e 1014#ifdef AIX
f5272227
KL
1015 tty.main.c_cc[VSTRT] = CDISABLE;
1016 tty.main.c_cc[VSTOP] = CDISABLE;
1017 tty.main.c_cc[VSUSP] = CDISABLE;
1018 tty.main.c_cc[VDSUSP] = CDISABLE;
2246281f
KL
1019 if (tty_out->flow_control)
1020 {
ac567c95 1021#ifdef VSTART
2246281f 1022 tty.main.c_cc[VSTART] = '\021';
ac567c95
RS
1023#endif /* VSTART */
1024#ifdef VSTOP
2246281f 1025 tty.main.c_cc[VSTOP] = '\023';
ac567c95 1026#endif /* VSTOP */
2246281f
KL
1027 }
1028 /* Also, PTY overloads NUL and BREAK.
1029 don't ignore break, but don't signal either, so it looks like NUL.
1030 This really serves a purpose only if running in an XTERM window
1031 or via TELNET or the like, but does no harm elsewhere. */
1032 tty.main.c_iflag &= ~IGNBRK;
1033 tty.main.c_iflag &= ~BRKINT;
86a5659e 1034#endif
fe03522b 1035#endif /* not DOS_NT */
cf84bb53 1036
207bdbdb 1037#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
2246281f
KL
1038 if (!tty_out->term_initted)
1039 internal_terminal_init ();
4e389d32 1040 dos_ttraw (tty_out);
207bdbdb 1041#endif
91bac16a 1042
12e610e8 1043 emacs_set_tty (fileno (tty_out->input), &tty, 0);
86a5659e 1044
2246281f
KL
1045 /* This code added to insure that, if flow-control is not to be used,
1046 we have an unlocked terminal at the start. */
91bac16a 1047
86a5659e 1048#ifdef TCXONC
0b0d3e0b 1049 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
86a5659e 1050#endif
86a5659e 1051#ifdef TIOCSTART
0b0d3e0b 1052 if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
86a5659e 1053#endif
86a5659e 1054
a7ebc409 1055#if !defined (DOS_NT)
51417996 1056#ifdef TCOON
0b0d3e0b 1057 if (!tty_out->flow_control) tcflow (fileno (tty_out->input), TCOON);
d228f207 1058#endif
51417996 1059#endif
d228f207 1060
49cdacda 1061#ifdef F_GETOWN
2246281f 1062 if (interrupt_input)
86a5659e 1063 {
0b0d3e0b
KL
1064 old_fcntl_owner[fileno (tty_out->input)] =
1065 fcntl (fileno (tty_out->input), F_GETOWN, 0);
1066 fcntl (fileno (tty_out->input), F_SETOWN, getpid ());
1067 init_sigio (fileno (tty_out->input));
7e5a23bd 1068#ifdef HAVE_GPM
75a8734b 1069 if (gpm_tty == tty_out)
3e748bcb 1070 {
75a8734b 1071 /* Arrange for mouse events to give us SIGIO signals. */
3e748bcb 1072 fcntl (gpm_fd, F_SETOWN, getpid ());
57669cf1 1073 fcntl (gpm_fd, F_SETFL, fcntl (gpm_fd, F_GETFL, 0) | O_NONBLOCK);
3e748bcb
NR
1074 init_sigio (gpm_fd);
1075 }
7e5a23bd 1076#endif /* HAVE_GPM */
86a5659e
JB
1077 }
1078#endif /* F_GETOWN */
86a5659e 1079
86a5659e
JB
1080#ifdef _IOFBF
1081 /* This symbol is defined on recent USG systems.
1082 Someone says without this call USG won't really buffer the file
1083 even with a call to setbuf. */
0b0d3e0b 1084 setvbuf (tty_out->output, (char *) _sobuf, _IOFBF, sizeof _sobuf);
86a5659e 1085#else
0b0d3e0b 1086 setbuf (tty_out->output, (char *) _sobuf);
86a5659e 1087#endif
4d553a13 1088
69fb5031
JR
1089 if (tty_out->terminal->set_terminal_modes_hook)
1090 tty_out->terminal->set_terminal_modes_hook (tty_out->terminal);
4b311aaf 1091
9628b887
KL
1092 if (!tty_out->term_initted)
1093 {
1094 Lisp_Object tail, frame;
1095 FOR_EACH_FRAME (tail, frame)
1096 {
daf01701 1097 /* XXX This needs to be revised. */
9628b887
KL
1098 if (FRAME_TERMCAP_P (XFRAME (frame))
1099 && FRAME_TTY (XFRAME (frame)) == tty_out)
1100 init_frame_faces (XFRAME (frame));
1101 }
1102 }
045942b2 1103
9628b887 1104 if (tty_out->term_initted && no_redraw_on_reenter)
86a5659e 1105 {
855a0da7
SM
1106 /* We used to call "direct_output_forward_char(0)" here,
1107 but it's not clear why, since it may not do anything anyway. */
86a5659e
JB
1108 }
1109 else
1110 {
9628b887 1111 Lisp_Object tail, frame;
0137dbf7 1112 frame_garbaged = 1;
9628b887
KL
1113 FOR_EACH_FRAME (tail, frame)
1114 {
7ab98847
EZ
1115 if ((FRAME_TERMCAP_P (XFRAME (frame))
1116 || FRAME_MSDOS_P (XFRAME (frame)))
9628b887
KL
1117 && FRAME_TTY (XFRAME (frame)) == tty_out)
1118 FRAME_GARBAGED_P (XFRAME (frame)) = 1;
1119 }
86a5659e 1120 }
91bac16a 1121
9628b887 1122 tty_out->term_initted = 1;
86a5659e
JB
1123}
1124
1125/* Return nonzero if safe to use tabs in output.
1126 At the time this is called, init_sys_modes has not been done yet. */
177c0ea7 1127
dfcf069d 1128int
16c290d8 1129tabs_safe_p (int fd)
86a5659e 1130{
6548cf00 1131 struct emacs_tty etty;
91bac16a 1132
12e610e8
DN
1133 emacs_get_tty (fd, &etty);
1134#ifndef DOS_NT
1135#ifdef TABDLY
1136 return ((etty.main.c_oflag & TABDLY) != TAB3);
1137#else /* not TABDLY */
1138 return 1;
1139#endif /* not TABDLY */
1140#else /* DOS_NT */
1141 return 0;
1142#endif /* DOS_NT */
86a5659e 1143}
73d5358f 1144\f
86a5659e 1145/* Get terminal size from system.
73d5358f
RS
1146 Store number of lines into *HEIGHTP and width into *WIDTHP.
1147 We store 0 if there's no valid information. */
86a5659e 1148
08633194 1149void
16c290d8 1150get_tty_size (int fd, int *widthp, int *heightp)
86a5659e 1151{
e16e55d4 1152#if defined TIOCGWINSZ
91bac16a
JB
1153
1154 /* BSD-style. */
86a5659e 1155 struct winsize size;
91bac16a 1156
16c290d8 1157 if (ioctl (fd, TIOCGWINSZ, &size) == -1)
91bac16a
JB
1158 *widthp = *heightp = 0;
1159 else
1160 {
1161 *widthp = size.ws_col;
1162 *heightp = size.ws_row;
1163 }
1164
e16e55d4 1165#elif defined TIOCGSIZE
91bac16a
JB
1166
1167 /* SunOS - style. */
177c0ea7 1168 struct ttysize size;
91bac16a 1169
16c290d8 1170 if (ioctl (fd, TIOCGSIZE, &size) == -1)
91bac16a
JB
1171 *widthp = *heightp = 0;
1172 else
1173 {
1174 *widthp = size.ts_cols;
1175 *heightp = size.ts_lines;
1176 }
1177
e16e55d4
JB
1178#elif defined WINDOWSNT
1179
1180 CONSOLE_SCREEN_BUFFER_INFO info;
1181 if (GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info))
1182 {
1183 *widthp = info.srWindow.Right - info.srWindow.Left + 1;
1184 *heightp = info.srWindow.Bottom - info.srWindow.Top + 1;
1185 }
1186 else
1187 *widthp = *heightp = 0;
1188
1189#elif defined MSDOS
1190
207bdbdb
RS
1191 *widthp = ScreenCols ();
1192 *heightp = ScreenRows ();
e16e55d4 1193
86a5659e 1194#else /* system doesn't know size */
e16e55d4 1195
86a5659e
JB
1196 *widthp = 0;
1197 *heightp = 0;
e16e55d4 1198
207bdbdb 1199#endif
86a5659e 1200}
91bac16a 1201
73d5358f
RS
1202/* Set the logical window size associated with descriptor FD
1203 to HEIGHT and WIDTH. This is used mainly with ptys. */
1204
1205int
971de7fb 1206set_window_size (int fd, int height, int width)
73d5358f
RS
1207{
1208#ifdef TIOCSWINSZ
1209
1210 /* BSD-style. */
1211 struct winsize size;
1212 size.ws_row = height;
1213 size.ws_col = width;
1214
1215 if (ioctl (fd, TIOCSWINSZ, &size) == -1)
1216 return 0; /* error */
1217 else
1218 return 1;
1219
1220#else
1221#ifdef TIOCSSIZE
1222
1223 /* SunOS - style. */
177c0ea7 1224 struct ttysize size;
73d5358f
RS
1225 size.ts_lines = height;
1226 size.ts_cols = width;
1227
1228 if (ioctl (fd, TIOCGSIZE, &size) == -1)
1229 return 0;
1230 else
1231 return 1;
1232#else
1233 return -1;
1234#endif /* not SunOS-style */
1235#endif /* not BSD-style */
1236}
1237
86a5659e 1238\f
da8e1115
KL
1239
1240/* Prepare all terminal devices for exiting Emacs. */
1241
28d440ab
KL
1242void
1243reset_all_sys_modes (void)
1244{
28d7d09f 1245 struct tty_display_info *tty;
16c290d8 1246 for (tty = tty_list; tty; tty = tty->next)
28d440ab 1247 reset_sys_modes (tty);
28d440ab
KL
1248}
1249
0a125897 1250/* Prepare the terminal for closing it; move the cursor to the
0137dbf7 1251 bottom of the frame, turn off interrupt-driven I/O, etc. */
da8e1115 1252
08633194 1253void
971de7fb 1254reset_sys_modes (struct tty_display_info *tty_out)
86a5659e
JB
1255{
1256 if (noninteractive)
1257 {
1258 fflush (stdout);
1259 return;
1260 }
9628b887 1261 if (!tty_out->term_initted)
86a5659e 1262 return;
da8e1115 1263
0b0d3e0b
KL
1264 if (!tty_out->output)
1265 return; /* The tty is suspended. */
cf84bb53 1266
da8e1115
KL
1267 /* Go to and clear the last line of the terminal. */
1268
0a125897 1269 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
cf84bb53 1270
da8e1115
KL
1271 /* Code adapted from tty_clear_end_of_line. */
1272 if (tty_out->TS_clr_line)
1273 {
1274 emacs_tputs (tty_out, tty_out->TS_clr_line, 1, cmputc);
1275 }
1276 else
1277 { /* have to do it the hard way */
1278 int i;
ed8dad6b 1279 tty_turn_off_insert (tty_out);
cf84bb53 1280
da8e1115 1281 for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
0b0d3e0b
KL
1282 {
1283 fputc (' ', tty_out->output);
1284 }
da8e1115 1285 }
cf84bb53 1286
0a125897 1287 cmgoto (tty_out, FrameRows (tty_out) - 1, 0);
819b8f00 1288 fflush (tty_out->output);
cf84bb53 1289
69fb5031
JR
1290 if (tty_out->terminal->reset_terminal_modes_hook)
1291 tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal);
2f98e6e3 1292
2a633456 1293#ifdef BSD_SYSTEM
86a5659e 1294 /* Avoid possible loss of output when changing terminal modes. */
0b0d3e0b 1295 fsync (fileno (tty_out->output));
86a5659e 1296#endif
91bac16a 1297
49cdacda
PE
1298#ifndef DOS_NT
1299#ifdef F_SETOWN
86a5659e
JB
1300 if (interrupt_input)
1301 {
0b0d3e0b
KL
1302 reset_sigio (fileno (tty_out->input));
1303 fcntl (fileno (tty_out->input), F_SETOWN,
1304 old_fcntl_owner[fileno (tty_out->input)]);
86a5659e
JB
1305 }
1306#endif /* F_SETOWN */
0b0d3e0b 1307 fcntl (fileno (tty_out->input), F_SETFL,
49cdacda 1308 fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NONBLOCK);
a6b00318 1309#endif
91bac16a 1310
fca177d4 1311 if (tty_out->old_tty)
12e610e8 1312 while (emacs_set_tty (fileno (tty_out->input),
fca177d4 1313 tty_out->old_tty, 0) < 0 && errno == EINTR)
7e32a4fb 1314 ;
86a5659e 1315
207bdbdb
RS
1316#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1317 dos_ttcooked ();
1318#endif
1319
322aea6d 1320 widen_foreground_group (fileno (tty_out->input));
86a5659e
JB
1321}
1322\f
1323#ifdef HAVE_PTYS
1324
1325/* Set up the proper status flags for use of a pty. */
1326
08633194 1327void
971de7fb 1328setup_pty (int fd)
86a5659e
JB
1329{
1330 /* I'm told that TOICREMOTE does not mean control chars
1331 "can't be sent" but rather that they don't have
1332 input-editing or signaling effects.
1333 That should be good, because we have other ways
1334 to do those things in Emacs.
1335 However, telnet mode seems not to work on 4.2.
1336 So TIOCREMOTE is turned off now. */
1337
1338 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1339 will hang. In particular, the "timeout" feature (which
1340 causes a read to return if there is no data available)
1341 does this. Also it is known that telnet mode will hang
1342 in such a way that Emacs must be stopped (perhaps this
1343 is the same problem).
177c0ea7 1344
86a5659e
JB
1345 If TIOCREMOTE is turned off, then there is a bug in
1346 hp-ux which sometimes loses data. Apparently the
1347 code which blocks the master process when the internal
1348 buffer fills up does not work. Other than this,
1349 though, everything else seems to work fine.
177c0ea7 1350
86a5659e
JB
1351 Since the latter lossage is more benign, we may as well
1352 lose that way. -- cph */
1353#ifdef FIONBIO
5e617bc2 1354#if defined (UNIX98_PTYS)
86a5659e
JB
1355 {
1356 int on = 1;
1357 ioctl (fd, FIONBIO, &on);
1358 }
1359#endif
1360#endif
86a5659e
JB
1361}
1362#endif /* HAVE_PTYS */
1363\f
f8a80313
RS
1364#ifdef HAVE_SOCKETS
1365#include <sys/socket.h>
1366#include <netdb.h>
1367#endif /* HAVE_SOCKETS */
f8a80313 1368
8581cd64
KH
1369#ifdef TRY_AGAIN
1370#ifndef HAVE_H_ERRNO
1371extern int h_errno;
1372#endif
1373#endif /* TRY_AGAIN */
1374
c0c86835 1375void
971de7fb 1376init_system_name (void)
86a5659e 1377{
210b2b4f 1378#ifndef HAVE_GETHOSTNAME
c0c86835
KH
1379 struct utsname uts;
1380 uname (&uts);
1381 Vsystem_name = build_string (uts.nodename);
67004ffb 1382#else /* HAVE_GETHOSTNAME */
cc6e7269 1383 unsigned int hostname_size = 256;
38182d90 1384 char *hostname = alloca (hostname_size);
c0c86835
KH
1385
1386 /* Try to get the host name; if the buffer is too short, try
1387 again. Apparently, the only indication gethostname gives of
1388 whether the buffer was large enough is the presence or absence
1389 of a '\0' in the string. Eech. */
1390 for (;;)
1391 {
1392 gethostname (hostname, hostname_size - 1);
1393 hostname[hostname_size - 1] = '\0';
1394
1395 /* Was the buffer large enough for the '\0'? */
1396 if (strlen (hostname) < hostname_size - 1)
1397 break;
1398
1399 hostname_size <<= 1;
38182d90 1400 hostname = alloca (hostname_size);
c0c86835 1401 }
67004ffb 1402#ifdef HAVE_SOCKETS
c0c86835
KH
1403 /* Turn the hostname into the official, fully-qualified hostname.
1404 Don't do this if we're going to dump; this can confuse system
1405 libraries on some machines and make the dumped emacs core dump. */
67004ffb 1406#ifndef CANNOT_DUMP
c0c86835 1407 if (initialized)
67004ffb 1408#endif /* not CANNOT_DUMP */
8966b757 1409 if (! strchr (hostname, '.'))
960d894c 1410 {
960d894c 1411 int count;
3d66b985
JD
1412#ifdef HAVE_GETADDRINFO
1413 struct addrinfo *res;
1414 struct addrinfo hints;
1415 int ret;
1416
cf84bb53 1417 memset (&hints, 0, sizeof (hints));
3d66b985
JD
1418 hints.ai_socktype = SOCK_STREAM;
1419 hints.ai_flags = AI_CANONNAME;
1420
960d894c
KH
1421 for (count = 0;; count++)
1422 {
3d66b985
JD
1423 if ((ret = getaddrinfo (hostname, NULL, &hints, &res)) == 0
1424 || ret != EAI_AGAIN)
1425 break;
1426
1427 if (count >= 5)
1428 break;
1429 Fsleep_for (make_number (1), Qnil);
1430 }
1431
1432 if (ret == 0)
1433 {
1434 struct addrinfo *it = res;
1435 while (it)
1436 {
1437 char *fqdn = it->ai_canonname;
8966b757 1438 if (fqdn && strchr (fqdn, '.')
3d66b985
JD
1439 && strcmp (fqdn, "localhost.localdomain") != 0)
1440 break;
1441 it = it->ai_next;
1442 }
1443 if (it)
1444 {
1445 hostname = alloca (strlen (it->ai_canonname) + 1);
1446 strcpy (hostname, it->ai_canonname);
1447 }
1448 freeaddrinfo (res);
1449 }
1450#else /* !HAVE_GETADDRINFO */
1451 struct hostent *hp;
1452 for (count = 0;; count++)
1453 {
1454
e24f1d55 1455#ifdef TRY_AGAIN
960d894c 1456 h_errno = 0;
e24f1d55 1457#endif
960d894c 1458 hp = gethostbyname (hostname);
efa04277 1459#ifdef TRY_AGAIN
960d894c
KH
1460 if (! (hp == 0 && h_errno == TRY_AGAIN))
1461#endif
3d66b985 1462
960d894c 1463 break;
3d66b985 1464
960d894c
KH
1465 if (count >= 5)
1466 break;
1467 Fsleep_for (make_number (1), Qnil);
1468 }
3d66b985 1469
960d894c
KH
1470 if (hp)
1471 {
1472 char *fqdn = (char *) hp->h_name;
960d894c 1473
8966b757 1474 if (!strchr (fqdn, '.'))
960d894c
KH
1475 {
1476 /* We still don't have a fully qualified domain name.
1477 Try to find one in the list of alternate names */
1478 char **alias = hp->h_aliases;
923721f4 1479 while (*alias
8966b757 1480 && (!strchr (*alias, '.')
923721f4 1481 || !strcmp (*alias, "localhost.localdomain")))
960d894c
KH
1482 alias++;
1483 if (*alias)
1484 fqdn = *alias;
1485 }
1486 hostname = fqdn;
960d894c 1487 }
3d66b985 1488#endif /* !HAVE_GETADDRINFO */
960d894c 1489 }
67004ffb 1490#endif /* HAVE_SOCKETS */
c0c86835 1491 Vsystem_name = build_string (hostname);
67004ffb 1492#endif /* HAVE_GETHOSTNAME */
c0c86835
KH
1493 {
1494 unsigned char *p;
d5db4077 1495 for (p = SDATA (Vsystem_name); *p; p++)
c0c86835
KH
1496 if (*p == ' ' || *p == '\t')
1497 *p = '-';
1498 }
67004ffb 1499}
86a5659e 1500\f
1fa53021 1501sigset_t empty_mask;
86a5659e 1502
4d7e6e51
PE
1503static struct sigaction process_fatal_action;
1504
1505static int
1506emacs_sigaction_flags (void)
86a5659e 1507{
4d7e6e51 1508#ifdef SA_RESTART
0caaedb1
PE
1509 /* SA_RESTART causes interruptible functions with timeouts (e.g.,
1510 'select') to reset their timeout on some platforms (e.g.,
1511 HP-UX 11), which is not what we want. Also, when Emacs is
1512 interactive, we don't want SA_RESTART because we need to poll
275464e7 1513 for pending input so we need long-running syscalls to be interrupted
4d7e6e51
PE
1514 after a signal that sets pending_signals.
1515
1516 Non-interactive keyboard input goes through stdio, where we
1517 always want restartable system calls. */
ef874e3d 1518 if (noninteractive)
4d7e6e51 1519 return SA_RESTART;
e065a56e 1520#endif
4d7e6e51
PE
1521 return 0;
1522}
1523
1524/* Store into *ACTION a signal action suitable for Emacs, with handler
1525 HANDLER. */
1526void
1527emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
1528{
1529 sigemptyset (&action->sa_mask);
1530
1531 /* When handling a signal, block nonfatal system signals that are caught
1532 by Emacs. This makes race conditions less likely. */
1533 sigaddset (&action->sa_mask, SIGALRM);
4d7e6e51 1534 sigaddset (&action->sa_mask, SIGCHLD);
4d7e6e51
PE
1535#ifdef SIGDANGER
1536 sigaddset (&action->sa_mask, SIGDANGER);
1537#endif
d89460ed
PE
1538#ifdef PROFILER_CPU_SUPPORT
1539 sigaddset (&action->sa_mask, SIGPROF);
1540#endif
4d7e6e51
PE
1541#ifdef SIGWINCH
1542 sigaddset (&action->sa_mask, SIGWINCH);
1543#endif
1544 if (! noninteractive)
1545 {
1546 sigaddset (&action->sa_mask, SIGINT);
1547 sigaddset (&action->sa_mask, SIGQUIT);
1548#ifdef USABLE_SIGIO
1549 sigaddset (&action->sa_mask, SIGIO);
1550#endif
1551 }
1552
1553 if (! IEEE_FLOATING_POINT)
1554 sigaddset (&action->sa_mask, SIGFPE);
1555
1556 action->sa_handler = handler;
1557 action->sa_flags = emacs_sigaction_flags ();
86a5659e
JB
1558}
1559
20ef56db 1560#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
0caaedb1 1561static pthread_t main_thread;
20ef56db
PE
1562#endif
1563
4d7e6e51
PE
1564/* SIG has arrived at the current process. Deliver it to the main
1565 thread, which should handle it with HANDLER.
1566
1567 If we are on the main thread, handle the signal SIG with HANDLER.
20ef56db
PE
1568 Otherwise, redirect the signal to the main thread, blocking it from
1569 this thread. POSIX says any thread can receive a signal that is
1570 associated with a process, process group, or asynchronous event.
1571 On GNU/Linux that is not true, but for other systems (FreeBSD at
1572 least) it is. */
1573void
4d7e6e51 1574deliver_process_signal (int sig, signal_handler_t handler)
20ef56db
PE
1575{
1576 /* Preserve errno, to avoid race conditions with signal handlers that
1577 might change errno. Races can occur even in single-threaded hosts. */
1578 int old_errno = errno;
1579
1580 bool on_main_thread = true;
1581#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1582 if (! pthread_equal (pthread_self (), main_thread))
1583 {
1584 sigset_t blocked;
1585 sigemptyset (&blocked);
1586 sigaddset (&blocked, sig);
1587 pthread_sigmask (SIG_BLOCK, &blocked, 0);
1588 pthread_kill (main_thread, sig);
1589 on_main_thread = false;
1590 }
1591#endif
1592 if (on_main_thread)
1593 handler (sig);
1594
1595 errno = old_errno;
1596}
4d7e6e51
PE
1597
1598/* Static location to save a fatal backtrace in a thread.
1599 FIXME: If two subsidiary threads fail simultaneously, the resulting
1600 backtrace may be garbage. */
1601enum { BACKTRACE_LIMIT_MAX = 500 };
1602static void *thread_backtrace_buffer[BACKTRACE_LIMIT_MAX + 1];
1603static int thread_backtrace_npointers;
1604
1605/* SIG has arrived at the current thread.
1606 If we are on the main thread, handle the signal SIG with HANDLER.
1607 Otherwise, this is a fatal error in the handling thread. */
1608static void
1609deliver_thread_signal (int sig, signal_handler_t handler)
1610{
1611 int old_errno = errno;
1612
1613#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1614 if (! pthread_equal (pthread_self (), main_thread))
1615 {
1616 thread_backtrace_npointers
1617 = backtrace (thread_backtrace_buffer, BACKTRACE_LIMIT_MAX);
1618 sigaction (sig, &process_fatal_action, 0);
1619 pthread_kill (main_thread, sig);
1620
1621 /* Avoid further damage while the main thread is exiting. */
1622 while (1)
1623 sigsuspend (&empty_mask);
1624 }
1625#endif
1626
1627 handler (sig);
1628 errno = old_errno;
1629}
86a5659e 1630\f
aa1ba90e
PE
1631#if !HAVE_DECL_SYS_SIGLIST
1632# undef sys_siglist
c622b48f
PE
1633# ifdef _sys_siglist
1634# define sys_siglist _sys_siglist
1635# else
1636# define sys_siglist my_sys_siglist
aa1ba90e 1637static char const *sys_siglist[NSIG];
c622b48f
PE
1638# endif
1639#endif
1640
1641#ifdef _sys_nsig
1642# define sys_siglist_entries _sys_nsig
1643#else
1644# define sys_siglist_entries NSIG
ca9c0567
PE
1645#endif
1646
4d7e6e51
PE
1647/* Handle bus errors, invalid instruction, etc. */
1648static void
1649handle_fatal_signal (int sig)
1650{
9d4dcdc9 1651 terminate_due_to_signal (sig, 40);
4d7e6e51
PE
1652}
1653
1654static void
1655deliver_fatal_signal (int sig)
1656{
1657 deliver_process_signal (sig, handle_fatal_signal);
1658}
1659
1660static void
1661deliver_fatal_thread_signal (int sig)
1662{
1663 deliver_thread_signal (sig, handle_fatal_signal);
1664}
1665
1666static _Noreturn void
1667handle_arith_signal (int sig)
1668{
1669 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
1670 xsignal0 (Qarith_error);
1671}
1672
1673static void
1674deliver_arith_signal (int sig)
1675{
1676 deliver_thread_signal (sig, handle_arith_signal);
1677}
1678
b6f960a0
PE
1679#ifdef SIGDANGER
1680
1681/* Handler for SIGDANGER. */
1682static void
1683handle_danger_signal (int sig)
1684{
1685 malloc_warning ("Operating system warns that virtual memory is running low.\n");
1686
1687 /* It might be unsafe to call do_auto_save now. */
1688 force_auto_save_soon ();
1689}
1690
1691static void
1692deliver_danger_signal (int sig)
1693{
1694 deliver_process_signal (sig, handle_danger_signal);
1695}
1696#endif
1697
4d7e6e51
PE
1698/* Treat SIG as a terminating signal, unless it is already ignored and
1699 we are in --batch mode. Among other things, this makes nohup work. */
1700static void
1701maybe_fatal_sig (int sig)
1702{
1703 bool catch_sig = !noninteractive;
1704 if (!catch_sig)
1705 {
1706 struct sigaction old_action;
1707 sigaction (sig, 0, &old_action);
1708 catch_sig = old_action.sa_handler != SIG_IGN;
1709 }
1710 if (catch_sig)
1711 sigaction (sig, &process_fatal_action, 0);
1712}
1713
ca9c0567 1714void
4d7e6e51 1715init_signals (bool dumping)
ca9c0567 1716{
4d7e6e51
PE
1717 struct sigaction thread_fatal_action;
1718 struct sigaction action;
1719
ca9c0567 1720 sigemptyset (&empty_mask);
ca9c0567 1721
20ef56db
PE
1722#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1723 main_thread = pthread_self ();
1724#endif
1725
c622b48f 1726#if !HAVE_DECL_SYS_SIGLIST && !defined _sys_siglist
ca9c0567
PE
1727 if (! initialized)
1728 {
ca9c0567 1729 sys_siglist[SIGABRT] = "Aborted";
ca9c0567
PE
1730# ifdef SIGAIO
1731 sys_siglist[SIGAIO] = "LAN I/O interrupt";
1732# endif
ca9c0567 1733 sys_siglist[SIGALRM] = "Alarm clock";
ca9c0567
PE
1734# ifdef SIGBUS
1735 sys_siglist[SIGBUS] = "Bus error";
1736# endif
ca9c0567 1737 sys_siglist[SIGCHLD] = "Child status changed";
ca9c0567
PE
1738# ifdef SIGCONT
1739 sys_siglist[SIGCONT] = "Continued";
1740# endif
1741# ifdef SIGDANGER
1742 sys_siglist[SIGDANGER] = "Swap space dangerously low";
1743# endif
1744# ifdef SIGDGNOTIFY
1745 sys_siglist[SIGDGNOTIFY] = "Notification message in queue";
1746# endif
1747# ifdef SIGEMT
1748 sys_siglist[SIGEMT] = "Emulation trap";
1749# endif
ca9c0567 1750 sys_siglist[SIGFPE] = "Arithmetic exception";
ca9c0567
PE
1751# ifdef SIGFREEZE
1752 sys_siglist[SIGFREEZE] = "SIGFREEZE";
1753# endif
1754# ifdef SIGGRANT
1755 sys_siglist[SIGGRANT] = "Monitor mode granted";
1756# endif
ca9c0567 1757 sys_siglist[SIGHUP] = "Hangup";
ca9c0567 1758 sys_siglist[SIGILL] = "Illegal instruction";
ca9c0567 1759 sys_siglist[SIGINT] = "Interrupt";
ca9c0567
PE
1760# ifdef SIGIO
1761 sys_siglist[SIGIO] = "I/O possible";
1762# endif
1763# ifdef SIGIOINT
1764 sys_siglist[SIGIOINT] = "I/O intervention required";
1765# endif
1766# ifdef SIGIOT
1767 sys_siglist[SIGIOT] = "IOT trap";
1768# endif
ca9c0567 1769 sys_siglist[SIGKILL] = "Killed";
ca9c0567
PE
1770# ifdef SIGLOST
1771 sys_siglist[SIGLOST] = "Resource lost";
1772# endif
1773# ifdef SIGLWP
1774 sys_siglist[SIGLWP] = "SIGLWP";
1775# endif
1776# ifdef SIGMSG
1777 sys_siglist[SIGMSG] = "Monitor mode data available";
1778# endif
1779# ifdef SIGPHONE
1780 sys_siglist[SIGWIND] = "SIGPHONE";
1781# endif
ca9c0567 1782 sys_siglist[SIGPIPE] = "Broken pipe";
ca9c0567
PE
1783# ifdef SIGPOLL
1784 sys_siglist[SIGPOLL] = "Pollable event occurred";
1785# endif
1786# ifdef SIGPROF
1787 sys_siglist[SIGPROF] = "Profiling timer expired";
1788# endif
1789# ifdef SIGPTY
1790 sys_siglist[SIGPTY] = "PTY I/O interrupt";
1791# endif
1792# ifdef SIGPWR
1793 sys_siglist[SIGPWR] = "Power-fail restart";
1794# endif
ca9c0567 1795 sys_siglist[SIGQUIT] = "Quit";
ca9c0567 1796# ifdef SIGRETRACT
40ba43b4 1797 sys_siglist[SIGRETRACT] = "Need to relinquish monitor mode";
ca9c0567
PE
1798# endif
1799# ifdef SIGSAK
1800 sys_siglist[SIGSAK] = "Secure attention";
1801# endif
ca9c0567 1802 sys_siglist[SIGSEGV] = "Segmentation violation";
ca9c0567
PE
1803# ifdef SIGSOUND
1804 sys_siglist[SIGSOUND] = "Sound completed";
1805# endif
1806# ifdef SIGSTOP
1807 sys_siglist[SIGSTOP] = "Stopped (signal)";
1808# endif
1809# ifdef SIGSTP
1810 sys_siglist[SIGSTP] = "Stopped (user)";
1811# endif
1812# ifdef SIGSYS
1813 sys_siglist[SIGSYS] = "Bad argument to system call";
1814# endif
ca9c0567 1815 sys_siglist[SIGTERM] = "Terminated";
ca9c0567
PE
1816# ifdef SIGTHAW
1817 sys_siglist[SIGTHAW] = "SIGTHAW";
1818# endif
1819# ifdef SIGTRAP
1820 sys_siglist[SIGTRAP] = "Trace/breakpoint trap";
1821# endif
1822# ifdef SIGTSTP
1823 sys_siglist[SIGTSTP] = "Stopped (user)";
1824# endif
1825# ifdef SIGTTIN
1826 sys_siglist[SIGTTIN] = "Stopped (tty input)";
1827# endif
1828# ifdef SIGTTOU
1829 sys_siglist[SIGTTOU] = "Stopped (tty output)";
1830# endif
1831# ifdef SIGURG
1832 sys_siglist[SIGURG] = "Urgent I/O condition";
1833# endif
1834# ifdef SIGUSR1
1835 sys_siglist[SIGUSR1] = "User defined signal 1";
1836# endif
1837# ifdef SIGUSR2
1838 sys_siglist[SIGUSR2] = "User defined signal 2";
1839# endif
1840# ifdef SIGVTALRM
1841 sys_siglist[SIGVTALRM] = "Virtual timer expired";
1842# endif
1843# ifdef SIGWAITING
1844 sys_siglist[SIGWAITING] = "Process's LWPs are blocked";
1845# endif
1846# ifdef SIGWINCH
1847 sys_siglist[SIGWINCH] = "Window size changed";
1848# endif
1849# ifdef SIGWIND
1850 sys_siglist[SIGWIND] = "SIGWIND";
1851# endif
1852# ifdef SIGXCPU
1853 sys_siglist[SIGXCPU] = "CPU time limit exceeded";
1854# endif
1855# ifdef SIGXFSZ
1856 sys_siglist[SIGXFSZ] = "File size limit exceeded";
1857# endif
1858 }
c622b48f 1859#endif /* !HAVE_DECL_SYS_SIGLIST && !_sys_siglist */
4d7e6e51
PE
1860
1861 /* Don't alter signal handlers if dumping. On some machines,
1862 changing signal handlers sets static data that would make signals
1863 fail to work right when the dumped Emacs is run. */
1864 if (dumping)
1865 return;
1866
1867 sigfillset (&process_fatal_action.sa_mask);
1868 process_fatal_action.sa_handler = deliver_fatal_signal;
62a1d661 1869 process_fatal_action.sa_flags = emacs_sigaction_flags ();
4d7e6e51
PE
1870
1871 sigfillset (&thread_fatal_action.sa_mask);
1872 thread_fatal_action.sa_handler = deliver_fatal_thread_signal;
1873 thread_fatal_action.sa_flags = process_fatal_action.sa_flags;
1874
1875 /* SIGINT may need special treatment on MS-Windows. See
1876 http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html
1877 Please update the doc of kill-emacs, kill-emacs-hook, and
1878 NEWS if you change this. */
1879
1880 maybe_fatal_sig (SIGHUP);
1881 maybe_fatal_sig (SIGINT);
1882 maybe_fatal_sig (SIGTERM);
1883
1884 /* Emacs checks for write errors, so it can safely ignore SIGPIPE.
1885 However, in batch mode leave SIGPIPE alone, as that causes Emacs
1886 to behave more like typical batch applications do. */
1887 if (! noninteractive)
1888 signal (SIGPIPE, SIG_IGN);
1889
1890 sigaction (SIGQUIT, &process_fatal_action, 0);
1891 sigaction (SIGILL, &thread_fatal_action, 0);
1892 sigaction (SIGTRAP, &thread_fatal_action, 0);
1893
1894 /* Typically SIGFPE is thread-specific and is fatal, like SIGILL.
1895 But on a non-IEEE host SIGFPE can come from a trap in the Lisp
1896 interpreter's floating point operations, so treat SIGFPE as an
1897 arith-error if it arises in the main thread. */
1898 if (IEEE_FLOATING_POINT)
1899 sigaction (SIGFPE, &thread_fatal_action, 0);
1900 else
1901 {
1902 emacs_sigaction_init (&action, deliver_arith_signal);
1903 sigaction (SIGFPE, &action, 0);
1904 }
1905
1906#ifdef SIGUSR1
1907 add_user_signal (SIGUSR1, "sigusr1");
1908#endif
1909#ifdef SIGUSR2
1910 add_user_signal (SIGUSR2, "sigusr2");
1911#endif
1912 sigaction (SIGABRT, &thread_fatal_action, 0);
1913#ifdef SIGPRE
1914 sigaction (SIGPRE, &thread_fatal_action, 0);
1915#endif
1916#ifdef SIGORE
1917 sigaction (SIGORE, &thread_fatal_action, 0);
1918#endif
1919#ifdef SIGUME
1920 sigaction (SIGUME, &thread_fatal_action, 0);
1921#endif
1922#ifdef SIGDLK
1923 sigaction (SIGDLK, &process_fatal_action, 0);
1924#endif
1925#ifdef SIGCPULIM
1926 sigaction (SIGCPULIM, &process_fatal_action, 0);
1927#endif
1928#ifdef SIGIOT
1929 sigaction (SIGIOT, &thread_fatal_action, 0);
1930#endif
1931#ifdef SIGEMT
1932 sigaction (SIGEMT, &thread_fatal_action, 0);
1933#endif
1934#ifdef SIGBUS
1935 sigaction (SIGBUS, &thread_fatal_action, 0);
1936#endif
1937 sigaction (SIGSEGV, &thread_fatal_action, 0);
1938#ifdef SIGSYS
1939 sigaction (SIGSYS, &thread_fatal_action, 0);
1940#endif
1941 sigaction (SIGTERM, &process_fatal_action, 0);
1942#ifdef SIGPROF
d89460ed 1943 signal (SIGPROF, SIG_IGN);
4d7e6e51
PE
1944#endif
1945#ifdef SIGVTALRM
1946 sigaction (SIGVTALRM, &process_fatal_action, 0);
1947#endif
1948#ifdef SIGXCPU
1949 sigaction (SIGXCPU, &process_fatal_action, 0);
1950#endif
1951#ifdef SIGXFSZ
1952 sigaction (SIGXFSZ, &process_fatal_action, 0);
1953#endif
1954
1955#ifdef SIGDANGER
1956 /* This just means available memory is getting low. */
1957 emacs_sigaction_init (&action, deliver_danger_signal);
1958 sigaction (SIGDANGER, &action, 0);
1959#endif
1960
1961 /* AIX-specific signals. */
1962#ifdef SIGGRANT
1963 sigaction (SIGGRANT, &process_fatal_action, 0);
1964#endif
1965#ifdef SIGMIGRATE
1966 sigaction (SIGMIGRATE, &process_fatal_action, 0);
1967#endif
1968#ifdef SIGMSG
1969 sigaction (SIGMSG, &process_fatal_action, 0);
1970#endif
1971#ifdef SIGRETRACT
1972 sigaction (SIGRETRACT, &process_fatal_action, 0);
1973#endif
1974#ifdef SIGSAK
1975 sigaction (SIGSAK, &process_fatal_action, 0);
1976#endif
1977#ifdef SIGSOUND
1978 sigaction (SIGSOUND, &process_fatal_action, 0);
1979#endif
1980#ifdef SIGTALRM
1981 sigaction (SIGTALRM, &thread_fatal_action, 0);
1982#endif
ca9c0567
PE
1983}
1984\f
9927a7b1 1985#ifndef HAVE_RANDOM
4bb8c8b7
KH
1986#ifdef random
1987#define HAVE_RANDOM
1988#endif
1989#endif
1990
1991/* Figure out how many bits the system's random number generator uses.
1992 `random' and `lrand48' are assumed to return 31 usable bits.
1993 BSD `rand' returns a 31 bit value but the low order bits are unusable;
1994 so we'll shift it and treat it like the 15-bit USG `rand'. */
1995
1996#ifndef RAND_BITS
1997# ifdef HAVE_RANDOM
1998# define RAND_BITS 31
1999# else /* !HAVE_RANDOM */
2000# ifdef HAVE_LRAND48
2001# define RAND_BITS 31
2002# define random lrand48
2003# else /* !HAVE_LRAND48 */
2004# define RAND_BITS 15
2005# if RAND_MAX == 32767
2006# define random rand
2007# else /* RAND_MAX != 32767 */
2008# if RAND_MAX == 2147483647
2009# define random() (rand () >> 16)
2010# else /* RAND_MAX != 2147483647 */
2011# ifdef USG
2012# define random rand
2013# else
2014# define random() (rand () >> 16)
2a633456 2015# endif /* !USG */
4bb8c8b7
KH
2016# endif /* RAND_MAX != 2147483647 */
2017# endif /* RAND_MAX != 32767 */
2018# endif /* !HAVE_LRAND48 */
2019# endif /* !HAVE_RANDOM */
2020#endif /* !RAND_BITS */
2e46c7c6 2021
4bb8c8b7 2022void
0e23ef9d 2023seed_random (void *seed, ptrdiff_t seed_size)
86a5659e 2024{
33634217 2025#if defined HAVE_RANDOM || ! defined HAVE_LRAND48
0e23ef9d
PE
2026 unsigned int arg = 0;
2027#else
2028 long int arg = 0;
2029#endif
2030 unsigned char *argp = (unsigned char *) &arg;
2031 unsigned char *seedp = seed;
2032 ptrdiff_t i;
2033 for (i = 0; i < seed_size; i++)
2034 argp[i % sizeof arg] ^= seedp[i];
4bb8c8b7 2035#ifdef HAVE_RANDOM
0e23ef9d 2036 srandom (arg);
f8b53a82 2037#else
4bb8c8b7 2038# ifdef HAVE_LRAND48
76425a49 2039 srand48 (arg);
4bb8c8b7 2040# else
0e23ef9d 2041 srand (arg);
4bb8c8b7 2042# endif
2e46c7c6 2043#endif
86a5659e
JB
2044}
2045
0e23ef9d
PE
2046void
2047init_random (void)
2048{
2049 EMACS_TIME t = current_emacs_time ();
2050 uintmax_t v = getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t);
2051 seed_random (&v, sizeof v);
2052}
2053
4bb8c8b7 2054/*
d8ed26bd
PE
2055 * Return a nonnegative random integer out of whatever we've got.
2056 * It contains enough bits to make a random (signed) Emacs fixnum.
4bb8c8b7
KH
2057 * This suffices even for a 64-bit architecture with a 15-bit rand.
2058 */
ede49d71 2059EMACS_INT
971de7fb 2060get_random (void)
4bb8c8b7 2061{
ede49d71
PE
2062 EMACS_UINT val = 0;
2063 int i;
d8ed26bd
PE
2064 for (i = 0; i < (FIXNUM_BITS + RAND_BITS - 1) / RAND_BITS; i++)
2065 val = (random () ^ (val << RAND_BITS)
2066 ^ (val >> (BITS_PER_EMACS_INT - RAND_BITS)));
2067 val ^= val >> (BITS_PER_EMACS_INT - FIXNUM_BITS);
2068 return val & INTMASK;
4bb8c8b7 2069}
7088d1ca 2070
55e5faa1
PE
2071#ifndef HAVE_SNPRINTF
2072/* Approximate snprintf as best we can on ancient hosts that lack it. */
2073int
2074snprintf (char *buf, size_t bufsize, char const *format, ...)
2075{
2076 ptrdiff_t size = min (bufsize, PTRDIFF_MAX);
2077 ptrdiff_t nbytes = size - 1;
2078 va_list ap;
2079
2080 if (size)
2081 {
2082 va_start (ap, format);
2083 nbytes = doprnt (buf, size, format, 0, ap);
2084 va_end (ap);
2085 }
2086
2087 if (nbytes == size - 1)
2088 {
2089 /* Calculate the length of the string that would have been created
2090 had the buffer been large enough. */
2091 char stackbuf[4000];
2092 char *b = stackbuf;
2093 ptrdiff_t bsize = sizeof stackbuf;
2094 va_start (ap, format);
2095 nbytes = evxprintf (&b, &bsize, stackbuf, -1, format, ap);
2096 va_end (ap);
2097 if (b != stackbuf)
2098 xfree (b);
2099 }
2100
2101 if (INT_MAX < nbytes)
2102 {
31bed486 2103#ifdef EOVERFLOW
55e5faa1 2104 errno = EOVERFLOW;
31bed486
EZ
2105#else
2106 errno = EDOM;
2107#endif
55e5faa1
PE
2108 return -1;
2109 }
2110 return nbytes;
2111}
2112#endif
86a5659e 2113\f
cf29dd84
PE
2114/* If a backtrace is available, output the top lines of it to stderr.
2115 Do not output more than BACKTRACE_LIMIT or BACKTRACE_LIMIT_MAX lines.
2116 This function may be called from a signal handler, so it should
2117 not invoke async-unsafe functions like malloc. */
2118void
2119emacs_backtrace (int backtrace_limit)
2120{
4d7e6e51 2121 void *main_backtrace_buffer[BACKTRACE_LIMIT_MAX + 1];
cf29dd84 2122 int bounded_limit = min (backtrace_limit, BACKTRACE_LIMIT_MAX);
4d7e6e51
PE
2123 void *buffer;
2124 int npointers;
2125
2126 if (thread_backtrace_npointers)
2127 {
2128 buffer = thread_backtrace_buffer;
2129 npointers = thread_backtrace_npointers;
2130 }
2131 else
2132 {
2133 buffer = main_backtrace_buffer;
2134 npointers = backtrace (buffer, bounded_limit + 1);
2135 }
2136
cf29dd84 2137 if (npointers)
4d7e6e51
PE
2138 {
2139 ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12));
2140 backtrace_symbols_fd (buffer, npointers, STDERR_FILENO);
2141 if (bounded_limit < npointers)
2142 ignore_value (write (STDERR_FILENO, "...\n", 4));
2143 }
cf29dd84
PE
2144}
2145\f
1088b922 2146#ifndef HAVE_NTGUI
1088b922
PE
2147void
2148emacs_abort (void)
2149{
17fdfc15 2150 terminate_due_to_signal (SIGABRT, 40);
1088b922
PE
2151}
2152#endif
2153
86a5659e 2154int
971de7fb 2155emacs_open (const char *path, int oflag, int mode)
86a5659e
JB
2156{
2157 register int rtnval;
68c45bf0 2158
86a5659e 2159 while ((rtnval = open (path, oflag, mode)) == -1
275464e7
SM
2160 && (errno == EINTR))
2161 QUIT;
86a5659e
JB
2162 return (rtnval);
2163}
2164
dfcf069d 2165int
971de7fb 2166emacs_close (int fd)
86a5659e 2167{
fe111daf 2168 int did_retry = 0;
86a5659e
JB
2169 register int rtnval;
2170
2171 while ((rtnval = close (fd)) == -1
fe111daf
KH
2172 && (errno == EINTR))
2173 did_retry = 1;
2174
2175 /* If close is interrupted SunOS 4.1 may or may not have closed the
2176 file descriptor. If it did the second close will fail with
2177 errno = EBADF. That means we have succeeded. */
2178 if (rtnval == -1 && did_retry && errno == EBADF)
2179 return 0;
2180
86a5659e
JB
2181 return rtnval;
2182}
2183
1963a2e0
PE
2184/* Maximum number of bytes to read or write in a single system call.
2185 This works around a serious bug in Linux kernels before 2.6.16; see
2186 <https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=612839>.
2187 It's likely to work around similar bugs in other operating systems, so do it
2188 on all platforms. Round INT_MAX down to a page size, with the conservative
2189 assumption that page sizes are at most 2**18 bytes (any kernel with a
2190 page size larger than that shouldn't have the bug). */
2191#ifndef MAX_RW_COUNT
2192#define MAX_RW_COUNT (INT_MAX >> 18 << 18)
2193#endif
2194
273a5f82
PE
2195/* Read from FILEDESC to a buffer BUF with size NBYTE, retrying if interrupted.
2196 Return the number of bytes read, which might be less than NBYTE.
2197 On error, set errno and return -1. */
d311d28c
PE
2198ptrdiff_t
2199emacs_read (int fildes, char *buf, ptrdiff_t nbyte)
86a5659e 2200{
8a2cbd72 2201 register ssize_t rtnval;
177c0ea7 2202
71b41406
PE
2203 /* There is no need to check against MAX_RW_COUNT, since no caller ever
2204 passes a size that large to emacs_read. */
2205
2206 while ((rtnval = read (fildes, buf, nbyte)) == -1
275464e7
SM
2207 && (errno == EINTR))
2208 QUIT;
86a5659e
JB
2209 return (rtnval);
2210}
2211
273a5f82
PE
2212/* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted
2213 or if a partial write occurs. Return the number of bytes written, setting
2214 errno if this is less than NBYTE. */
d311d28c
PE
2215ptrdiff_t
2216emacs_write (int fildes, const char *buf, ptrdiff_t nbyte)
86a5659e 2217{
273a5f82 2218 ssize_t rtnval;
d311d28c 2219 ptrdiff_t bytes_written;
28272684 2220
b95520f5
BF
2221 bytes_written = 0;
2222
273a5f82 2223 while (nbyte > 0)
b95520f5 2224 {
1963a2e0 2225 rtnval = write (fildes, buf, min (nbyte, MAX_RW_COUNT));
b95520f5 2226
273a5f82 2227 if (rtnval < 0)
b95520f5
BF
2228 {
2229 if (errno == EINTR)
77220eeb 2230 {
77220eeb
SM
2231 /* I originally used `QUIT' but that might causes files to
2232 be truncated if you hit C-g in the middle of it. --Stef */
4d7e6e51
PE
2233 if (pending_signals)
2234 process_pending_signals ();
77220eeb
SM
2235 continue;
2236 }
b95520f5 2237 else
273a5f82 2238 break;
b95520f5
BF
2239 }
2240
2241 buf += rtnval;
2242 nbyte -= rtnval;
2243 bytes_written += rtnval;
2244 }
273a5f82 2245
b95520f5 2246 return (bytes_written);
86a5659e 2247}
86a5659e 2248\f
d35af63c
PE
2249/* Return a struct timeval that is roughly equivalent to T.
2250 Use the least timeval not less than T.
2251 Return an extremal value if the result would overflow. */
2252struct timeval
2253make_timeval (EMACS_TIME t)
2254{
2255 struct timeval tv;
2256 tv.tv_sec = t.tv_sec;
2257 tv.tv_usec = t.tv_nsec / 1000;
2258
2259 if (t.tv_nsec % 1000 != 0)
2260 {
2261 if (tv.tv_usec < 999999)
2262 tv.tv_usec++;
2263 else if (tv.tv_sec < TYPE_MAXIMUM (time_t))
2264 {
2265 tv.tv_sec++;
2266 tv.tv_usec = 0;
2267 }
2268 }
2269
2270 return tv;
2271}
2272
2273/* Set the access and modification time stamps of FD (a.k.a. FILE) to be
2274 ATIME and MTIME, respectively.
2275 FD must be either negative -- in which case it is ignored --
2276 or a file descriptor that is open on FILE.
2277 If FD is nonnegative, then FILE can be NULL. */
53ea491a 2278int
d35af63c
PE
2279set_file_times (int fd, const char *filename,
2280 EMACS_TIME atime, EMACS_TIME mtime)
2281{
2282 struct timespec timespec[2];
2283 timespec[0] = atime;
2284 timespec[1] = mtime;
2285 return fdutimens (fd, filename, timespec);
53ea491a
KH
2286}
2287\f
aa1ba90e
PE
2288/* Like strsignal, except async-signal-safe, and this function typically
2289 returns a string in the C locale rather than the current locale. */
2290char const *
2291safe_strsignal (int code)
68c45bf0 2292{
aa1ba90e 2293 char const *signame = 0;
68c45bf0 2294
c622b48f 2295 if (0 <= code && code < sys_siglist_entries)
aa1ba90e
PE
2296 signame = sys_siglist[code];
2297 if (! signame)
2298 signame = "Unknown signal";
c4ea52a6 2299
68c45bf0
PE
2300 return signame;
2301}
d888760c 2302\f
a7ebc409 2303#ifndef DOS_NT
d888760c 2304/* For make-serial-process */
cf84bb53
JB
2305int
2306serial_open (char *port)
d888760c 2307{
49cdacda 2308 int fd = emacs_open (port, O_RDWR | O_NOCTTY | O_NONBLOCK, 0);
d888760c
GM
2309 if (fd < 0)
2310 {
2311 error ("Could not open %s: %s",
2312 port, emacs_strerror (errno));
2313 }
2314#ifdef TIOCEXCL
2315 ioctl (fd, TIOCEXCL, (char *) 0);
2316#endif
2317
2318 return fd;
2319}
759d3f32
SM
2320
2321#if !defined (HAVE_CFMAKERAW)
2322/* Workaround for targets which are missing cfmakeraw. */
2323/* Pasted from man page. */
cf84bb53
JB
2324static void
2325cfmakeraw (struct termios *termios_p)
759d3f32
SM
2326{
2327 termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
2328 termios_p->c_oflag &= ~OPOST;
2329 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
2330 termios_p->c_cflag &= ~(CSIZE|PARENB);
2331 termios_p->c_cflag |= CS8;
2332}
2333#endif /* !defined (HAVE_CFMAKERAW */
2334
2335#if !defined (HAVE_CFSETSPEED)
2336/* Workaround for targets which are missing cfsetspeed. */
cf84bb53
JB
2337static int
2338cfsetspeed (struct termios *termios_p, speed_t vitesse)
759d3f32
SM
2339{
2340 return (cfsetispeed (termios_p, vitesse)
2341 + cfsetospeed (termios_p, vitesse));
2342}
2343#endif
2344
d888760c
GM
2345/* For serial-process-configure */
2346void
2347serial_configure (struct Lisp_Process *p,
cf84bb53 2348 Lisp_Object contact)
d888760c
GM
2349{
2350 Lisp_Object childp2 = Qnil;
2351 Lisp_Object tem = Qnil;
2352 struct termios attr;
2353 int err = -1;
2354 char summary[4] = "???"; /* This usually becomes "8N1". */
2355
4d2b044c 2356 childp2 = Fcopy_sequence (p->childp);
d888760c
GM
2357
2358 /* Read port attributes and prepare default configuration. */
2359 err = tcgetattr (p->outfd, &attr);
2360 if (err != 0)
2361 error ("tcgetattr() failed: %s", emacs_strerror (errno));
2362 cfmakeraw (&attr);
2363#if defined (CLOCAL)
2364 attr.c_cflag |= CLOCAL;
2365#endif
2366#if defined (CREAD)
6d1921be 2367 attr.c_cflag |= CREAD;
d888760c
GM
2368#endif
2369
2370 /* Configure speed. */
2371 if (!NILP (Fplist_member (contact, QCspeed)))
2372 tem = Fplist_get (contact, QCspeed);
2373 else
4d2b044c 2374 tem = Fplist_get (p->childp, QCspeed);
d888760c
GM
2375 CHECK_NUMBER (tem);
2376 err = cfsetspeed (&attr, XINT (tem));
2377 if (err != 0)
c2982e87 2378 error ("cfsetspeed(%"pI"d) failed: %s", XINT (tem),
5fdb398c 2379 emacs_strerror (errno));
d888760c
GM
2380 childp2 = Fplist_put (childp2, QCspeed, tem);
2381
2382 /* Configure bytesize. */
2383 if (!NILP (Fplist_member (contact, QCbytesize)))
2384 tem = Fplist_get (contact, QCbytesize);
2385 else
4d2b044c 2386 tem = Fplist_get (p->childp, QCbytesize);
d888760c
GM
2387 if (NILP (tem))
2388 tem = make_number (8);
2389 CHECK_NUMBER (tem);
2390 if (XINT (tem) != 7 && XINT (tem) != 8)
2391 error (":bytesize must be nil (8), 7, or 8");
cf84bb53 2392 summary[0] = XINT (tem) + '0';
d888760c
GM
2393#if defined (CSIZE) && defined (CS7) && defined (CS8)
2394 attr.c_cflag &= ~CSIZE;
2395 attr.c_cflag |= ((XINT (tem) == 7) ? CS7 : CS8);
2396#else
16bad4dd 2397 /* Don't error on bytesize 8, which should be set by cfmakeraw. */
d888760c
GM
2398 if (XINT (tem) != 8)
2399 error ("Bytesize cannot be changed");
2400#endif
2401 childp2 = Fplist_put (childp2, QCbytesize, tem);
2402
2403 /* Configure parity. */
2404 if (!NILP (Fplist_member (contact, QCparity)))
2405 tem = Fplist_get (contact, QCparity);
2406 else
4d2b044c 2407 tem = Fplist_get (p->childp, QCparity);
d888760c
GM
2408 if (!NILP (tem) && !EQ (tem, Qeven) && !EQ (tem, Qodd))
2409 error (":parity must be nil (no parity), `even', or `odd'");
2410#if defined (PARENB) && defined (PARODD) && defined (IGNPAR) && defined (INPCK)
2411 attr.c_cflag &= ~(PARENB | PARODD);
2412 attr.c_iflag &= ~(IGNPAR | INPCK);
2413 if (NILP (tem))
2414 {
2415 summary[1] = 'N';
2416 }
2417 else if (EQ (tem, Qeven))
2418 {
2419 summary[1] = 'E';
2420 attr.c_cflag |= PARENB;
2421 attr.c_iflag |= (IGNPAR | INPCK);
2422 }
2423 else if (EQ (tem, Qodd))
2424 {
2425 summary[1] = 'O';
2426 attr.c_cflag |= (PARENB | PARODD);
2427 attr.c_iflag |= (IGNPAR | INPCK);
2428 }
2429#else
16bad4dd 2430 /* Don't error on no parity, which should be set by cfmakeraw. */
d888760c
GM
2431 if (!NILP (tem))
2432 error ("Parity cannot be configured");
2433#endif
2434 childp2 = Fplist_put (childp2, QCparity, tem);
2435
2436 /* Configure stopbits. */
2437 if (!NILP (Fplist_member (contact, QCstopbits)))
2438 tem = Fplist_get (contact, QCstopbits);
2439 else
4d2b044c 2440 tem = Fplist_get (p->childp, QCstopbits);
d888760c
GM
2441 if (NILP (tem))
2442 tem = make_number (1);
2443 CHECK_NUMBER (tem);
2444 if (XINT (tem) != 1 && XINT (tem) != 2)
2445 error (":stopbits must be nil (1 stopbit), 1, or 2");
2446 summary[2] = XINT (tem) + '0';
2447#if defined (CSTOPB)
2448 attr.c_cflag &= ~CSTOPB;
2449 if (XINT (tem) == 2)
2450 attr.c_cflag |= CSTOPB;
2451#else
16bad4dd 2452 /* Don't error on 1 stopbit, which should be set by cfmakeraw. */
d888760c
GM
2453 if (XINT (tem) != 1)
2454 error ("Stopbits cannot be configured");
2455#endif
2456 childp2 = Fplist_put (childp2, QCstopbits, tem);
2457
2458 /* Configure flowcontrol. */
2459 if (!NILP (Fplist_member (contact, QCflowcontrol)))
2460 tem = Fplist_get (contact, QCflowcontrol);
2461 else
4d2b044c 2462 tem = Fplist_get (p->childp, QCflowcontrol);
d888760c
GM
2463 if (!NILP (tem) && !EQ (tem, Qhw) && !EQ (tem, Qsw))
2464 error (":flowcontrol must be nil (no flowcontrol), `hw', or `sw'");
2465#if defined (CRTSCTS)
2466 attr.c_cflag &= ~CRTSCTS;
2467#endif
2468#if defined (CNEW_RTSCTS)
2469 attr.c_cflag &= ~CNEW_RTSCTS;
2470#endif
2471#if defined (IXON) && defined (IXOFF)
2472 attr.c_iflag &= ~(IXON | IXOFF);
2473#endif
2474 if (NILP (tem))
2475 {
2476 /* Already configured. */
2477 }
2478 else if (EQ (tem, Qhw))
2479 {
2480#if defined (CRTSCTS)
2481 attr.c_cflag |= CRTSCTS;
2482#elif defined (CNEW_RTSCTS)
2483 attr.c_cflag |= CNEW_RTSCTS;
2484#else
2485 error ("Hardware flowcontrol (RTS/CTS) not supported");
2486#endif
2487 }
2488 else if (EQ (tem, Qsw))
2489 {
2490#if defined (IXON) && defined (IXOFF)
2491 attr.c_iflag |= (IXON | IXOFF);
2492#else
2493 error ("Software flowcontrol (XON/XOFF) not supported");
2494#endif
2495 }
2496 childp2 = Fplist_put (childp2, QCflowcontrol, tem);
2497
2498 /* Activate configuration. */
2499 err = tcsetattr (p->outfd, TCSANOW, &attr);
2500 if (err != 0)
2501 error ("tcsetattr() failed: %s", emacs_strerror (errno));
2502
2503 childp2 = Fplist_put (childp2, QCsummary, build_string (summary));
6a09a33b 2504 pset_childp (p, childp2);
d888760c 2505}
a7ebc409 2506#endif /* not DOS_NT */
06e111a6
DN
2507\f
2508/* System depended enumeration of and access to system processes a-la ps(1). */
2509
2510#ifdef HAVE_PROCFS
2511
2512/* Process enumeration and access via /proc. */
2513
2514Lisp_Object
971de7fb 2515list_system_processes (void)
06e111a6
DN
2516{
2517 Lisp_Object procdir, match, proclist, next;
2518 struct gcpro gcpro1, gcpro2;
2519 register Lisp_Object tail;
2520
2521 GCPRO2 (procdir, match);
2522 /* For every process on the system, there's a directory in the
2523 "/proc" pseudo-directory whose name is the numeric ID of that
2524 process. */
2525 procdir = build_string ("/proc");
2526 match = build_string ("[0-9]+");
86ec63ba 2527 proclist = directory_files_internal (procdir, Qnil, match, Qt, 0, Qnil);
06e111a6
DN
2528
2529 /* `proclist' gives process IDs as strings. Destructively convert
2530 each string into a number. */
2531 for (tail = proclist; CONSP (tail); tail = next)
2532 {
2533 next = XCDR (tail);
2534 XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil));
2535 }
2536 UNGCPRO;
2537
2538 /* directory_files_internal returns the files in reverse order; undo
2539 that. */
2540 proclist = Fnreverse (proclist);
2541 return proclist;
2542}
2543
f01769f9 2544#elif defined BSD_SYSTEM
b91b7e4d
EW
2545
2546Lisp_Object
5790543d 2547list_system_processes (void)
b91b7e4d 2548{
f3047c75 2549#if defined DARWIN_OS || defined __NetBSD__ || defined __OpenBSD__
f01769f9
LL
2550 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
2551#else
b91b7e4d 2552 int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PROC};
f01769f9 2553#endif
b91b7e4d
EW
2554 size_t len;
2555 struct kinfo_proc *procs;
2556 size_t i;
2557
2558 struct gcpro gcpro1;
2559 Lisp_Object proclist = Qnil;
2560
2561 if (sysctl (mib, 3, NULL, &len, NULL, 0) != 0)
2562 return proclist;
5790543d 2563
b91b7e4d
EW
2564 procs = xmalloc (len);
2565 if (sysctl (mib, 3, procs, &len, NULL, 0) != 0)
2566 {
2567 xfree (procs);
2568 return proclist;
2569 }
5790543d 2570
b91b7e4d
EW
2571 GCPRO1 (proclist);
2572 len /= sizeof (struct kinfo_proc);
2573 for (i = 0; i < len; i++)
f01769f9 2574 {
f3047c75 2575#if defined DARWIN_OS || defined __NetBSD__
f01769f9 2576 proclist = Fcons (make_fixnum_or_float (procs[i].kp_proc.p_pid), proclist);
7dca65a4
PE
2577#elif defined __OpenBSD__
2578 proclist = Fcons (make_fixnum_or_float (procs[i].p_pid), proclist);
f01769f9
LL
2579#else
2580 proclist = Fcons (make_fixnum_or_float (procs[i].ki_pid), proclist);
2581#endif
2582 }
b91b7e4d 2583 UNGCPRO;
5790543d 2584
b91b7e4d
EW
2585 xfree (procs);
2586
2587 return proclist;
2588}
2589
f8d23104
DN
2590/* The WINDOWSNT implementation is in w32.c.
2591 The MSDOS implementation is in dosfns.c. */
c4605e09 2592#elif !defined (WINDOWSNT) && !defined (MSDOS)
06e111a6
DN
2593
2594Lisp_Object
cf84bb53 2595list_system_processes (void)
06e111a6
DN
2596{
2597 return Qnil;
2598}
91c85b70
EZ
2599
2600#endif /* !defined (WINDOWSNT) */
06e111a6
DN
2601
2602#ifdef GNU_LINUX
d35af63c
PE
2603static EMACS_TIME
2604time_from_jiffies (unsigned long long tval, long hz)
2605{
2606 unsigned long long s = tval / hz;
2607 unsigned long long frac = tval % hz;
2608 int ns;
d35af63c
PE
2609
2610 if (TYPE_MAXIMUM (time_t) < s)
2611 time_overflow ();
2612 if (LONG_MAX - 1 <= ULLONG_MAX / EMACS_TIME_RESOLUTION
2613 || frac <= ULLONG_MAX / EMACS_TIME_RESOLUTION)
2614 ns = frac * EMACS_TIME_RESOLUTION / hz;
06e111a6 2615 else
d35af63c
PE
2616 {
2617 /* This is reachable only in the unlikely case that HZ * HZ
2618 exceeds ULLONG_MAX. It calculates an approximation that is
2619 guaranteed to be in range. */
2620 long hz_per_ns = (hz / EMACS_TIME_RESOLUTION
2621 + (hz % EMACS_TIME_RESOLUTION != 0));
2622 ns = frac / hz_per_ns;
2623 }
2624
e9a9ae03 2625 return make_emacs_time (s, ns);
06e111a6
DN
2626}
2627
2628static Lisp_Object
2629ltime_from_jiffies (unsigned long long tval, long hz)
2630{
d35af63c
PE
2631 EMACS_TIME t = time_from_jiffies (tval, hz);
2632 return make_lisp_time (t);
06e111a6
DN
2633}
2634
d35af63c
PE
2635static EMACS_TIME
2636get_up_time (void)
06e111a6
DN
2637{
2638 FILE *fup;
e9a9ae03 2639 EMACS_TIME up = make_emacs_time (0, 0);
06e111a6 2640
4d7e6e51 2641 block_input ();
06e111a6
DN
2642 fup = fopen ("/proc/uptime", "r");
2643
2644 if (fup)
2645 {
d35af63c
PE
2646 unsigned long long upsec, upfrac, idlesec, idlefrac;
2647 int upfrac_start, upfrac_end, idlefrac_start, idlefrac_end;
06e111a6 2648
d35af63c
PE
2649 if (fscanf (fup, "%llu.%n%llu%n %llu.%n%llu%n",
2650 &upsec, &upfrac_start, &upfrac, &upfrac_end,
2651 &idlesec, &idlefrac_start, &idlefrac, &idlefrac_end)
2652 == 4)
06e111a6 2653 {
d35af63c
PE
2654 if (TYPE_MAXIMUM (time_t) < upsec)
2655 {
2656 upsec = TYPE_MAXIMUM (time_t);
2657 upfrac = EMACS_TIME_RESOLUTION - 1;
2658 }
2659 else
2660 {
2661 int upfraclen = upfrac_end - upfrac_start;
2662 for (; upfraclen < LOG10_EMACS_TIME_RESOLUTION; upfraclen++)
2663 upfrac *= 10;
2664 for (; LOG10_EMACS_TIME_RESOLUTION < upfraclen; upfraclen--)
2665 upfrac /= 10;
2666 upfrac = min (upfrac, EMACS_TIME_RESOLUTION - 1);
2667 }
e9a9ae03 2668 up = make_emacs_time (upsec, upfrac);
06e111a6
DN
2669 }
2670 fclose (fup);
2671 }
4d7e6e51 2672 unblock_input ();
d35af63c
PE
2673
2674 return up;
06e111a6
DN
2675}
2676
2677#define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
2678#define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12))
2679
2680static Lisp_Object
f4f634e8 2681procfs_ttyname (int rdev)
06e111a6
DN
2682{
2683 FILE *fdev = NULL;
2684 char name[PATH_MAX];
2685
4d7e6e51 2686 block_input ();
06e111a6
DN
2687 fdev = fopen ("/proc/tty/drivers", "r");
2688
2689 if (fdev)
2690 {
2691 unsigned major;
2692 unsigned long minor_beg, minor_end;
2693 char minor[25]; /* 2 32-bit numbers + dash */
2694 char *endp;
2695
2696 while (!feof (fdev) && !ferror (fdev))
2697 {
2698 if (3 <= fscanf (fdev, "%*s %s %u %s %*s\n", name, &major, minor)
2699 && major == MAJOR (rdev))
2700 {
2701 minor_beg = strtoul (minor, &endp, 0);
2702 if (*endp == '\0')
2703 minor_end = minor_beg;
2704 else if (*endp == '-')
2705 minor_end = strtoul (endp + 1, &endp, 0);
2706 else
2707 continue;
2708
2709 if (MINOR (rdev) >= minor_beg && MINOR (rdev) <= minor_end)
2710 {
10d66ec0 2711 sprintf (name + strlen (name), "%u", MINOR (rdev));
06e111a6
DN
2712 break;
2713 }
2714 }
2715 }
2716 fclose (fdev);
2717 }
4d7e6e51 2718 unblock_input ();
06e111a6
DN
2719 return build_string (name);
2720}
2721
2722static unsigned long
2723procfs_get_total_memory (void)
2724{
2725 FILE *fmem = NULL;
2726 unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */
2727
4d7e6e51 2728 block_input ();
06e111a6
DN
2729 fmem = fopen ("/proc/meminfo", "r");
2730
2731 if (fmem)
2732 {
2733 unsigned long entry_value;
2734 char entry_name[20]; /* the longest I saw is 13+1 */
2735
2736 while (!feof (fmem) && !ferror (fmem))
2737 {
2738 if (2 <= fscanf (fmem, "%s %lu kB\n", entry_name, &entry_value)
2739 && strcmp (entry_name, "MemTotal:") == 0)
2740 {
2741 retval = entry_value;
2742 break;
2743 }
2744 }
2745 fclose (fmem);
2746 }
4d7e6e51 2747 unblock_input ();
06e111a6
DN
2748 return retval;
2749}
2750
2751Lisp_Object
f4f634e8 2752system_process_attributes (Lisp_Object pid)
06e111a6
DN
2753{
2754 char procfn[PATH_MAX], fn[PATH_MAX];
2755 struct stat st;
2756 struct passwd *pw;
2757 struct group *gr;
2758 long clocks_per_sec;
2759 char *procfn_end;
2760 char procbuf[1025], *p, *q;
2761 int fd;
2762 ssize_t nread;
e99a530f
PE
2763 static char const default_cmd[] = "???";
2764 const char *cmd = default_cmd;
2765 int cmdsize = sizeof default_cmd - 1;
06e111a6 2766 char *cmdline = NULL;
e99a530f 2767 ptrdiff_t cmdline_size;
06e111a6 2768 unsigned char c;
d311d28c
PE
2769 printmax_t proc_id;
2770 int ppid, pgrp, sess, tty, tpgid, thcount;
2771 uid_t uid;
2772 gid_t gid;
a70072c9
PE
2773 unsigned long long u_time, s_time, cutime, cstime, start;
2774 long priority, niceness, rss;
06e111a6 2775 unsigned long minflt, majflt, cminflt, cmajflt, vsize;
d35af63c 2776 EMACS_TIME tnow, tstart, tboot, telapsed, us_time;
06e111a6
DN
2777 double pcpu, pmem;
2778 Lisp_Object attrs = Qnil;
2779 Lisp_Object cmd_str, decoded_cmd, tem;
2780 struct gcpro gcpro1, gcpro2;
06e111a6
DN
2781
2782 CHECK_NUMBER_OR_FLOAT (pid);
225a2cff 2783 CONS_TO_INTEGER (pid, pid_t, proc_id);
d311d28c 2784 sprintf (procfn, "/proc/%"pMd, proc_id);
06e111a6
DN
2785 if (stat (procfn, &st) < 0)
2786 return attrs;
2787
2788 GCPRO2 (attrs, decoded_cmd);
2789
2790 /* euid egid */
2791 uid = st.st_uid;
d311d28c 2792 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs);
4d7e6e51 2793 block_input ();
06e111a6 2794 pw = getpwuid (uid);
4d7e6e51 2795 unblock_input ();
06e111a6
DN
2796 if (pw)
2797 attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
2798
2799 gid = st.st_gid;
d311d28c 2800 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs);
4d7e6e51 2801 block_input ();
06e111a6 2802 gr = getgrgid (gid);
4d7e6e51 2803 unblock_input ();
06e111a6
DN
2804 if (gr)
2805 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
2806
2807 strcpy (fn, procfn);
2808 procfn_end = fn + strlen (fn);
2809 strcpy (procfn_end, "/stat");
2810 fd = emacs_open (fn, O_RDONLY, 0);
cf84bb53 2811 if (fd >= 0 && (nread = emacs_read (fd, procbuf, sizeof (procbuf) - 1)) > 0)
06e111a6
DN
2812 {
2813 procbuf[nread] = '\0';
2814 p = procbuf;
2815
2816 p = strchr (p, '(');
2817 if (p != NULL)
2818 {
2819 q = strrchr (p + 1, ')');
2820 /* comm */
2821 if (q != NULL)
2822 {
2823 cmd = p + 1;
2824 cmdsize = q - cmd;
2825 }
2826 }
2827 else
2828 q = NULL;
06e111a6
DN
2829 /* Command name is encoded in locale-coding-system; decode it. */
2830 cmd_str = make_unibyte_string (cmd, cmdsize);
2831 decoded_cmd = code_convert_string_norecord (cmd_str,
2832 Vlocale_coding_system, 0);
2833 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
2834
2835 if (q)
2836 {
2837 EMACS_INT ppid_eint, pgrp_eint, sess_eint, tpgid_eint, thcount_eint;
2838 p = q + 2;
2839 /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */
2840 sscanf (p, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld",
2841 &c, &ppid, &pgrp, &sess, &tty, &tpgid,
2842 &minflt, &cminflt, &majflt, &cmajflt,
a70072c9
PE
2843 &u_time, &s_time, &cutime, &cstime,
2844 &priority, &niceness, &thcount, &start, &vsize, &rss);
06e111a6
DN
2845 {
2846 char state_str[2];
2847
2848 state_str[0] = c;
2849 state_str[1] = '\0';
2850 tem = build_string (state_str);
2851 attrs = Fcons (Fcons (Qstate, tem), attrs);
2852 }
2853 /* Stops GCC whining about limited range of data type. */
2854 ppid_eint = ppid;
2855 pgrp_eint = pgrp;
2856 sess_eint = sess;
2857 tpgid_eint = tpgid;
2858 thcount_eint = thcount;
2859 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid_eint)), attrs);
2860 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp_eint)), attrs);
2861 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess_eint)), attrs);
2862 attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs);
2863 attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid_eint)), attrs);
2864 attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs);
2865 attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs);
2866 attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), attrs);
2867 attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), attrs);
2868 clocks_per_sec = sysconf (_SC_CLK_TCK);
2869 if (clocks_per_sec < 0)
2870 clocks_per_sec = 100;
2871 attrs = Fcons (Fcons (Qutime,
a70072c9 2872 ltime_from_jiffies (u_time, clocks_per_sec)),
06e111a6
DN
2873 attrs);
2874 attrs = Fcons (Fcons (Qstime,
a70072c9 2875 ltime_from_jiffies (s_time, clocks_per_sec)),
06e111a6 2876 attrs);
ac1e4171 2877 attrs = Fcons (Fcons (Qtime,
a70072c9
PE
2878 ltime_from_jiffies (s_time + u_time,
2879 clocks_per_sec)),
ac1e4171 2880 attrs);
06e111a6
DN
2881 attrs = Fcons (Fcons (Qcutime,
2882 ltime_from_jiffies (cutime, clocks_per_sec)),
2883 attrs);
2884 attrs = Fcons (Fcons (Qcstime,
2885 ltime_from_jiffies (cstime, clocks_per_sec)),
ac1e4171
EZ
2886 attrs);
2887 attrs = Fcons (Fcons (Qctime,
2888 ltime_from_jiffies (cstime+cutime, clocks_per_sec)),
06e111a6
DN
2889 attrs);
2890 attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs);
a70072c9 2891 attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs);
06e111a6 2892 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount_eint)), attrs);
e9a9ae03 2893 tnow = current_emacs_time ();
d35af63c 2894 telapsed = get_up_time ();
e9a9ae03 2895 tboot = sub_emacs_time (tnow, telapsed);
d35af63c 2896 tstart = time_from_jiffies (start, clocks_per_sec);
e9a9ae03 2897 tstart = add_emacs_time (tboot, tstart);
d35af63c 2898 attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs);
06e111a6
DN
2899 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize/1024)), attrs);
2900 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4*rss)), attrs);
e9a9ae03 2901 telapsed = sub_emacs_time (tnow, tstart);
d35af63c
PE
2902 attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs);
2903 us_time = time_from_jiffies (u_time + s_time, clocks_per_sec);
2904 pcpu = (EMACS_TIME_TO_DOUBLE (us_time)
2905 / EMACS_TIME_TO_DOUBLE (telapsed));
06e111a6
DN
2906 if (pcpu > 1.0)
2907 pcpu = 1.0;
2908 attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs);
2909 pmem = 4.0 * 100 * rss / procfs_get_total_memory ();
2910 if (pmem > 100)
2911 pmem = 100;
2912 attrs = Fcons (Fcons (Qpmem, make_float (pmem)), attrs);
2913 }
2914 }
2915 if (fd >= 0)
2916 emacs_close (fd);
2917
2918 /* args */
2919 strcpy (procfn_end, "/cmdline");
2920 fd = emacs_open (fn, O_RDONLY, 0);
2921 if (fd >= 0)
2922 {
fbd02d7b 2923 char ch;
fe6442b1 2924 for (cmdline_size = 0; cmdline_size < STRING_BYTES_BOUND; cmdline_size++)
06e111a6 2925 {
fe6442b1
PE
2926 if (emacs_read (fd, &ch, 1) != 1)
2927 break;
fbd02d7b 2928 c = ch;
620f13b0 2929 if (c_isspace (c) || c == '\\')
06e111a6
DN
2930 cmdline_size++; /* for later quoting, see below */
2931 }
2932 if (cmdline_size)
2933 {
2934 cmdline = xmalloc (cmdline_size + 1);
2935 lseek (fd, 0L, SEEK_SET);
2936 cmdline[0] = '\0';
2937 if ((nread = read (fd, cmdline, cmdline_size)) >= 0)
2938 cmdline[nread++] = '\0';
2939 else
2940 {
2941 /* Assigning zero to `nread' makes us skip the following
2942 two loops, assign zero to cmdline_size, and enter the
2943 following `if' clause that handles unknown command
2944 lines. */
2945 nread = 0;
2946 }
2947 /* We don't want trailing null characters. */
fe6442b1 2948 for (p = cmdline + nread; p > cmdline + 1 && !p[-1]; p--)
06e111a6
DN
2949 nread--;
2950 for (p = cmdline; p < cmdline + nread; p++)
2951 {
2952 /* Escape-quote whitespace and backslashes. */
620f13b0 2953 if (c_isspace (*p) || *p == '\\')
06e111a6
DN
2954 {
2955 memmove (p + 1, p, nread - (p - cmdline));
2956 nread++;
2957 *p++ = '\\';
2958 }
2959 else if (*p == '\0')
2960 *p = ' ';
2961 }
2962 cmdline_size = nread;
2963 }
2964 if (!cmdline_size)
2965 {
06e111a6
DN
2966 cmdline_size = cmdsize + 2;
2967 cmdline = xmalloc (cmdline_size + 1);
e99a530f 2968 sprintf (cmdline, "[%.*s]", cmdsize, cmd);
06e111a6
DN
2969 }
2970 emacs_close (fd);
2971 /* Command line is encoded in locale-coding-system; decode it. */
2972 cmd_str = make_unibyte_string (cmdline, cmdline_size);
2973 decoded_cmd = code_convert_string_norecord (cmd_str,
2974 Vlocale_coding_system, 0);
2975 xfree (cmdline);
2976 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
2977 }
2978
2979 UNGCPRO;
2980 return attrs;
2981}
91c85b70 2982
f4f634e8
DN
2983#elif defined (SOLARIS2) && defined (HAVE_PROCFS)
2984
2985/* The <procfs.h> header does not like to be included if _LP64 is defined and
2986 __FILE_OFFSET_BITS == 64. This is an ugly workaround that. */
2987#if !defined (_LP64) && defined (_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
2988#define PROCFS_FILE_OFFSET_BITS_HACK 1
2989#undef _FILE_OFFSET_BITS
2990#else
2991#define PROCFS_FILE_OFFSET_BITS_HACK 0
2992#endif
2993
2994#include <procfs.h>
2995
2996#if PROCFS_FILE_OFFSET_BITS_HACK == 1
2997#define _FILE_OFFSET_BITS 64
90efadd1
PE
2998#ifdef _FILE_OFFSET_BITS /* Avoid unused-macro warnings. */
2999#endif
f4f634e8
DN
3000#endif /* PROCFS_FILE_OFFSET_BITS_HACK == 1 */
3001
3002Lisp_Object
3003system_process_attributes (Lisp_Object pid)
3004{
3005 char procfn[PATH_MAX], fn[PATH_MAX];
3006 struct stat st;
3007 struct passwd *pw;
3008 struct group *gr;
3009 char *procfn_end;
3010 struct psinfo pinfo;
3011 int fd;
3012 ssize_t nread;
d311d28c
PE
3013 printmax_t proc_id;
3014 uid_t uid;
3015 gid_t gid;
f4f634e8
DN
3016 Lisp_Object attrs = Qnil;
3017 Lisp_Object decoded_cmd, tem;
3018 struct gcpro gcpro1, gcpro2;
f4f634e8
DN
3019
3020 CHECK_NUMBER_OR_FLOAT (pid);
225a2cff 3021 CONS_TO_INTEGER (pid, pid_t, proc_id);
d311d28c 3022 sprintf (procfn, "/proc/%"pMd, proc_id);
f4f634e8
DN
3023 if (stat (procfn, &st) < 0)
3024 return attrs;
3025
3026 GCPRO2 (attrs, decoded_cmd);
3027
3028 /* euid egid */
3029 uid = st.st_uid;
d311d28c 3030 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs);
4d7e6e51 3031 block_input ();
f4f634e8 3032 pw = getpwuid (uid);
4d7e6e51 3033 unblock_input ();
f4f634e8
DN
3034 if (pw)
3035 attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
3036
3037 gid = st.st_gid;
d311d28c 3038 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs);
4d7e6e51 3039 block_input ();
f4f634e8 3040 gr = getgrgid (gid);
4d7e6e51 3041 unblock_input ();
f4f634e8
DN
3042 if (gr)
3043 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3044
3045 strcpy (fn, procfn);
3046 procfn_end = fn + strlen (fn);
3047 strcpy (procfn_end, "/psinfo");
3048 fd = emacs_open (fn, O_RDONLY, 0);
3049 if (fd >= 0
cf84bb53 3050 && (nread = read (fd, (char*)&pinfo, sizeof (struct psinfo)) > 0))
f4f634e8
DN
3051 {
3052 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs);
3053 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs);
3054 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs);
3055
3056 {
3057 char state_str[2];
3058 state_str[0] = pinfo.pr_lwp.pr_sname;
3059 state_str[1] = '\0';
3060 tem = build_string (state_str);
3061 attrs = Fcons (Fcons (Qstate, tem), attrs);
3062 }
3063
3064 /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
3065 need to get a string from it. */
3066
3067 /* FIXME: missing: Qtpgid */
3068
3069 /* FIXME: missing:
3070 Qminflt
3071 Qmajflt
3072 Qcminflt
3073 Qcmajflt
3074
bfe11752
DN
3075 Qutime
3076 Qcutime
f4f634e8
DN
3077 Qstime
3078 Qcstime
3079 Are they available? */
3080
d35af63c
PE
3081 attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs);
3082 attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs);
f4f634e8
DN
3083 attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs);
3084 attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs);
3085 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), attrs);
3086
d35af63c 3087 attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs);
f4f634e8
DN
3088 attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), attrs);
3089 attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), attrs);
3090
773d47f6
PE
3091 /* pr_pctcpu and pr_pctmem are unsigned integers in the
3092 range 0 .. 2**15, representing 0.0 .. 1.0. */
63810350
PE
3093 attrs = Fcons (Fcons (Qpcpu, make_float (100.0 / 0x8000 * pinfo.pr_pctcpu)), attrs);
3094 attrs = Fcons (Fcons (Qpmem, make_float (100.0 / 0x8000 * pinfo.pr_pctmem)), attrs);
f4f634e8
DN
3095
3096 decoded_cmd
3097 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_fname,
3098 strlen (pinfo.pr_fname)),
3099 Vlocale_coding_system, 0);
3100 attrs = Fcons (Fcons (Qcomm, decoded_cmd), attrs);
3101 decoded_cmd
3102 = code_convert_string_norecord (make_unibyte_string (pinfo.pr_psargs,
3103 strlen (pinfo.pr_psargs)),
3104 Vlocale_coding_system, 0);
3105 attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
3106 }
3107
2d2d05d8
DN
3108 if (fd >= 0)
3109 emacs_close (fd);
3110
f4f634e8
DN
3111 UNGCPRO;
3112 return attrs;
3113}
06e111a6 3114
5790543d 3115#elif defined __FreeBSD__
b91b7e4d 3116
d054f3fb
PE
3117static EMACS_TIME
3118timeval_to_EMACS_TIME (struct timeval t)
3119{
e9a9ae03 3120 return make_emacs_time (t.tv_sec, t.tv_usec * 1000);
d054f3fb
PE
3121}
3122
3123static Lisp_Object
db7b8d06 3124make_lisp_timeval (struct timeval t)
d054f3fb
PE
3125{
3126 return make_lisp_time (timeval_to_EMACS_TIME (t));
3127}
3128
b91b7e4d
EW
3129Lisp_Object
3130system_process_attributes (Lisp_Object pid)
3131{
3132 int proc_id;
5790543d 3133 int pagesize = getpagesize ();
b91b7e4d
EW
3134 int npages;
3135 int fscale;
3136 struct passwd *pw;
3137 struct group *gr;
3138 char *ttyname;
3139 size_t len;
3140 char args[MAXPATHLEN];
3141 EMACS_TIME t, now;
5790543d 3142
b91b7e4d
EW
3143 int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID};
3144 struct kinfo_proc proc;
5790543d 3145 size_t proclen = sizeof proc;
b91b7e4d
EW
3146
3147 struct gcpro gcpro1, gcpro2;
3148 Lisp_Object attrs = Qnil;
3149 Lisp_Object decoded_comm;
5790543d 3150
b91b7e4d 3151 CHECK_NUMBER_OR_FLOAT (pid);
af52196c 3152 CONS_TO_INTEGER (pid, int, proc_id);
b91b7e4d 3153 mib[3] = proc_id;
5790543d 3154
b91b7e4d
EW
3155 if (sysctl (mib, 4, &proc, &proclen, NULL, 0) != 0)
3156 return attrs;
3157
3158 GCPRO2 (attrs, decoded_comm);
5790543d
PE
3159
3160 attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (proc.ki_uid)), attrs);
3161
4d7e6e51 3162 block_input ();
b91b7e4d 3163 pw = getpwuid (proc.ki_uid);
4d7e6e51 3164 unblock_input ();
b91b7e4d
EW
3165 if (pw)
3166 attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs);
3167
5790543d 3168 attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (proc.ki_svgid)), attrs);
b91b7e4d 3169
4d7e6e51 3170 block_input ();
b91b7e4d 3171 gr = getgrgid (proc.ki_svgid);
4d7e6e51 3172 unblock_input ();
b91b7e4d
EW
3173 if (gr)
3174 attrs = Fcons (Fcons (Qgroup, build_string (gr->gr_name)), attrs);
3175
3176 decoded_comm = code_convert_string_norecord
3177 (make_unibyte_string (proc.ki_comm, strlen (proc.ki_comm)),
3178 Vlocale_coding_system, 0);
5790543d 3179
b91b7e4d
EW
3180 attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
3181 {
3182 char state[2] = {'\0', '\0'};
3183 switch (proc.ki_stat)
3184 {
3185 case SRUN:
3186 state[0] = 'R';
3187 break;
3188
3189 case SSLEEP:
3190 state[0] = 'S';
3191 break;
5790543d 3192
b91b7e4d
EW
3193 case SLOCK:
3194 state[0] = 'D';
3195 break;
3196
3197 case SZOMB:
3198 state[0] = 'Z';
3199 break;
5790543d 3200
b91b7e4d
EW
3201 case SSTOP:
3202 state[0] = 'T';
3203 break;
3204 }
3205 attrs = Fcons (Fcons (Qstate, build_string (state)), attrs);
3206 }
5790543d 3207
b91b7e4d
EW
3208 attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (proc.ki_ppid)), attrs);
3209 attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (proc.ki_pgid)), attrs);
3210 attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (proc.ki_sid)), attrs);
3211
4d7e6e51 3212 block_input ();
b91b7e4d 3213 ttyname = proc.ki_tdev == NODEV ? NULL : devname (proc.ki_tdev, S_IFCHR);
4d7e6e51 3214 unblock_input ();
b91b7e4d
EW
3215 if (ttyname)
3216 attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs);
5790543d 3217
b91b7e4d
EW
3218 attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (proc.ki_tpgid)), attrs);
3219 attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (proc.ki_rusage.ru_minflt)), attrs);
3220 attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (proc.ki_rusage.ru_majflt)), attrs);
3221 attrs = Fcons (Fcons (Qcminflt, make_number (proc.ki_rusage_ch.ru_minflt)), attrs);
3222 attrs = Fcons (Fcons (Qcmajflt, make_number (proc.ki_rusage_ch.ru_majflt)), attrs);
3223
db7b8d06
PE
3224 attrs = Fcons (Fcons (Qutime, make_lisp_timeval (proc.ki_rusage.ru_utime)),
3225 attrs);
3226 attrs = Fcons (Fcons (Qstime, make_lisp_timeval (proc.ki_rusage.ru_stime)),
3227 attrs);
e9a9ae03
PE
3228 t = add_emacs_time (timeval_to_EMACS_TIME (proc.ki_rusage.ru_utime),
3229 timeval_to_EMACS_TIME (proc.ki_rusage.ru_stime));
db7b8d06 3230 attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs);
b91b7e4d 3231
db7b8d06
PE
3232 attrs = Fcons (Fcons (Qcutime,
3233 make_lisp_timeval (proc.ki_rusage_ch.ru_utime)),
3234 attrs);
3235 attrs = Fcons (Fcons (Qcstime,
3236 make_lisp_timeval (proc.ki_rusage_ch.ru_utime)),
3237 attrs);
e9a9ae03
PE
3238 t = add_emacs_time (timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_utime),
3239 timeval_to_EMACS_TIME (proc.ki_rusage_ch.ru_stime));
db7b8d06 3240 attrs = Fcons (Fcons (Qctime, make_lisp_time (t)), attrs);
b91b7e4d 3241
5790543d
PE
3242 attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (proc.ki_numthreads)),
3243 attrs);
b91b7e4d
EW
3244 attrs = Fcons (Fcons (Qpri, make_number (proc.ki_pri.pri_native)), attrs);
3245 attrs = Fcons (Fcons (Qnice, make_number (proc.ki_nice)), attrs);
db7b8d06 3246 attrs = Fcons (Fcons (Qstart, make_lisp_timeval (proc.ki_start)), attrs);
b91b7e4d 3247 attrs = Fcons (Fcons (Qvsize, make_number (proc.ki_size >> 10)), attrs);
5790543d
PE
3248 attrs = Fcons (Fcons (Qrss, make_number (proc.ki_rssize * pagesize >> 10)),
3249 attrs);
b91b7e4d 3250
e9a9ae03
PE
3251 now = current_emacs_time ();
3252 t = sub_emacs_time (now, timeval_to_EMACS_TIME (proc.ki_start));
db7b8d06 3253 attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs);
b91b7e4d 3254
5790543d 3255 len = sizeof fscale;
b91b7e4d
EW
3256 if (sysctlbyname ("kern.fscale", &fscale, &len, NULL, 0) == 0)
3257 {
5790543d 3258 double pcpu;
b91b7e4d 3259 fixpt_t ccpu;
5790543d 3260 len = sizeof ccpu;
b91b7e4d
EW
3261 if (sysctlbyname ("kern.ccpu", &ccpu, &len, NULL, 0) == 0)
3262 {
5790543d
PE
3263 pcpu = (100.0 * proc.ki_pctcpu / fscale
3264 / (1 - exp (proc.ki_swtime * log ((double) ccpu / fscale))));
3265 attrs = Fcons (Fcons (Qpcpu, make_fixnum_or_float (pcpu)), attrs);
b91b7e4d
EW
3266 }
3267 }
3268
5790543d 3269 len = sizeof npages;
b91b7e4d
EW
3270 if (sysctlbyname ("hw.availpages", &npages, &len, NULL, 0) == 0)
3271 {
5790543d
PE
3272 double pmem = (proc.ki_flag & P_INMEM
3273 ? 100.0 * proc.ki_rssize / npages
3274 : 0);
3275 attrs = Fcons (Fcons (Qpmem, make_fixnum_or_float (pmem)), attrs);
b91b7e4d
EW
3276 }
3277
3278 mib[2] = KERN_PROC_ARGS;
3279 len = MAXPATHLEN;
3280 if (sysctl (mib, 4, args, &len, NULL, 0) == 0)
3281 {
3282 int i;
3283 for (i = 0; i < len; i++)
3284 {
3285 if (! args[i] && i < len - 1)
3286 args[i] = ' ';
3287 }
3288
5790543d
PE
3289 decoded_comm =
3290 (code_convert_string_norecord
d7ea76b4 3291 (build_unibyte_string (args),
5790543d 3292 Vlocale_coding_system, 0));
b91b7e4d
EW
3293
3294 attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
3295 }
5790543d 3296
b91b7e4d
EW
3297 UNGCPRO;
3298 return attrs;
3299}
3300
f8d23104
DN
3301/* The WINDOWSNT implementation is in w32.c.
3302 The MSDOS implementation is in dosfns.c. */
c4605e09 3303#elif !defined (WINDOWSNT) && !defined (MSDOS)
06e111a6
DN
3304
3305Lisp_Object
3306system_process_attributes (Lisp_Object pid)
3307{
9dcbe89b 3308 return Qnil;
06e111a6
DN
3309}
3310
3311#endif /* !defined (WINDOWSNT) */