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