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