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