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