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