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