1 /* Interfaces to system-dependent kernel and library entries.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32 #endif /* HAVE_PWD_H */
35 #endif /* HAVE_LIMITS_H */
41 #endif /* HAVE_ALLOCA_H */
44 /* Including stdlib.h isn't necessarily enough to get srandom
45 declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2. */
47 /* The w32 build defines select stuff in w32.h, which is included by
48 sys/select.h (included below). */
50 #include "sysselect.h"
53 #include "blockinput.h"
57 #define write sys_write
62 #endif /* not WINDOWSNT */
64 /* Does anyone other than VMS need this? */
66 #define sys_fwrite fwrite
71 #include <sys/types.h>
76 #if !defined (USG) || defined (BSD_PGRPS)
78 #define setpgrp setpgid
82 /* Get SI_SRPC_DOMAIN, if it is available. */
83 #ifdef HAVE_SYS_SYSTEMINFO_H
84 #include <sys/systeminfo.h>
87 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
91 #include <sys/param.h>
95 extern unsigned start
__asm__ ("start");
105 #include <sys/file.h>
112 #include <sys/ioctl.h>
119 #include <sys/utsname.h>
123 extern int quit_char
;
125 #include "keyboard.h"
128 #include "termhooks.h"
129 #include "termchar.h"
130 #include "termopts.h"
131 #include "dispextern.h"
133 #include "cm.h" /* for reset_sys_modes */
135 /* For serial_configure and serial_open. */
136 extern Lisp_Object QCport
, QCspeed
, QCprocess
;
137 extern Lisp_Object QCbytesize
, QCstopbits
, QCparity
, Qodd
, Qeven
;
138 extern Lisp_Object QCflowcontrol
, Qhw
, Qsw
, QCsummary
;
142 /* In process.h which conflicts with the local copy. */
144 int _cdecl
_spawnlp (int, const char *, const char *, ...);
145 int _cdecl
_getpid (void);
146 extern char *getwd (char *);
149 #include "syssignal.h"
156 #ifndef HAVE_STRUCT_UTIMBUF
157 /* We want to use utime rather than utimes, but we couldn't find the
158 structure declaration. We'll use the traditional one. */
166 /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */
171 static const int baud_convert
[] =
173 0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
174 1800, 2400, 4800, 9600, 19200, 38400
180 #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
182 #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
190 void croak
P_ ((char *)) NO_RETURN
;
192 /* Temporary used by `sigblock' when defined in terms of signprocmask. */
194 SIGMASKTYPE sigprocmask_set
;
197 #if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
199 /* Return the current working directory. Returns NULL on errors.
200 Any other returned value must be freed with free. This is used
201 only when get_current_dir_name is not defined on the system. */
203 get_current_dir_name ()
207 struct stat dotstat
, pwdstat
;
208 /* If PWD is accurate, use it instead of calling getwd. PWD is
209 sometimes a nicer name, and using it may avoid a fatal error if a
210 parent directory is searchable but not readable. */
211 if ((pwd
= getenv ("PWD")) != 0
212 && (IS_DIRECTORY_SEP (*pwd
) || (*pwd
&& IS_DEVICE_SEP (pwd
[1])))
213 && stat (pwd
, &pwdstat
) == 0
214 && stat (".", &dotstat
) == 0
215 && dotstat
.st_ino
== pwdstat
.st_ino
216 && dotstat
.st_dev
== pwdstat
.st_dev
218 && strlen (pwd
) < MAXPATHLEN
222 buf
= (char *) malloc (strlen (pwd
) + 1);
230 size_t buf_size
= 1024;
231 buf
= (char *) malloc (buf_size
);
236 if (getcwd (buf
, buf_size
) == buf
)
240 int tmp_errno
= errno
;
246 buf
= (char *) realloc (buf
, buf_size
);
254 /* We need MAXPATHLEN here. */
255 buf
= (char *) malloc (MAXPATHLEN
+ 1);
258 if (getwd (buf
) == NULL
)
260 int tmp_errno
= errno
;
272 /* Discard pending input on all input descriptors. */
278 struct emacs_tty buf
;
283 #ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
284 while (dos_keyread () != -1)
286 #else /* not MSDOS */
288 struct tty_display_info
*tty
;
289 for (tty
= tty_list
; tty
; tty
= tty
->next
)
291 if (tty
->input
) /* Is the device suspended? */
293 EMACS_GET_TTY (fileno (tty
->input
), &buf
);
294 EMACS_SET_TTY (fileno (tty
->input
), &buf
, 0);
298 #endif /* not MSDOS */
299 #endif /* not WINDOWSNT */
305 /* Arrange for character C to be read as the next input from
307 XXX What if we have multiple ttys?
313 if (! FRAME_TERMCAP_P (SELECTED_FRAME ()))
316 /* Should perhaps error if in batch mode */
318 ioctl (fileno (CURTTY()->input
), TIOCSTI
, &c
);
319 #else /* no TIOCSTI */
320 error ("Cannot stuff terminal input characters in this version of Unix");
321 #endif /* no TIOCSTI */
327 init_baud_rate (int fd
)
335 #else /* not DOS_NT */
341 emacs_ospeed
= cfgetospeed (&sg
);
342 #else /* not TERMIOS */
350 ioctl (fd
, TCGETA
, &sg
);
352 emacs_ospeed
= sg
.c_cflag
& CBAUD
;
353 #else /* neither TERMIOS nor TERMIO */
356 sg
.sg_ospeed
= B9600
;
357 if (ioctl (fd
, TIOCGETP
, &sg
) < 0)
359 emacs_ospeed
= sg
.sg_ospeed
;
360 #endif /* not HAVE_TERMIO */
361 #endif /* not HAVE_TERMIOS */
362 #endif /* not DOS_NT */
365 baud_rate
= (emacs_ospeed
< sizeof baud_convert
/ sizeof baud_convert
[0]
366 ? baud_convert
[emacs_ospeed
] : 9600);
374 set_exclusive_use (fd
)
378 ioctl (fd
, FIOCLEX
, 0);
380 /* Ok to do nothing if this feature does not exist */
385 wait_without_blocking ()
388 wait3 (0, WNOHANG
| WUNTRACED
, 0);
390 croak ("wait_without_blocking");
392 synch_process_alive
= 0;
395 #endif /* not subprocesses */
397 int wait_debugging
; /* Set nonzero to make following function work under dbx
398 (at least for bsd). */
401 wait_for_termination_signal ()
404 /* Wait for subprocess with process id `pid' to terminate and
405 make sure it will get eliminated (not remain forever as a zombie) */
408 wait_for_termination (pid
)
414 #if defined (BSD_SYSTEM) || defined (HPUX)
415 /* Note that kill returns -1 even if the process is just a zombie now.
416 But inevitably a SIGCHLD interrupt should be generated
417 and child_sig will do wait3 and make the process go away. */
418 /* There is some indication that there is a bug involved with
419 termination of subprocesses, perhaps involving a kernel bug too,
420 but no idea what it is. Just as a hunch we signal SIGCHLD to see
421 if that causes the problem to go away or get worse. */
422 sigsetmask (sigmask (SIGCHLD
));
423 if (0 > kill (pid
, 0))
425 sigsetmask (SIGEMPTYMASK
);
426 kill (getpid (), SIGCHLD
);
432 sigpause (SIGEMPTYMASK
);
433 #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
434 #ifdef POSIX_SIGNALS /* would this work for GNU/Linux as well? */
437 /* XXX: can I replace this code without problems? --giuseppe
439 sigblock (sigmask (SIGCHLD));
441 if (kill (pid, 0) == -1 && errno == ESRCH)
443 sigunblock (sigmask (SIGCHLD));
447 sigsuspend (&empty_mask);
449 w
= waitpid (pid
, &status
, WUNTRACED
| WCONTINUED
);
450 if (w
== -1 || WIFEXITED (w
))
452 #else /* not POSIX_SIGNALS */
453 #ifdef HAVE_SYSV_SIGPAUSE
455 if (0 > kill (pid
, 0))
461 #else /* not HAVE_SYSV_SIGPAUSE */
465 #else /* not WINDOWSNT */
466 if (0 > kill (pid
, 0))
468 /* Using sleep instead of pause avoids timing error.
469 If the inferior dies just before the sleep,
470 we lose just one second. */
472 #endif /* not WINDOWSNT */
473 #endif /* not HAVE_SYSV_SIGPAUSE */
474 #endif /* not POSIX_SIGNALS */
475 #endif /* not BSD_SYSTEM, and not HPUX version >= 6 */
476 #else /* not subprocesses */
479 #else /* not __DJGPP__ > 1 */
480 if (kill (pid
, 0) < 0)
483 #endif /* not __DJGPP__ > 1*/
484 #endif /* not subprocesses */
491 * flush any pending output
492 * (may flush input as well; it does not matter the way we use it)
496 flush_pending_output (channel
)
500 /* If we try this, we get hit with SIGTTIN, because
501 the child's tty belongs to the child's pgrp. */
504 ioctl (channel
, TCFLSH
, 1);
508 /* 3rd arg should be ignored
509 but some 4.2 kernels actually want the address of an int
510 and nonzero means something different. */
511 ioctl (channel
, TIOCFLUSH
, &zero
);
517 /* Set up the terminal at the other end of a pseudo-terminal that
518 we will be controlling an inferior through.
519 It should not echo or do line-editing, since that is done
520 in Emacs. No padding needed for insertion into an Emacs buffer. */
523 child_setup_tty (out
)
529 EMACS_GET_TTY (out
, &s
);
531 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
532 s
.main
.c_oflag
|= OPOST
; /* Enable output postprocessing */
533 s
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL on output */
535 /* http://lists.gnu.org/archive/html/emacs-devel/2008-05/msg00406.html
536 Some versions of GNU Hurd do not have FFDLY? */
538 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
|FFDLY
);
539 /* No output delays */
541 s
.main
.c_oflag
&= ~(NLDLY
|CRDLY
|TABDLY
|BSDLY
|VTDLY
);
542 /* No output delays */
545 s
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
546 s
.main
.c_lflag
|= ISIG
; /* Enable signals */
548 s
.main
.c_iflag
&= ~IUCLC
; /* Disable downcasing on input. */
551 s
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
554 s
.main
.c_oflag
&= ~OLCUC
; /* Disable upcasing on output. */
556 s
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
557 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CSIZE
) | CS8
; /* Don't strip 8th bit */
558 s
.main
.c_lflag
|= ICANON
; /* Enable erase/kill and eof processing */
559 s
.main
.c_cc
[VEOF
] = 04; /* insure that EOF is Control-D */
560 s
.main
.c_cc
[VERASE
] = CDISABLE
; /* disable erase processing */
561 s
.main
.c_cc
[VKILL
] = CDISABLE
; /* disable kill processing */
564 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
567 #ifdef SIGNALS_VIA_CHARACTERS
568 /* the QUIT and INTR character are used in process_send_signal
569 so set them here to something useful. */
570 if (s
.main
.c_cc
[VQUIT
] == CDISABLE
)
571 s
.main
.c_cc
[VQUIT
] = '\\'&037; /* Control-\ */
572 if (s
.main
.c_cc
[VINTR
] == CDISABLE
)
573 s
.main
.c_cc
[VINTR
] = 'C'&037; /* Control-C */
574 #endif /* not SIGNALS_VIA_CHARACTERS */
577 /* AIX enhanced edit loses NULs, so disable it */
580 s
.main
.c_iflag
&= ~ASCEDIT
;
582 /* Also, PTY overloads NUL and BREAK.
583 don't ignore break, but don't signal either, so it looks like NUL. */
584 s
.main
.c_iflag
&= ~IGNBRK
;
585 s
.main
.c_iflag
&= ~BRKINT
;
586 /* rms: Formerly it set s.main.c_cc[VINTR] to 0377 here
587 unconditionally. Then a SIGNALS_VIA_CHARACTERS conditional
588 would force it to 0377. That looks like duplicated code. */
589 s
.main
.c_cc
[VEOL
] = CDISABLE
;
590 s
.main
.c_cflag
= (s
.main
.c_cflag
& ~CBAUD
) | B9600
; /* baud rate sanity */
593 #else /* not HAVE_TERMIO */
595 s
.main
.sg_flags
&= ~(ECHO
| CRMOD
| ANYP
| ALLDELAY
| RAW
| LCASE
597 s
.main
.sg_flags
|= LPASS8
;
598 s
.main
.sg_erase
= 0377;
599 s
.main
.sg_kill
= 0377;
600 s
.lmode
= LLITOUT
| s
.lmode
; /* Don't strip 8th bit */
602 #endif /* not HAVE_TERMIO */
604 EMACS_SET_TTY (out
, &s
, 0);
606 #endif /* not DOS_NT */
609 #endif /* subprocesses */
611 /* Record a signal code and the handler for it. */
615 SIGTYPE (*handler
) P_ ((int));
618 static void save_signal_handlers
P_ ((struct save_signal
*));
619 static void restore_signal_handlers
P_ ((struct save_signal
*));
621 /* Suspend the Emacs process; give terminal to its superior. */
626 #if defined (SIGTSTP) && !defined (MSDOS)
629 int pgrp
= EMACS_GETPGRP (0);
630 EMACS_KILLPG (pgrp
, SIGTSTP
);
633 #else /* No SIGTSTP */
634 /* On a system where suspending is not implemented,
635 instead fork a subshell and let it talk directly to the terminal
639 #endif /* no SIGTSTP */
642 /* Fork a subshell. */
647 #ifdef DOS_NT /* Demacs 1.1.2 91/10/20 Manabu Higashida */
649 char oldwd
[MAXPATHLEN
+1]; /* Fixed length is safe on MSDOS. */
652 struct save_signal saved_handlers
[5];
654 unsigned char *str
= 0;
657 saved_handlers
[0].code
= SIGINT
;
658 saved_handlers
[1].code
= SIGQUIT
;
659 saved_handlers
[2].code
= SIGTERM
;
661 saved_handlers
[3].code
= SIGIO
;
662 saved_handlers
[4].code
= 0;
664 saved_handlers
[3].code
= 0;
667 /* Mentioning current_buffer->buffer would mean including buffer.h,
668 which somehow wedges the hp compiler. So instead... */
670 dir
= intern ("default-directory");
671 if (NILP (Fboundp (dir
)))
673 dir
= Fsymbol_value (dir
);
677 dir
= expand_and_dir_to_file (Funhandled_file_name_directory (dir
), Qnil
);
678 str
= (unsigned char *) alloca (SCHARS (dir
) + 2);
680 bcopy (SDATA (dir
), str
, len
);
681 if (str
[len
- 1] != '/') str
[len
++] = '/';
688 save_signal_handlers (saved_handlers
);
689 synch_process_alive
= 1;
690 #endif /* __DJGPP__ > 1 */
694 error ("Can't spawn subshell");
701 #ifdef DOS_NT /* MW, Aug 1993 */
704 sh
= (char *) egetenv ("SUSPEND"); /* KFS, 1994-12-14 */
707 sh
= (char *) egetenv ("SHELL");
711 /* Use our buffer's default directory for the subshell. */
713 chdir ((char *) str
);
716 close_process_descs (); /* Close Emacs's pipes/ptys */
719 #ifdef SET_EMACS_PRIORITY
721 extern EMACS_INT emacs_priority
;
723 if (emacs_priority
< 0)
724 nice (-emacs_priority
);
728 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
730 char *epwd
= getenv ("PWD");
731 char old_pwd
[MAXPATHLEN
+1+4];
733 /* If PWD is set, pass it with corrected value. */
736 strcpy (old_pwd
, epwd
);
737 if (str
[len
- 1] == '/')
739 setenv ("PWD", str
, 1);
744 putenv (old_pwd
); /* restore previous value */
746 #else /* not MSDOS */
748 /* Waits for process completion */
749 pid
= _spawnlp (_P_WAIT
, sh
, sh
, NULL
);
752 write (1, "Can't execute subshell", 22);
753 #else /* not WINDOWSNT */
754 execlp (sh
, sh
, (char *) 0);
755 write (1, "Can't execute subshell", 22);
757 #endif /* not WINDOWSNT */
758 #endif /* not MSDOS */
761 /* Do this now if we did not do it before. */
762 #if !defined (MSDOS) || __DJGPP__ == 1
763 save_signal_handlers (saved_handlers
);
764 synch_process_alive
= 1;
768 wait_for_termination (pid
);
770 restore_signal_handlers (saved_handlers
);
771 synch_process_alive
= 0;
775 save_signal_handlers (saved_handlers
)
776 struct save_signal
*saved_handlers
;
778 while (saved_handlers
->code
)
780 saved_handlers
->handler
781 = (SIGTYPE (*) P_ ((int))) signal (saved_handlers
->code
, SIG_IGN
);
787 restore_signal_handlers (saved_handlers
)
788 struct save_signal
*saved_handlers
;
790 while (saved_handlers
->code
)
792 signal (saved_handlers
->code
, saved_handlers
->handler
);
798 /* If SIGIO is broken, don't do anything. */
815 unrequest_sigio (void)
822 int old_fcntl_flags
[MAXDESC
];
829 old_fcntl_flags
[fd
] = fcntl (fd
, F_GETFL
, 0) & ~FASYNC
;
830 fcntl (fd
, F_SETFL
, old_fcntl_flags
[fd
] | FASYNC
);
832 interrupts_deferred
= 0;
840 fcntl (fd
, F_SETFL
, old_fcntl_flags
[fd
]);
844 #ifdef FASYNC /* F_SETFL does not imply existence of FASYNC */
845 /* XXX Uhm, FASYNC is not used anymore here. */
846 /* XXX Yeah, but you need it for SIGIO, don't you? */
855 sigunblock (sigmask (SIGWINCH
));
857 sigunblock (sigmask (SIGIO
));
859 interrupts_deferred
= 0;
863 unrequest_sigio (void)
868 #if 0 /* XXX What's wrong with blocking SIGIO under X? */
874 sigblock (sigmask (SIGWINCH
));
876 sigblock (sigmask (SIGIO
));
877 interrupts_deferred
= 1;
880 #else /* no FASYNC */
886 if (noninteractive
|| read_socket_hook
)
889 croak ("request_sigio");
895 if (noninteractive
|| read_socket_hook
)
898 croak ("unrequest_sigio");
906 /* Saving and restoring the process group of Emacs's terminal. */
910 /* The process group of which Emacs was a member when it initially
913 If Emacs was in its own process group (i.e. inherited_pgroup ==
914 getpid ()), then we know we're running under a shell with job
915 control (Emacs would never be run as part of a pipeline).
918 If Emacs was not in its own process group, then we know we're
919 running under a shell (or a caller) that doesn't know how to
920 separate itself from Emacs (like sh). Emacs must be in its own
921 process group in order to receive SIGIO correctly. In this
922 situation, we put ourselves in our own pgroup, forcibly set the
923 tty's pgroup to our pgroup, and make sure to restore and reinstate
924 the tty's pgroup just like any other terminal setting. If
925 inherited_group was not the tty's pgroup, then we'll get a
926 SIGTTmumble when we try to change the tty's pgroup, and a CONT if
927 it goes foreground in the future, which is what should happen.
929 This variable is initialized in emacs.c. */
930 int inherited_pgroup
;
932 /* Split off the foreground process group to Emacs alone. When we are
933 in the foreground, but not started in our own process group,
934 redirect the tty device handle FD to point to our own process
935 group. We need to be in our own process group to receive SIGIO
938 narrow_foreground_group (int fd
)
942 setpgrp (0, inherited_pgroup
);
944 /* XXX inherited_pgroup should not be zero here, but GTK seems to
946 if (! inherited_pgroup
)
947 abort (); /* Should not happen. */
949 if (inherited_pgroup
!= me
)
950 EMACS_SET_TTY_PGRP (fd
, &me
); /* XXX This only works on the controlling tty. */
954 /* Set the tty to our original foreground group. */
956 widen_foreground_group (int fd
)
958 if (inherited_pgroup
!= getpid ())
959 EMACS_SET_TTY_PGRP (fd
, &inherited_pgroup
);
960 setpgrp (0, inherited_pgroup
);
963 #endif /* BSD_PGRPS */
965 /* Getting and setting emacs_tty structures. */
967 /* Set *TC to the parameters associated with the terminal FD.
968 Return zero if all's well, or -1 if we ran into an error we
969 couldn't deal with. */
971 emacs_get_tty (fd
, settings
)
973 struct emacs_tty
*settings
;
975 /* Retrieve the primary parameters - baud rate, character size, etcetera. */
977 /* We have those nifty POSIX tcmumbleattr functions. */
978 bzero (&settings
->main
, sizeof (settings
->main
));
979 if (tcgetattr (fd
, &settings
->main
) < 0)
984 /* The SYSV-style interface? */
985 if (ioctl (fd
, TCGETA
, &settings
->main
) < 0)
990 /* I give up - I hope you have the BSD ioctls. */
991 if (ioctl (fd
, TIOCGETP
, &settings
->main
) < 0)
993 #endif /* not DOS_NT */
997 /* Suivant - Do we have to get struct ltchars data? */
999 if (ioctl (fd
, TIOCGLTC
, &settings
->ltchars
) < 0)
1003 /* How about a struct tchars and a wordful of lmode bits? */
1005 if (ioctl (fd
, TIOCGETC
, &settings
->tchars
) < 0
1006 || ioctl (fd
, TIOCLGET
, &settings
->lmode
) < 0)
1010 /* We have survived the tempest. */
1015 /* Set the parameters of the tty on FD according to the contents of
1016 *SETTINGS. If FLUSHP is non-zero, we discard input.
1017 Return 0 if all went well, and -1 if anything failed. */
1020 emacs_set_tty (fd
, settings
, flushp
)
1022 struct emacs_tty
*settings
;
1025 /* Set the primary parameters - baud rate, character size, etcetera. */
1028 /* We have those nifty POSIX tcmumbleattr functions.
1029 William J. Smith <wjs@wiis.wang.com> writes:
1030 "POSIX 1003.1 defines tcsetattr to return success if it was
1031 able to perform any of the requested actions, even if some
1032 of the requested actions could not be performed.
1033 We must read settings back to ensure tty setup properly.
1034 AIX requires this to keep tty from hanging occasionally." */
1035 /* This make sure that we don't loop indefinitely in here. */
1036 for (i
= 0 ; i
< 10 ; i
++)
1037 if (tcsetattr (fd
, flushp
? TCSAFLUSH
: TCSADRAIN
, &settings
->main
) < 0)
1048 bzero (&new, sizeof (new));
1049 /* Get the current settings, and see if they're what we asked for. */
1050 tcgetattr (fd
, &new);
1051 /* We cannot use memcmp on the whole structure here because under
1052 * aix386 the termios structure has some reserved field that may
1055 if ( new.c_iflag
== settings
->main
.c_iflag
1056 && new.c_oflag
== settings
->main
.c_oflag
1057 && new.c_cflag
== settings
->main
.c_cflag
1058 && new.c_lflag
== settings
->main
.c_lflag
1059 && memcmp (new.c_cc
, settings
->main
.c_cc
, NCCS
) == 0)
1067 /* The SYSV-style interface? */
1068 if (ioctl (fd
, flushp
? TCSETAF
: TCSETAW
, &settings
->main
) < 0)
1073 /* I give up - I hope you have the BSD ioctls. */
1074 if (ioctl (fd
, (flushp
) ? TIOCSETP
: TIOCSETN
, &settings
->main
) < 0)
1076 #endif /* not DOS_NT */
1081 /* Suivant - Do we have to get struct ltchars data? */
1083 if (ioctl (fd
, TIOCSLTC
, &settings
->ltchars
) < 0)
1087 /* How about a struct tchars and a wordful of lmode bits? */
1089 if (ioctl (fd
, TIOCSETC
, &settings
->tchars
) < 0
1090 || ioctl (fd
, TIOCLSET
, &settings
->lmode
) < 0)
1094 /* We have survived the tempest. */
1101 int old_fcntl_owner
[MAXDESC
];
1102 #endif /* F_SETOWN */
1104 /* This may also be defined in stdio,
1105 but if so, this does no harm,
1106 and using the same name avoids wasting the other one's space. */
1109 unsigned char _sobuf
[BUFSIZ
+8];
1111 char _sobuf
[BUFSIZ
];
1115 static struct ltchars new_ltchars
= {-1,-1,-1,-1,-1,-1};
1118 static struct tchars new_tchars
= {-1,-1,-1,-1,-1,-1};
1121 /* Initialize the terminal mode on all tty devices that are currently
1125 init_all_sys_modes (void)
1127 struct tty_display_info
*tty
;
1128 for (tty
= tty_list
; tty
; tty
= tty
->next
)
1129 init_sys_modes (tty
);
1132 /* Initialize the terminal mode on the given tty device. */
1135 init_sys_modes (tty_out
)
1136 struct tty_display_info
*tty_out
;
1138 struct emacs_tty tty
;
1140 Vtty_erase_char
= Qnil
;
1145 if (!tty_out
->output
)
1146 return; /* The tty is suspended. */
1150 /* read_socket_hook is not global anymore. I think doing this
1151 unconditionally will not cause any problems. */
1152 if (! read_socket_hook
&& EQ (Vinitial_window_system
, Qnil
))
1154 narrow_foreground_group (fileno (tty_out
->input
));
1157 if (! tty_out
->old_tty
)
1158 tty_out
->old_tty
= (struct emacs_tty
*) xmalloc (sizeof (struct emacs_tty
));
1160 EMACS_GET_TTY (fileno (tty_out
->input
), tty_out
->old_tty
);
1162 tty
= *tty_out
->old_tty
;
1164 #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
1165 XSETINT (Vtty_erase_char
, tty
.main
.c_cc
[VERASE
]);
1167 tty
.main
.c_iflag
|= (IGNBRK
); /* Ignore break condition */
1168 tty
.main
.c_iflag
&= ~ICRNL
; /* Disable map of CR to NL on input */
1169 #ifdef INLCR /* I'm just being cautious,
1170 since I can't check how widespread INLCR is--rms. */
1171 tty
.main
.c_iflag
&= ~INLCR
; /* Disable map of NL to CR on input */
1174 tty
.main
.c_iflag
&= ~ISTRIP
; /* don't strip 8th bit on input */
1176 tty
.main
.c_lflag
&= ~ECHO
; /* Disable echo */
1177 tty
.main
.c_lflag
&= ~ICANON
; /* Disable erase/kill processing */
1179 tty
.main
.c_lflag
&= ~IEXTEN
; /* Disable other editing characters. */
1181 tty
.main
.c_lflag
|= ISIG
; /* Enable signals */
1182 if (tty_out
->flow_control
)
1184 tty
.main
.c_iflag
|= IXON
; /* Enable start/stop output control */
1186 tty
.main
.c_iflag
&= ~IXANY
;
1190 tty
.main
.c_iflag
&= ~IXON
; /* Disable start/stop output control */
1191 tty
.main
.c_oflag
&= ~ONLCR
; /* Disable map of NL to CR-NL
1193 tty
.main
.c_oflag
&= ~TAB3
; /* Disable tab expansion */
1195 if (tty_out
->meta_key
)
1197 tty
.main
.c_cflag
|= CS8
; /* allow 8th bit on input */
1198 tty
.main
.c_cflag
&= ~PARENB
;/* Don't check parity */
1201 if (tty_out
->input
== stdin
)
1203 tty
.main
.c_cc
[VINTR
] = quit_char
; /* C-g (usually) gives SIGINT */
1204 /* Set up C-g for both SIGQUIT and SIGINT.
1205 We don't know which we will get, but we handle both alike
1206 so which one it really gives us does not matter. */
1207 tty
.main
.c_cc
[VQUIT
] = quit_char
;
1211 /* We normally don't get interrupt or quit signals from tty
1212 devices other than our controlling terminal; therefore,
1213 we must handle C-g as normal input. Unfortunately, this
1214 means that the interrupt and quit feature must be
1215 disabled on secondary ttys, or we would not even see the
1218 Note that even though emacsclient could have special code
1219 to pass SIGINT to Emacs, we should _not_ enable
1220 interrupt/quit keys for emacsclient frames. This means
1221 that we can't break out of loops in C code from a
1222 secondary tty frame, but we can always decide what
1223 display the C-g came from, which is more important from a
1224 usability point of view. (Consider the case when two
1225 people work together using the same Emacs instance.) */
1226 tty
.main
.c_cc
[VINTR
] = CDISABLE
;
1227 tty
.main
.c_cc
[VQUIT
] = CDISABLE
;
1229 tty
.main
.c_cc
[VMIN
] = 1; /* Input should wait for at least 1 char */
1230 tty
.main
.c_cc
[VTIME
] = 0; /* no matter how long that takes. */
1232 tty
.main
.c_cc
[VSWTCH
] = CDISABLE
; /* Turn off shell layering use
1236 #if defined (__mips__) || defined (HAVE_TCATTR)
1238 tty
.main
.c_cc
[VSUSP
] = CDISABLE
; /* Turn off mips handling of C-z. */
1241 tty
.main
.c_cc
[V_DSUSP
] = CDISABLE
; /* Turn off mips handling of C-y. */
1242 #endif /* V_DSUSP */
1243 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
1244 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1247 tty
.main
.c_cc
[VLNEXT
] = CDISABLE
;
1250 tty
.main
.c_cc
[VREPRINT
] = CDISABLE
;
1251 #endif /* VREPRINT */
1253 tty
.main
.c_cc
[VWERASE
] = CDISABLE
;
1254 #endif /* VWERASE */
1256 tty
.main
.c_cc
[VDISCARD
] = CDISABLE
;
1257 #endif /* VDISCARD */
1259 if (tty_out
->flow_control
)
1262 tty
.main
.c_cc
[VSTART
] = '\021';
1265 tty
.main
.c_cc
[VSTOP
] = '\023';
1271 tty
.main
.c_cc
[VSTART
] = CDISABLE
;
1274 tty
.main
.c_cc
[VSTOP
] = CDISABLE
;
1277 #endif /* mips or HAVE_TCATTR */
1281 /* AIX enhanced edit loses NULs, so disable it. */
1282 tty
.main
.c_line
= 0;
1283 tty
.main
.c_iflag
&= ~ASCEDIT
;
1285 tty
.main
.c_cc
[VSTRT
] = CDISABLE
;
1286 tty
.main
.c_cc
[VSTOP
] = CDISABLE
;
1287 tty
.main
.c_cc
[VSUSP
] = CDISABLE
;
1288 tty
.main
.c_cc
[VDSUSP
] = CDISABLE
;
1289 #endif /* IBMR2AIX */
1290 if (tty_out
->flow_control
)
1293 tty
.main
.c_cc
[VSTART
] = '\021';
1296 tty
.main
.c_cc
[VSTOP
] = '\023';
1299 /* Also, PTY overloads NUL and BREAK.
1300 don't ignore break, but don't signal either, so it looks like NUL.
1301 This really serves a purpose only if running in an XTERM window
1302 or via TELNET or the like, but does no harm elsewhere. */
1303 tty
.main
.c_iflag
&= ~IGNBRK
;
1304 tty
.main
.c_iflag
&= ~BRKINT
;
1306 #else /* if not HAVE_TERMIO */
1308 XSETINT (Vtty_erase_char
, tty
.main
.sg_erase
);
1309 tty
.main
.sg_flags
&= ~(ECHO
| CRMOD
| XTABS
);
1311 tty
.main
.sg_flags
|= ANYP
;
1312 tty
.main
.sg_flags
|= interrupt_input
? RAW
: CBREAK
;
1313 #endif /* not DOS_NT */
1314 #endif /* not HAVE_TERMIO */
1316 /* If going to use CBREAK mode, we must request C-g to interrupt
1317 and turn off start and stop chars, etc. If not going to use
1318 CBREAK mode, do this anyway so as to turn off local flow
1319 control for user coming over network on 4.2; in this case,
1320 only t_stopc and t_startc really matter. */
1323 /* Note: if not using CBREAK mode, it makes no difference how we
1325 tty
.tchars
= new_tchars
;
1326 tty
.tchars
.t_intrc
= quit_char
;
1327 if (tty_out
->flow_control
)
1329 tty
.tchars
.t_startc
= '\021';
1330 tty
.tchars
.t_stopc
= '\023';
1333 tty
.lmode
= LDECCTQ
| LLITOUT
| LPASS8
| LNOFLSH
| tty_out
->old_tty
.lmode
;
1335 #endif /* HAVE_TCHARS */
1336 #endif /* not HAVE_TERMIO */
1339 tty
.ltchars
= new_ltchars
;
1340 #endif /* HAVE_LTCHARS */
1341 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
1342 if (!tty_out
->term_initted
)
1343 internal_terminal_init ();
1344 dos_ttraw (tty_out
);
1347 EMACS_SET_TTY (fileno (tty_out
->input
), &tty
, 0);
1349 /* This code added to insure that, if flow-control is not to be used,
1350 we have an unlocked terminal at the start. */
1353 if (!tty_out
->flow_control
) ioctl (fileno (tty_out
->input
), TCXONC
, 1);
1356 if (!tty_out
->flow_control
) ioctl (fileno (tty_out
->input
), TIOCSTART
, 0);
1359 #if defined (HAVE_TERMIOS) || defined (HPUX)
1361 if (!tty_out
->flow_control
) tcflow (fileno (tty_out
->input
), TCOON
);
1366 #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */
1367 if (interrupt_input
)
1369 old_fcntl_owner
[fileno (tty_out
->input
)] =
1370 fcntl (fileno (tty_out
->input
), F_GETOWN
, 0);
1371 fcntl (fileno (tty_out
->input
), F_SETOWN
, getpid ());
1372 init_sigio (fileno (tty_out
->input
));
1374 if (gpm_tty
== tty_out
)
1376 /* Arrange for mouse events to give us SIGIO signals. */
1377 fcntl (gpm_fd
, F_SETOWN
, getpid ());
1378 fcntl (gpm_fd
, F_SETFL
, fcntl (gpm_fd
, F_GETFL
, 0) | O_NONBLOCK
);
1379 init_sigio (gpm_fd
);
1381 #endif /* HAVE_GPM */
1383 #endif /* F_GETOWN */
1384 #endif /* F_SETFL */
1387 /* This symbol is defined on recent USG systems.
1388 Someone says without this call USG won't really buffer the file
1389 even with a call to setbuf. */
1390 setvbuf (tty_out
->output
, (char *) _sobuf
, _IOFBF
, sizeof _sobuf
);
1392 setbuf (tty_out
->output
, (char *) _sobuf
);
1395 if (tty_out
->terminal
->set_terminal_modes_hook
)
1396 tty_out
->terminal
->set_terminal_modes_hook (tty_out
->terminal
);
1398 if (!tty_out
->term_initted
)
1400 Lisp_Object tail
, frame
;
1401 FOR_EACH_FRAME (tail
, frame
)
1403 /* XXX This needs to be revised. */
1404 if (FRAME_TERMCAP_P (XFRAME (frame
))
1405 && FRAME_TTY (XFRAME (frame
)) == tty_out
)
1406 init_frame_faces (XFRAME (frame
));
1410 if (tty_out
->term_initted
&& no_redraw_on_reenter
)
1412 /* XXX This seems wrong on multi-tty. */
1413 if (display_completed
)
1414 direct_output_forward_char (0);
1418 Lisp_Object tail
, frame
;
1420 FOR_EACH_FRAME (tail
, frame
)
1422 if ((FRAME_TERMCAP_P (XFRAME (frame
))
1423 || FRAME_MSDOS_P (XFRAME (frame
)))
1424 && FRAME_TTY (XFRAME (frame
)) == tty_out
)
1425 FRAME_GARBAGED_P (XFRAME (frame
)) = 1;
1429 tty_out
->term_initted
= 1;
1432 /* Return nonzero if safe to use tabs in output.
1433 At the time this is called, init_sys_modes has not been done yet. */
1436 tabs_safe_p (int fd
)
1438 struct emacs_tty etty
;
1440 EMACS_GET_TTY (fd
, &etty
);
1441 return EMACS_TTY_TABS_OK (&etty
);
1444 /* Get terminal size from system.
1445 Store number of lines into *HEIGHTP and width into *WIDTHP.
1446 We store 0 if there's no valid information. */
1449 get_tty_size (int fd
, int *widthp
, int *heightp
)
1455 struct winsize size
;
1457 if (ioctl (fd
, TIOCGWINSZ
, &size
) == -1)
1458 *widthp
= *heightp
= 0;
1461 *widthp
= size
.ws_col
;
1462 *heightp
= size
.ws_row
;
1468 /* SunOS - style. */
1469 struct ttysize size
;
1471 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1472 *widthp
= *heightp
= 0;
1475 *widthp
= size
.ts_cols
;
1476 *heightp
= size
.ts_lines
;
1481 *widthp
= ScreenCols ();
1482 *heightp
= ScreenRows ();
1483 #else /* system doesn't know size */
1487 #endif /* not SunOS-style */
1488 #endif /* not BSD-style */
1491 /* Set the logical window size associated with descriptor FD
1492 to HEIGHT and WIDTH. This is used mainly with ptys. */
1495 set_window_size (fd
, height
, width
)
1496 int fd
, height
, width
;
1501 struct winsize size
;
1502 size
.ws_row
= height
;
1503 size
.ws_col
= width
;
1505 if (ioctl (fd
, TIOCSWINSZ
, &size
) == -1)
1506 return 0; /* error */
1513 /* SunOS - style. */
1514 struct ttysize size
;
1515 size
.ts_lines
= height
;
1516 size
.ts_cols
= width
;
1518 if (ioctl (fd
, TIOCGSIZE
, &size
) == -1)
1524 #endif /* not SunOS-style */
1525 #endif /* not BSD-style */
1530 /* Prepare all terminal devices for exiting Emacs. */
1533 reset_all_sys_modes (void)
1535 struct tty_display_info
*tty
;
1536 for (tty
= tty_list
; tty
; tty
= tty
->next
)
1537 reset_sys_modes (tty
);
1540 /* Prepare the terminal for closing it; move the cursor to the
1541 bottom of the frame, turn off interrupt-driven I/O, etc. */
1544 reset_sys_modes (tty_out
)
1545 struct tty_display_info
*tty_out
;
1552 if (!tty_out
->term_initted
)
1555 if (!tty_out
->output
)
1556 return; /* The tty is suspended. */
1558 /* Go to and clear the last line of the terminal. */
1560 cmgoto (tty_out
, FrameRows (tty_out
) - 1, 0);
1562 /* Code adapted from tty_clear_end_of_line. */
1563 if (tty_out
->TS_clr_line
)
1565 emacs_tputs (tty_out
, tty_out
->TS_clr_line
, 1, cmputc
);
1568 { /* have to do it the hard way */
1570 tty_turn_off_insert (tty_out
);
1572 for (i
= curX (tty_out
); i
< FrameCols (tty_out
) - 1; i
++)
1574 fputc (' ', tty_out
->output
);
1578 cmgoto (tty_out
, FrameRows (tty_out
) - 1, 0);
1579 fflush (tty_out
->output
);
1581 if (tty_out
->terminal
->reset_terminal_modes_hook
)
1582 tty_out
->terminal
->reset_terminal_modes_hook (tty_out
->terminal
);
1585 /* Avoid possible loss of output when changing terminal modes. */
1586 fsync (fileno (tty_out
->output
));
1590 #ifdef F_SETOWN /* F_SETFL does not imply existence of F_SETOWN */
1591 if (interrupt_input
)
1593 reset_sigio (fileno (tty_out
->input
));
1594 fcntl (fileno (tty_out
->input
), F_SETOWN
,
1595 old_fcntl_owner
[fileno (tty_out
->input
)]);
1597 #endif /* F_SETOWN */
1599 fcntl (fileno (tty_out
->input
), F_SETFL
,
1600 fcntl (fileno (tty_out
->input
), F_GETFL
, 0) & ~O_NDELAY
);
1602 #endif /* F_SETFL */
1604 if (tty_out
->old_tty
)
1605 while (EMACS_SET_TTY (fileno (tty_out
->input
),
1606 tty_out
->old_tty
, 0) < 0 && errno
== EINTR
)
1609 #ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */
1614 widen_foreground_group (fileno (tty_out
->input
));
1620 /* Set up the proper status flags for use of a pty. */
1626 /* I'm told that TOICREMOTE does not mean control chars
1627 "can't be sent" but rather that they don't have
1628 input-editing or signaling effects.
1629 That should be good, because we have other ways
1630 to do those things in Emacs.
1631 However, telnet mode seems not to work on 4.2.
1632 So TIOCREMOTE is turned off now. */
1634 /* Under hp-ux, if TIOCREMOTE is turned on, some calls
1635 will hang. In particular, the "timeout" feature (which
1636 causes a read to return if there is no data available)
1637 does this. Also it is known that telnet mode will hang
1638 in such a way that Emacs must be stopped (perhaps this
1639 is the same problem).
1641 If TIOCREMOTE is turned off, then there is a bug in
1642 hp-ux which sometimes loses data. Apparently the
1643 code which blocks the master process when the internal
1644 buffer fills up does not work. Other than this,
1645 though, everything else seems to work fine.
1647 Since the latter lossage is more benign, we may as well
1648 lose that way. -- cph */
1650 #if defined(UNIX98_PTYS)
1653 ioctl (fd
, FIONBIO
, &on
);
1658 #endif /* HAVE_PTYS */
1660 #if !defined(CANNOT_DUMP) || !defined(SYSTEM_MALLOC)
1661 /* Some systems that cannot dump also cannot implement these. */
1664 * Return the address of the start of the text segment prior to
1665 * doing an unexec. After unexec the return value is undefined.
1666 * See crt0.c for further explanation and _start.
1670 #if !(defined (__NetBSD__) && defined (__ELF__))
1671 #ifndef HAVE_TEXT_START
1676 return ((char *) TEXT_START
);
1678 extern int _start ();
1679 return ((char *) _start
);
1680 #endif /* TEXT_START */
1682 #endif /* not HAVE_TEXT_START */
1686 * Return the address of the start of the data segment prior to
1687 * doing an unexec. After unexec the return value is undefined.
1688 * See crt0.c for further information and definition of data_start.
1690 * Apparently, on BSD systems this is etext at startup. On
1691 * USG systems (swapping) this is highly mmu dependent and
1692 * is also dependent on whether or not the program is running
1693 * with shared text. Generally there is a (possibly large)
1694 * gap between end of text and start of data with shared text.
1696 * On Uniplus+ systems with shared text, data starts at a
1697 * fixed address. Each port (from a given oem) is generally
1698 * different, and the specific value of the start of data can
1699 * be obtained via the UniPlus+ specific "uvar" system call,
1700 * however the method outlined in crt0.c seems to be more portable.
1702 * Probably what will have to happen when a USG unexec is available,
1703 * at least on UniPlus, is temacs will have to be made unshared so
1704 * that text and data are contiguous. Then once loadup is complete,
1705 * unexec will produce a shared executable where the data can be
1706 * at the normal shared text boundary and the startofdata variable
1707 * will be patched by unexec to the correct value.
1711 #ifndef start_of_data
1716 return ((char *) DATA_START
);
1718 #ifdef ORDINARY_LINK
1720 * This is a hack. Since we're not linking crt0.c or pre_crt0.c,
1721 * data_start isn't defined. We take the address of environ, which
1722 * is known to live at or near the start of the system crt0.c, and
1723 * we don't sweat the handful of bytes that might lose.
1725 extern char **environ
;
1727 return ((char *) &environ
);
1729 extern int data_start
;
1730 return ((char *) &data_start
);
1731 #endif /* ORDINARY_LINK */
1732 #endif /* DATA_START */
1734 #endif /* start_of_data */
1735 #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
1737 /* init_system_name sets up the string for the Lisp function
1738 system-name to return. */
1740 extern Lisp_Object impl_Vsystem_name
;
1743 #include <sys/socket.h>
1745 #endif /* HAVE_SOCKETS */
1748 #ifndef HAVE_H_ERRNO
1751 #endif /* TRY_AGAIN */
1756 #ifndef HAVE_GETHOSTNAME
1759 Vsystem_name
= build_string (uts
.nodename
);
1760 #else /* HAVE_GETHOSTNAME */
1761 unsigned int hostname_size
= 256;
1762 char *hostname
= (char *) alloca (hostname_size
);
1764 /* Try to get the host name; if the buffer is too short, try
1765 again. Apparently, the only indication gethostname gives of
1766 whether the buffer was large enough is the presence or absence
1767 of a '\0' in the string. Eech. */
1770 gethostname (hostname
, hostname_size
- 1);
1771 hostname
[hostname_size
- 1] = '\0';
1773 /* Was the buffer large enough for the '\0'? */
1774 if (strlen (hostname
) < hostname_size
- 1)
1777 hostname_size
<<= 1;
1778 hostname
= (char *) alloca (hostname_size
);
1781 /* Turn the hostname into the official, fully-qualified hostname.
1782 Don't do this if we're going to dump; this can confuse system
1783 libraries on some machines and make the dumped emacs core dump. */
1786 #endif /* not CANNOT_DUMP */
1787 if (! index (hostname
, '.'))
1790 #ifdef HAVE_GETADDRINFO
1791 struct addrinfo
*res
;
1792 struct addrinfo hints
;
1795 memset (&hints
, 0, sizeof(hints
));
1796 hints
.ai_socktype
= SOCK_STREAM
;
1797 hints
.ai_flags
= AI_CANONNAME
;
1799 for (count
= 0;; count
++)
1801 if ((ret
= getaddrinfo (hostname
, NULL
, &hints
, &res
)) == 0
1802 || ret
!= EAI_AGAIN
)
1807 Fsleep_for (make_number (1), Qnil
);
1812 struct addrinfo
*it
= res
;
1815 char *fqdn
= it
->ai_canonname
;
1816 if (fqdn
&& index (fqdn
, '.')
1817 && strcmp (fqdn
, "localhost.localdomain") != 0)
1823 hostname
= alloca (strlen (it
->ai_canonname
) + 1);
1824 strcpy (hostname
, it
->ai_canonname
);
1828 #else /* !HAVE_GETADDRINFO */
1830 for (count
= 0;; count
++)
1836 hp
= gethostbyname (hostname
);
1838 if (! (hp
== 0 && h_errno
== TRY_AGAIN
))
1845 Fsleep_for (make_number (1), Qnil
);
1850 char *fqdn
= (char *) hp
->h_name
;
1852 if (!index (fqdn
, '.'))
1854 /* We still don't have a fully qualified domain name.
1855 Try to find one in the list of alternate names */
1856 char **alias
= hp
->h_aliases
;
1858 && (!index (*alias
, '.')
1859 || !strcmp (*alias
, "localhost.localdomain")))
1866 #endif /* !HAVE_GETADDRINFO */
1868 #endif /* HAVE_SOCKETS */
1869 Vsystem_name
= build_string (hostname
);
1870 #endif /* HAVE_GETHOSTNAME */
1873 for (p
= SDATA (Vsystem_name
); *p
; p
++)
1874 if (*p
== ' ' || *p
== '\t')
1880 #if !defined (HAVE_SELECT)
1882 #include "sysselect.h"
1885 #if defined (HAVE_X_WINDOWS) && !defined (HAVE_SELECT)
1886 /* Cause explanatory error message at compile time,
1887 since the select emulation is not good enough for X. */
1888 int *x
= &x_windows_lose_if_no_select_system_call
;
1891 /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
1892 * Only checks read descriptors.
1894 /* How long to wait between checking fds in select */
1895 #define SELECT_PAUSE 1
1898 /* For longjmp'ing back to read_input_waiting. */
1900 jmp_buf read_alarm_throw
;
1902 /* Nonzero if the alarm signal should throw back to read_input_waiting.
1903 The read_socket_hook function sets this to 1 while it is waiting. */
1905 int read_alarm_should_throw
;
1911 signal (SIGALRM
, SIG_IGN
);
1912 SIGNAL_THREAD_CHECK (SIGALRM
);
1913 if (read_alarm_should_throw
)
1914 longjmp (read_alarm_throw
, 1);
1918 /* Only rfds are checked. */
1920 sys_select (nfds
, rfds
, wfds
, efds
, timeout
)
1922 SELECT_TYPE
*rfds
, *wfds
, *efds
;
1923 EMACS_TIME
*timeout
;
1925 /* XXX This needs to be updated for multi-tty support. Is there
1926 anybody who needs to emulate select these days? */
1931 extern int proc_buffered_char
[];
1932 #ifndef subprocesses
1933 int process_tick
= 0, update_tick
= 0;
1935 extern int process_tick
, update_tick
;
1939 #if defined (HAVE_SELECT) && defined (HAVE_X_WINDOWS)
1940 /* If we're using X, then the native select will work; we only need the
1941 emulation for non-X usage. */
1942 if (!NILP (Vinitial_window_system
))
1943 return select (nfds
, rfds
, wfds
, efds
, timeout
);
1945 timeoutval
= timeout
? EMACS_SECS (*timeout
) : 100000;
1946 local_timeout
= &timeoutval
;
1958 /* If we are looking only for the terminal, with no timeout,
1959 just read it and wait -- that's more efficient. */
1960 if (*local_timeout
== 100000 && process_tick
== update_tick
1961 && FD_ISSET (0, &orfds
))
1964 for (fd
= 1; fd
< nfds
; ++fd
)
1965 if (FD_ISSET (fd
, &orfds
))
1967 if (! detect_input_pending ())
1968 read_input_waiting ();
1974 /* Once a second, till the timer expires, check all the flagged read
1975 * descriptors to see if any input is available. If there is some then
1976 * set the corresponding bit in the return copy of rfds.
1980 register int to_check
, fd
;
1984 for (to_check
= nfds
, fd
= 0; --to_check
>= 0; fd
++)
1986 if (FD_ISSET (fd
, &orfds
))
1988 int avail
= 0, status
= 0;
1991 avail
= detect_input_pending (); /* Special keyboard handler */
1995 status
= ioctl (fd
, FIONREAD
, &avail
);
1996 #else /* no FIONREAD */
1997 /* Hoping it will return -1 if nothing available
1998 or 0 if all 0 chars requested are read. */
1999 if (proc_buffered_char
[fd
] >= 0)
2003 avail
= read (fd
, &buf
, 1);
2005 proc_buffered_char
[fd
] = buf
;
2007 #endif /* no FIONREAD */
2009 if (status
>= 0 && avail
> 0)
2017 if (*local_timeout
== 0 || ravail
!= 0 || process_tick
!= update_tick
)
2020 turn_on_atimers (0);
2021 signal (SIGALRM
, select_alarm
);
2023 alarm (SELECT_PAUSE
);
2025 /* Wait for a SIGALRM (or maybe a SIGTINT) */
2026 while (select_alarmed
== 0 && *local_timeout
!= 0
2027 && process_tick
== update_tick
)
2029 /* If we are interested in terminal input,
2030 wait by reading the terminal.
2031 That makes instant wakeup for terminal input at least. */
2032 if (FD_ISSET (0, &orfds
))
2034 read_input_waiting ();
2035 if (detect_input_pending ())
2041 (*local_timeout
) -= SELECT_PAUSE
;
2043 /* Reset the old alarm if there was one. */
2044 turn_on_atimers (1);
2046 if (*local_timeout
== 0) /* Stop on timer being cleared */
2051 #endif /* not WINDOWSNT */
2053 /* Read keyboard input into the standard buffer,
2054 waiting for at least one character. */
2057 read_input_waiting ()
2059 /* XXX This needs to be updated for multi-tty support. Is there
2060 anybody who needs to emulate select these days? */
2062 extern int quit_char
;
2064 if (read_socket_hook
)
2066 struct input_event hold_quit
;
2068 EVENT_INIT (hold_quit
);
2069 hold_quit
.kind
= NO_EVENT
;
2071 read_alarm_should_throw
= 0;
2072 if (! setjmp (read_alarm_throw
))
2073 nread
= (*read_socket_hook
) (0, 1, &hold_quit
);
2077 if (hold_quit
.kind
!= NO_EVENT
)
2078 kbd_buffer_store_event (&hold_quit
);
2082 struct input_event e
;
2084 nread
= read (fileno (stdin
), buf
, 1);
2087 /* Scan the chars for C-g and store them in kbd_buffer. */
2088 e
.kind
= ASCII_KEYSTROKE_EVENT
;
2089 e
.frame_or_window
= selected_frame
;
2091 for (i
= 0; i
< nread
; i
++)
2093 /* Convert chars > 0177 to meta events if desired.
2094 We do this under the same conditions that read_avail_input does. */
2095 if (read_socket_hook
== 0)
2097 /* If the user says she has a meta key, then believe her. */
2098 if (meta_key
== 1 && (buf
[i
] & 0x80))
2099 e
.modifiers
= meta_modifier
;
2104 XSETINT (e
.code
, buf
[i
]);
2105 kbd_buffer_store_event (&e
);
2106 /* Don't look at input that follows a C-g too closely.
2107 This reduces lossage due to autorepeat on C-g. */
2108 if (buf
[i
] == quit_char
)
2114 #if !defined (HAVE_SELECT)
2115 #define select sys_select
2118 #endif /* not HAVE_SELECT */
2119 #endif /* not MSDOS */
2121 /* POSIX signals support - DJB */
2122 /* Anyone with POSIX signals should have ANSI C declarations */
2124 #ifdef POSIX_SIGNALS
2126 sigset_t empty_mask
, full_mask
;
2129 sys_signal (int signal_number
, signal_handler_t action
)
2131 struct sigaction new_action
, old_action
;
2132 sigemptyset (&new_action
.sa_mask
);
2133 new_action
.sa_handler
= action
;
2134 new_action
.sa_flags
= 0;
2135 #if defined (SA_RESTART)
2136 /* Emacs mostly works better with restartable system services. If this
2137 flag exists, we probably want to turn it on here.
2138 However, on some systems this resets the timeout of `select'
2139 which means that `select' never finishes if it keeps getting signals.
2140 BROKEN_SA_RESTART is defined on those systems. */
2141 /* It's not clear why the comment above says "mostly works better". --Stef
2142 When SYNC_INPUT is set, we don't want SA_RESTART because we need to poll
2143 for pending input so we need long-running syscalls to be interrupted
2144 after a signal that sets the interrupt_input_pending flag. */
2145 /* Non-interactive keyboard input goes through stdio, where we always
2146 want restartable system calls. */
2147 # if defined (BROKEN_SA_RESTART) || defined(SYNC_INPUT)
2150 new_action
.sa_flags
= SA_RESTART
;
2152 sigaction (signal_number
, &new_action
, &old_action
);
2153 return (old_action
.sa_handler
);
2157 /* If we're compiling with GCC, we don't need this function, since it
2158 can be written as a macro. */
2160 sys_sigmask (int sig
)
2163 sigemptyset (&mask
);
2164 sigaddset (&mask
, sig
);
2169 /* I'd like to have these guys return pointers to the mask storage in here,
2170 but there'd be trouble if the code was saving multiple masks. I'll be
2171 safe and pass the structure. It normally won't be more than 2 bytes
2175 sys_sigblock (sigset_t new_mask
)
2178 sigprocmask (SIG_BLOCK
, &new_mask
, &old_mask
);
2183 sys_sigunblock (sigset_t new_mask
)
2186 sigprocmask (SIG_UNBLOCK
, &new_mask
, &old_mask
);
2191 sys_sigsetmask (sigset_t new_mask
)
2194 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
2198 #endif /* POSIX_SIGNALS */
2200 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2201 static char *my_sys_siglist
[NSIG
];
2205 # define sys_siglist my_sys_siglist
2211 #ifdef POSIX_SIGNALS
2212 sigemptyset (&empty_mask
);
2213 sigfillset (&full_mask
);
2216 #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
2220 sys_siglist
[SIGABRT
] = "Aborted";
2223 sys_siglist
[SIGAIO
] = "LAN I/O interrupt";
2226 sys_siglist
[SIGALRM
] = "Alarm clock";
2229 sys_siglist
[SIGBUS
] = "Bus error";
2232 sys_siglist
[SIGCLD
] = "Child status changed";
2235 sys_siglist
[SIGCHLD
] = "Child status changed";
2238 sys_siglist
[SIGCONT
] = "Continued";
2241 sys_siglist
[SIGDANGER
] = "Swap space dangerously low";
2244 sys_siglist
[SIGDGNOTIFY
] = "Notification message in queue";
2247 sys_siglist
[SIGEMT
] = "Emulation trap";
2250 sys_siglist
[SIGFPE
] = "Arithmetic exception";
2253 sys_siglist
[SIGFREEZE
] = "SIGFREEZE";
2256 sys_siglist
[SIGGRANT
] = "Monitor mode granted";
2259 sys_siglist
[SIGHUP
] = "Hangup";
2262 sys_siglist
[SIGILL
] = "Illegal instruction";
2265 sys_siglist
[SIGINT
] = "Interrupt";
2268 sys_siglist
[SIGIO
] = "I/O possible";
2271 sys_siglist
[SIGIOINT
] = "I/O intervention required";
2274 sys_siglist
[SIGIOT
] = "IOT trap";
2277 sys_siglist
[SIGKILL
] = "Killed";
2280 sys_siglist
[SIGLOST
] = "Resource lost";
2283 sys_siglist
[SIGLWP
] = "SIGLWP";
2286 sys_siglist
[SIGMSG
] = "Monitor mode data available";
2289 sys_siglist
[SIGWIND
] = "SIGPHONE";
2292 sys_siglist
[SIGPIPE
] = "Broken pipe";
2295 sys_siglist
[SIGPOLL
] = "Pollable event occurred";
2298 sys_siglist
[SIGPROF
] = "Profiling timer expired";
2301 sys_siglist
[SIGPTY
] = "PTY I/O interrupt";
2304 sys_siglist
[SIGPWR
] = "Power-fail restart";
2307 sys_siglist
[SIGQUIT
] = "Quit";
2310 sys_siglist
[SIGRETRACT
] = "Need to relinguish monitor mode";
2313 sys_siglist
[SIGSAK
] = "Secure attention";
2316 sys_siglist
[SIGSEGV
] = "Segmentation violation";
2319 sys_siglist
[SIGSOUND
] = "Sound completed";
2322 sys_siglist
[SIGSTOP
] = "Stopped (signal)";
2325 sys_siglist
[SIGSTP
] = "Stopped (user)";
2328 sys_siglist
[SIGSYS
] = "Bad argument to system call";
2331 sys_siglist
[SIGTERM
] = "Terminated";
2334 sys_siglist
[SIGTHAW
] = "SIGTHAW";
2337 sys_siglist
[SIGTRAP
] = "Trace/breakpoint trap";
2340 sys_siglist
[SIGTSTP
] = "Stopped (user)";
2343 sys_siglist
[SIGTTIN
] = "Stopped (tty input)";
2346 sys_siglist
[SIGTTOU
] = "Stopped (tty output)";
2349 sys_siglist
[SIGURG
] = "Urgent I/O condition";
2352 sys_siglist
[SIGUSR1
] = "User defined signal 1";
2355 sys_siglist
[SIGUSR2
] = "User defined signal 2";
2358 sys_siglist
[SIGVTALRM
] = "Virtual timer expired";
2361 sys_siglist
[SIGWAITING
] = "Process's LWPs are blocked";
2364 sys_siglist
[SIGWINCH
] = "Window size changed";
2367 sys_siglist
[SIGWIND
] = "SIGWIND";
2370 sys_siglist
[SIGXCPU
] = "CPU time limit exceeded";
2373 sys_siglist
[SIGXFSZ
] = "File size limit exceeded";
2376 #endif /* !defined HAVE_STRSIGNAL && !defined HAVE_DECL_SYS_SIGLIST */
2385 /* Figure out how many bits the system's random number generator uses.
2386 `random' and `lrand48' are assumed to return 31 usable bits.
2387 BSD `rand' returns a 31 bit value but the low order bits are unusable;
2388 so we'll shift it and treat it like the 15-bit USG `rand'. */
2392 # define RAND_BITS 31
2393 # else /* !HAVE_RANDOM */
2394 # ifdef HAVE_LRAND48
2395 # define RAND_BITS 31
2396 # define random lrand48
2397 # else /* !HAVE_LRAND48 */
2398 # define RAND_BITS 15
2399 # if RAND_MAX == 32767
2400 # define random rand
2401 # else /* RAND_MAX != 32767 */
2402 # if RAND_MAX == 2147483647
2403 # define random() (rand () >> 16)
2404 # else /* RAND_MAX != 2147483647 */
2406 # define random rand
2408 # define random() (rand () >> 16)
2410 # endif /* RAND_MAX != 2147483647 */
2411 # endif /* RAND_MAX != 32767 */
2412 # endif /* !HAVE_LRAND48 */
2413 # endif /* !HAVE_RANDOM */
2414 #endif /* !RAND_BITS */
2421 srandom ((unsigned int)arg
);
2423 # ifdef HAVE_LRAND48
2426 srand ((unsigned int)arg
);
2432 * Build a full Emacs-sized word out of whatever we've got.
2433 * This suffices even for a 64-bit architecture with a 15-bit rand.
2438 long val
= random ();
2439 #if VALBITS > RAND_BITS
2440 val
= (val
<< RAND_BITS
) ^ random ();
2441 #if VALBITS > 2*RAND_BITS
2442 val
= (val
<< RAND_BITS
) ^ random ();
2443 #if VALBITS > 3*RAND_BITS
2444 val
= (val
<< RAND_BITS
) ^ random ();
2445 #if VALBITS > 4*RAND_BITS
2446 val
= (val
<< RAND_BITS
) ^ random ();
2447 #endif /* need at least 5 */
2448 #endif /* need at least 4 */
2449 #endif /* need at least 3 */
2450 #endif /* need at least 2 */
2451 return val
& ((1L << VALBITS
) - 1);
2454 #ifndef HAVE_STRERROR
2460 extern char *sys_errlist
[];
2461 extern int sys_nerr
;
2463 if (errnum
>= 0 && errnum
< sys_nerr
)
2464 return sys_errlist
[errnum
];
2465 return (char *) "Unknown error";
2467 #endif /* not WINDOWSNT */
2468 #endif /* ! HAVE_STRERROR */
2471 emacs_open (path
, oflag
, mode
)
2475 register int rtnval
;
2477 while ((rtnval
= open (path
, oflag
, mode
)) == -1
2478 && (errno
== EINTR
))
2488 register int rtnval
;
2490 while ((rtnval
= close (fd
)) == -1
2491 && (errno
== EINTR
))
2494 /* If close is interrupted SunOS 4.1 may or may not have closed the
2495 file descriptor. If it did the second close will fail with
2496 errno = EBADF. That means we have succeeded. */
2497 if (rtnval
== -1 && did_retry
&& errno
== EBADF
)
2504 emacs_read (fildes
, buf
, nbyte
)
2509 register int rtnval
;
2511 while ((rtnval
= read (fildes
, buf
, nbyte
)) == -1
2512 && (errno
== EINTR
))
2518 emacs_write (fildes
, buf
, nbyte
)
2523 register int rtnval
, bytes_written
;
2529 rtnval
= write (fildes
, buf
, nbyte
);
2536 /* I originally used `QUIT' but that might causes files to
2537 be truncated if you hit C-g in the middle of it. --Stef */
2538 process_pending_signals ();
2543 return (bytes_written
? bytes_written
: -1);
2548 bytes_written
+= rtnval
;
2550 return (bytes_written
);
2555 * All of the following are for USG.
2557 * On USG systems the system calls are INTERRUPTIBLE by signals
2558 * that the user program has elected to catch. Thus the system call
2559 * must be retried in these cases. To handle this without massive
2560 * changes in the source code, we remap the standard system call names
2561 * to names for our own functions in sysdep.c that do the system call
2562 * with retries. Actually, for portability reasons, it is good
2563 * programming practice, as this example shows, to limit all actual
2564 * system calls to a single occurrence in the source. Sure, this
2565 * adds an extra level of function call overhead but it is almost
2566 * always negligible. Fred Fish, Unisoft Systems Inc.
2570 * Warning, this function may not duplicate 4.2 action properly
2571 * under error conditions.
2575 /* In 4.1, param.h fails to define this. */
2576 #define MAXPATHLEN 1024
2585 char *npath
, *spath
;
2586 extern char *getcwd ();
2588 BLOCK_INPUT
; /* getcwd uses malloc */
2589 spath
= npath
= getcwd ((char *) 0, MAXPATHLEN
);
2595 /* On Altos 3068, getcwd can return @hostname/dir, so discard
2596 up to first slash. Should be harmless on other systems. */
2597 while (*npath
&& *npath
!= '/')
2599 strcpy (pathname
, npath
);
2600 free (spath
); /* getcwd uses malloc */
2605 #endif /* HAVE_GETWD */
2608 * Emulate rename using unlink/link. Note that this is
2609 * only partially correct. Also, doesn't enforce restriction
2610 * that files be of same type (regular->regular, dir->dir, etc).
2619 if (access (from
, 0) == 0)
2622 if (link (from
, to
) == 0)
2623 if (unlink (from
) == 0)
2632 #if defined(HPUX) && !defined(HAVE_PERROR)
2634 /* HPUX curses library references perror, but as far as we know
2635 it won't be called. Anyway this definition will do for now. */
2640 #endif /* HPUX and not HAVE_PERROR */
2645 * Emulate BSD dup2. First close newd if it already exists.
2646 * Then, attempt to dup oldd. If not successful, call dup2 recursively
2647 * until we are, then close the unsuccessful ones.
2654 register int fd
, ret
;
2659 return fcntl (oldd
, F_DUPFD
, newd
);
2666 ret
= dup2 (old
,new);
2672 #endif /* not HAVE_DUP2 */
2675 * Gettimeofday. Simulate as much as possible. Only accurate
2676 * to nearest second. Emacs doesn't use tzp so ignore it for now.
2677 * Only needed when subprocesses are defined.
2681 #ifndef HAVE_GETTIMEOFDAY
2686 gettimeofday (tp
, tzp
)
2688 struct timezone
*tzp
;
2690 extern long time ();
2692 tp
->tv_sec
= time ((long *)0);
2695 tzp
->tz_minuteswest
= -1;
2701 #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL */
2704 * This function will go away as soon as all the stubs fixed. (fnf)
2711 printf ("%s not yet implemented\r\n", badfunc
);
2712 reset_all_sys_modes ();
2718 /* Directory routines for systems that don't have them. */
2720 #ifdef SYSV_SYSTEM_DIR
2724 #if !defined (HAVE_CLOSEDIR)
2727 closedir (DIR *dirp
/* stream from opendir */)
2731 rtnval
= emacs_close (dirp
->dd_fd
);
2733 /* Some systems (like Solaris) allocate the buffer and the DIR all
2734 in one block. Why in the world are we freeing this ourselves
2736 #if ! defined (SOLARIS2)
2737 xfree ((char *) dirp
->dd_buf
); /* directory block defined in <dirent.h> */
2739 xfree ((char *) dirp
);
2743 #endif /* not HAVE_CLOSEDIR */
2744 #endif /* SYSV_SYSTEM_DIR */
2748 set_file_times (filename
, atime
, mtime
)
2749 const char *filename
;
2750 EMACS_TIME atime
, mtime
;
2753 struct timeval tv
[2];
2756 return utimes (filename
, tv
);
2757 #else /* not HAVE_UTIMES */
2759 utb
.actime
= EMACS_SECS (atime
);
2760 utb
.modtime
= EMACS_SECS (mtime
);
2761 return utime (filename
, &utb
);
2762 #endif /* not HAVE_UTIMES */
2765 /* mkdir and rmdir functions, for systems which don't have them. */
2769 * Written by Robert Rother, Mariah Corporation, August 1985.
2771 * If you want it, it's yours. All I ask in return is that if you
2772 * figure out how to do this in a Bourne Shell script you send me
2774 * sdcsvax!rmr or rmr@uscd
2776 * Severely hacked over by John Gilmore to make a 4.2BSD compatible
2777 * subroutine. 11Mar86; hoptoad!gnu
2779 * Modified by rmtodd@uokmax 6-28-87 -- when making an already existing dir,
2780 * subroutine didn't return EEXIST. It does now.
2787 mkdir (dpath
, dmode
)
2791 int cpid
, status
, fd
;
2792 struct stat statbuf
;
2794 if (stat (dpath
, &statbuf
) == 0)
2796 errno
= EEXIST
; /* Stat worked, so it already exists */
2800 /* If stat fails for a reason other than non-existence, return error */
2801 if (errno
!= ENOENT
)
2804 synch_process_alive
= 1;
2805 switch (cpid
= fork ())
2808 case -1: /* Error in fork */
2809 return (-1); /* Errno is set already */
2811 case 0: /* Child process */
2813 * Cheap hack to set mode of new directory. Since this
2814 * child process is going away anyway, we zap its umask.
2815 * FIXME, this won't suffice to set SUID, SGID, etc. on this
2816 * directory. Does anybody care?
2818 status
= umask (0); /* Get current umask */
2819 status
= umask (status
| (0777 & ~dmode
)); /* Set for mkdir */
2820 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
2827 execl ("/bin/mkdir", "mkdir", dpath
, (char *) 0);
2828 _exit (-1); /* Can't exec /bin/mkdir */
2830 default: /* Parent process */
2831 wait_for_termination (cpid
);
2834 if (synch_process_death
!= 0 || synch_process_retcode
!= 0
2835 || synch_process_termsig
!= 0)
2837 errno
= EIO
; /* We don't know why, but */
2838 return -1; /* /bin/mkdir failed */
2843 #endif /* not HAVE_MKDIR */
2850 int cpid
, status
, fd
;
2851 struct stat statbuf
;
2853 if (stat (dpath
, &statbuf
) != 0)
2855 /* Stat just set errno. We don't have to */
2859 synch_process_alive
= 1;
2860 switch (cpid
= fork ())
2863 case -1: /* Error in fork */
2864 return (-1); /* Errno is set already */
2866 case 0: /* Child process */
2867 fd
= emacs_open ("/dev/null", O_RDWR
, 0);
2874 execl ("/bin/rmdir", "rmdir", dpath
, (char *) 0);
2875 _exit (-1); /* Can't exec /bin/rmdir */
2877 default: /* Parent process */
2878 wait_for_termination (cpid
);
2881 if (synch_process_death
!= 0 || synch_process_retcode
!= 0
2882 || synch_process_termsig
!= 0)
2884 errno
= EIO
; /* We don't know why, but */
2885 return -1; /* /bin/rmdir failed */
2890 #endif /* !HAVE_RMDIR */
2900 register int length
;
2902 while (length
-- > 0)
2906 #endif /* no bzero */
2907 #endif /* BSTRING */
2909 #if (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY)
2912 /* Saying `void' requires a declaration, above, where bcopy is used
2913 and that declaration causes pain for systems where bcopy is a macro. */
2914 bcopy (b1
, b2
, length
)
2917 register int length
;
2919 while (length
-- > 0)
2922 #endif /* (!defined (BSTRING) && !defined (bcopy)) || defined (NEED_BCOPY) */
2927 bcmp (b1
, b2
, length
) /* This could be a macro! */
2930 register int length
;
2932 while (length
-- > 0)
2938 #endif /* no bcmp */
2939 #endif /* not BSTRING */
2941 #ifndef HAVE_STRSIGNAL
2948 if (0 <= code
&& code
< NSIG
)
2950 /* Cast to suppress warning if the table has const char *. */
2951 signame
= (char *) sys_siglist
[code
];
2956 #endif /* HAVE_STRSIGNAL */
2959 /* For make-serial-process */
2960 int serial_open (char *port
)
2964 fd
= emacs_open ((char*) port
,
2977 error ("Could not open %s: %s",
2978 port
, emacs_strerror (errno
));
2981 ioctl (fd
, TIOCEXCL
, (char *) 0);
2986 #endif /* TERMIOS */
2990 #if !defined (HAVE_CFMAKERAW)
2991 /* Workaround for targets which are missing cfmakeraw. */
2992 /* Pasted from man page. */
2993 static void cfmakeraw (struct termios
*termios_p
)
2995 termios_p
->c_iflag
&= ~(IGNBRK
|BRKINT
|PARMRK
|ISTRIP
|INLCR
|IGNCR
|ICRNL
|IXON
);
2996 termios_p
->c_oflag
&= ~OPOST
;
2997 termios_p
->c_lflag
&= ~(ECHO
|ECHONL
|ICANON
|ISIG
|IEXTEN
);
2998 termios_p
->c_cflag
&= ~(CSIZE
|PARENB
);
2999 termios_p
->c_cflag
|= CS8
;
3001 #endif /* !defined (HAVE_CFMAKERAW */
3003 #if !defined (HAVE_CFSETSPEED)
3004 /* Workaround for targets which are missing cfsetspeed. */
3005 static int cfsetspeed (struct termios
*termios_p
, speed_t vitesse
)
3007 return (cfsetispeed (termios_p
, vitesse
)
3008 + cfsetospeed (termios_p
, vitesse
));
3012 /* For serial-process-configure */
3014 serial_configure (struct Lisp_Process
*p
,
3015 Lisp_Object contact
)
3017 Lisp_Object childp2
= Qnil
;
3018 Lisp_Object tem
= Qnil
;
3019 struct termios attr
;
3021 char summary
[4] = "???"; /* This usually becomes "8N1". */
3023 childp2
= Fcopy_sequence (p
->childp
);
3025 /* Read port attributes and prepare default configuration. */
3026 err
= tcgetattr (p
->outfd
, &attr
);
3028 error ("tcgetattr() failed: %s", emacs_strerror (errno
));
3030 #if defined (CLOCAL)
3031 attr
.c_cflag
|= CLOCAL
;
3034 attr
.c_cflag
|= CREAD
;
3037 /* Configure speed. */
3038 if (!NILP (Fplist_member (contact
, QCspeed
)))
3039 tem
= Fplist_get (contact
, QCspeed
);
3041 tem
= Fplist_get (p
->childp
, QCspeed
);
3043 err
= cfsetspeed (&attr
, XINT (tem
));
3045 error ("cfsetspeed(%d) failed: %s", XINT (tem
), emacs_strerror (errno
));
3046 childp2
= Fplist_put (childp2
, QCspeed
, tem
);
3048 /* Configure bytesize. */
3049 if (!NILP (Fplist_member (contact
, QCbytesize
)))
3050 tem
= Fplist_get (contact
, QCbytesize
);
3052 tem
= Fplist_get (p
->childp
, QCbytesize
);
3054 tem
= make_number (8);
3056 if (XINT (tem
) != 7 && XINT (tem
) != 8)
3057 error (":bytesize must be nil (8), 7, or 8");
3058 summary
[0] = XINT(tem
) + '0';
3059 #if defined (CSIZE) && defined (CS7) && defined (CS8)
3060 attr
.c_cflag
&= ~CSIZE
;
3061 attr
.c_cflag
|= ((XINT (tem
) == 7) ? CS7
: CS8
);
3063 /* Don't error on bytesize 8, which should be set by cfmakeraw. */
3064 if (XINT (tem
) != 8)
3065 error ("Bytesize cannot be changed");
3067 childp2
= Fplist_put (childp2
, QCbytesize
, tem
);
3069 /* Configure parity. */
3070 if (!NILP (Fplist_member (contact
, QCparity
)))
3071 tem
= Fplist_get (contact
, QCparity
);
3073 tem
= Fplist_get (p
->childp
, QCparity
);
3074 if (!NILP (tem
) && !EQ (tem
, Qeven
) && !EQ (tem
, Qodd
))
3075 error (":parity must be nil (no parity), `even', or `odd'");
3076 #if defined (PARENB) && defined (PARODD) && defined (IGNPAR) && defined (INPCK)
3077 attr
.c_cflag
&= ~(PARENB
| PARODD
);
3078 attr
.c_iflag
&= ~(IGNPAR
| INPCK
);
3083 else if (EQ (tem
, Qeven
))
3086 attr
.c_cflag
|= PARENB
;
3087 attr
.c_iflag
|= (IGNPAR
| INPCK
);
3089 else if (EQ (tem
, Qodd
))
3092 attr
.c_cflag
|= (PARENB
| PARODD
);
3093 attr
.c_iflag
|= (IGNPAR
| INPCK
);
3096 /* Don't error on no parity, which should be set by cfmakeraw. */
3098 error ("Parity cannot be configured");
3100 childp2
= Fplist_put (childp2
, QCparity
, tem
);
3102 /* Configure stopbits. */
3103 if (!NILP (Fplist_member (contact
, QCstopbits
)))
3104 tem
= Fplist_get (contact
, QCstopbits
);
3106 tem
= Fplist_get (p
->childp
, QCstopbits
);
3108 tem
= make_number (1);
3110 if (XINT (tem
) != 1 && XINT (tem
) != 2)
3111 error (":stopbits must be nil (1 stopbit), 1, or 2");
3112 summary
[2] = XINT (tem
) + '0';
3113 #if defined (CSTOPB)
3114 attr
.c_cflag
&= ~CSTOPB
;
3115 if (XINT (tem
) == 2)
3116 attr
.c_cflag
|= CSTOPB
;
3118 /* Don't error on 1 stopbit, which should be set by cfmakeraw. */
3119 if (XINT (tem
) != 1)
3120 error ("Stopbits cannot be configured");
3122 childp2
= Fplist_put (childp2
, QCstopbits
, tem
);
3124 /* Configure flowcontrol. */
3125 if (!NILP (Fplist_member (contact
, QCflowcontrol
)))
3126 tem
= Fplist_get (contact
, QCflowcontrol
);
3128 tem
= Fplist_get (p
->childp
, QCflowcontrol
);
3129 if (!NILP (tem
) && !EQ (tem
, Qhw
) && !EQ (tem
, Qsw
))
3130 error (":flowcontrol must be nil (no flowcontrol), `hw', or `sw'");
3131 #if defined (CRTSCTS)
3132 attr
.c_cflag
&= ~CRTSCTS
;
3134 #if defined (CNEW_RTSCTS)
3135 attr
.c_cflag
&= ~CNEW_RTSCTS
;
3137 #if defined (IXON) && defined (IXOFF)
3138 attr
.c_iflag
&= ~(IXON
| IXOFF
);
3142 /* Already configured. */
3144 else if (EQ (tem
, Qhw
))
3146 #if defined (CRTSCTS)
3147 attr
.c_cflag
|= CRTSCTS
;
3148 #elif defined (CNEW_RTSCTS)
3149 attr
.c_cflag
|= CNEW_RTSCTS
;
3151 error ("Hardware flowcontrol (RTS/CTS) not supported");
3154 else if (EQ (tem
, Qsw
))
3156 #if defined (IXON) && defined (IXOFF)
3157 attr
.c_iflag
|= (IXON
| IXOFF
);
3159 error ("Software flowcontrol (XON/XOFF) not supported");
3162 childp2
= Fplist_put (childp2
, QCflowcontrol
, tem
);
3164 /* Activate configuration. */
3165 err
= tcsetattr (p
->outfd
, TCSANOW
, &attr
);
3167 error ("tcsetattr() failed: %s", emacs_strerror (errno
));
3169 childp2
= Fplist_put (childp2
, QCsummary
, build_string (summary
));
3170 p
->childp
= childp2
;
3173 #endif /* TERMIOS */
3175 /* System depended enumeration of and access to system processes a-la ps(1). */
3179 /* Process enumeration and access via /proc. */
3182 list_system_processes ()
3184 Lisp_Object procdir
, match
, proclist
, next
;
3185 struct gcpro gcpro1
, gcpro2
;
3186 register Lisp_Object tail
;
3188 GCPRO2 (procdir
, match
);
3189 /* For every process on the system, there's a directory in the
3190 "/proc" pseudo-directory whose name is the numeric ID of that
3192 procdir
= build_string ("/proc");
3193 match
= build_string ("[0-9]+");
3194 proclist
= directory_files_internal (procdir
, Qnil
, match
, Qt
, 0, Qnil
);
3196 /* `proclist' gives process IDs as strings. Destructively convert
3197 each string into a number. */
3198 for (tail
= proclist
; CONSP (tail
); tail
= next
)
3201 XSETCAR (tail
, Fstring_to_number (XCAR (tail
), Qnil
));
3205 /* directory_files_internal returns the files in reverse order; undo
3207 proclist
= Fnreverse (proclist
);
3211 /* The WINDOWSNT implementation is in w32.c.
3212 The MSDOS implementation is in dosfns.c. */
3213 #elif !defined (WINDOWSNT) && !defined (MSDOS)
3216 list_system_processes ()
3221 #endif /* !defined (WINDOWSNT) */
3225 time_from_jiffies (unsigned long long tval
, long hz
,
3226 time_t *sec
, unsigned *usec
)
3228 unsigned long long ullsec
;
3232 tval
-= ullsec
* hz
;
3233 /* Careful: if HZ > 1 million, then integer division by it yields zero. */
3235 *usec
= tval
* 1000000 / hz
;
3237 *usec
= tval
/ (hz
/ 1000000);
3241 ltime_from_jiffies (unsigned long long tval
, long hz
)
3246 time_from_jiffies (tval
, hz
, &sec
, &usec
);
3248 return list3 (make_number ((sec
>> 16) & 0xffff),
3249 make_number (sec
& 0xffff),
3250 make_number (usec
));
3254 get_up_time (time_t *sec
, unsigned *usec
)
3261 fup
= fopen ("/proc/uptime", "r");
3265 double uptime
, idletime
;
3267 /* The numbers in /proc/uptime use C-locale decimal point, but
3268 we already set ourselves to the C locale (see `fixup_locale'
3270 if (2 <= fscanf (fup
, "%lf %lf", &uptime
, &idletime
))
3273 *usec
= (uptime
- *sec
) * 1000000;
3280 #define MAJOR(d) (((unsigned)(d) >> 8) & 0xfff)
3281 #define MINOR(d) (((unsigned)(d) & 0xff) | (((unsigned)(d) & 0xfff00000) >> 12))
3284 procfs_ttyname (int rdev
)
3287 char name
[PATH_MAX
];
3290 fdev
= fopen ("/proc/tty/drivers", "r");
3295 unsigned long minor_beg
, minor_end
;
3296 char minor
[25]; /* 2 32-bit numbers + dash */
3299 while (!feof (fdev
) && !ferror (fdev
))
3301 if (3 <= fscanf (fdev
, "%*s %s %u %s %*s\n", name
, &major
, minor
)
3302 && major
== MAJOR (rdev
))
3304 minor_beg
= strtoul (minor
, &endp
, 0);
3306 minor_end
= minor_beg
;
3307 else if (*endp
== '-')
3308 minor_end
= strtoul (endp
+ 1, &endp
, 0);
3312 if (MINOR (rdev
) >= minor_beg
&& MINOR (rdev
) <= minor_end
)
3314 sprintf (name
+ strlen (name
), "%u", MINOR (rdev
));
3322 return build_string (name
);
3325 static unsigned long
3326 procfs_get_total_memory (void)
3329 unsigned long retval
= 2 * 1024 * 1024; /* default: 2GB */
3332 fmem
= fopen ("/proc/meminfo", "r");
3336 unsigned long entry_value
;
3337 char entry_name
[20]; /* the longest I saw is 13+1 */
3339 while (!feof (fmem
) && !ferror (fmem
))
3341 if (2 <= fscanf (fmem
, "%s %lu kB\n", entry_name
, &entry_value
)
3342 && strcmp (entry_name
, "MemTotal:") == 0)
3344 retval
= entry_value
;
3355 system_process_attributes (Lisp_Object pid
)
3357 char procfn
[PATH_MAX
], fn
[PATH_MAX
];
3361 long clocks_per_sec
;
3363 char procbuf
[1025], *p
, *q
;
3366 const char *cmd
= NULL
;
3367 char *cmdline
= NULL
;
3368 size_t cmdsize
= 0, cmdline_size
;
3370 int proc_id
, ppid
, uid
, gid
, pgrp
, sess
, tty
, tpgid
, thcount
;
3371 unsigned long long utime
, stime
, cutime
, cstime
, start
;
3372 long priority
, nice
, rss
;
3373 unsigned long minflt
, majflt
, cminflt
, cmajflt
, vsize
;
3376 EMACS_TIME tnow
, tstart
, tboot
, telapsed
,ttotal
;
3378 Lisp_Object attrs
= Qnil
;
3379 Lisp_Object cmd_str
, decoded_cmd
, tem
;
3380 struct gcpro gcpro1
, gcpro2
;
3381 EMACS_INT uid_eint
, gid_eint
;
3383 CHECK_NUMBER_OR_FLOAT (pid
);
3384 proc_id
= FLOATP (pid
) ? XFLOAT_DATA (pid
) : XINT (pid
);
3385 sprintf (procfn
, "/proc/%u", proc_id
);
3386 if (stat (procfn
, &st
) < 0)
3389 GCPRO2 (attrs
, decoded_cmd
);
3393 /* Use of EMACS_INT stops GCC whining about limited range of data type. */
3395 attrs
= Fcons (Fcons (Qeuid
, make_fixnum_or_float (uid_eint
)), attrs
);
3397 pw
= getpwuid (uid
);
3400 attrs
= Fcons (Fcons (Quser
, build_string (pw
->pw_name
)), attrs
);
3404 attrs
= Fcons (Fcons (Qegid
, make_fixnum_or_float (gid_eint
)), attrs
);
3406 gr
= getgrgid (gid
);
3409 attrs
= Fcons (Fcons (Qgroup
, build_string (gr
->gr_name
)), attrs
);
3411 strcpy (fn
, procfn
);
3412 procfn_end
= fn
+ strlen (fn
);
3413 strcpy (procfn_end
, "/stat");
3414 fd
= emacs_open (fn
, O_RDONLY
, 0);
3415 if (fd
>= 0 && (nread
= emacs_read (fd
, procbuf
, sizeof(procbuf
) - 1)) > 0)
3417 procbuf
[nread
] = '\0';
3420 p
= strchr (p
, '(');
3423 q
= strrchr (p
+ 1, ')');
3438 /* Command name is encoded in locale-coding-system; decode it. */
3439 cmd_str
= make_unibyte_string (cmd
, cmdsize
);
3440 decoded_cmd
= code_convert_string_norecord (cmd_str
,
3441 Vlocale_coding_system
, 0);
3442 attrs
= Fcons (Fcons (Qcomm
, decoded_cmd
), attrs
);
3446 EMACS_INT ppid_eint
, pgrp_eint
, sess_eint
, tpgid_eint
, thcount_eint
;
3448 /* state ppid pgrp sess tty tpgid . minflt cminflt majflt cmajflt utime stime cutime cstime priority nice thcount . start vsize rss */
3449 sscanf (p
, "%c %d %d %d %d %d %*u %lu %lu %lu %lu %Lu %Lu %Lu %Lu %ld %ld %d %*d %Lu %lu %ld",
3450 &c
, &ppid
, &pgrp
, &sess
, &tty
, &tpgid
,
3451 &minflt
, &cminflt
, &majflt
, &cmajflt
,
3452 &utime
, &stime
, &cutime
, &cstime
,
3453 &priority
, &nice
, &thcount
, &start
, &vsize
, &rss
);
3458 state_str
[1] = '\0';
3459 tem
= build_string (state_str
);
3460 attrs
= Fcons (Fcons (Qstate
, tem
), attrs
);
3462 /* Stops GCC whining about limited range of data type. */
3467 thcount_eint
= thcount
;
3468 attrs
= Fcons (Fcons (Qppid
, make_fixnum_or_float (ppid_eint
)), attrs
);
3469 attrs
= Fcons (Fcons (Qpgrp
, make_fixnum_or_float (pgrp_eint
)), attrs
);
3470 attrs
= Fcons (Fcons (Qsess
, make_fixnum_or_float (sess_eint
)), attrs
);
3471 attrs
= Fcons (Fcons (Qttname
, procfs_ttyname (tty
)), attrs
);
3472 attrs
= Fcons (Fcons (Qtpgid
, make_fixnum_or_float (tpgid_eint
)), attrs
);
3473 attrs
= Fcons (Fcons (Qminflt
, make_fixnum_or_float (minflt
)), attrs
);
3474 attrs
= Fcons (Fcons (Qmajflt
, make_fixnum_or_float (majflt
)), attrs
);
3475 attrs
= Fcons (Fcons (Qcminflt
, make_fixnum_or_float (cminflt
)), attrs
);
3476 attrs
= Fcons (Fcons (Qcmajflt
, make_fixnum_or_float (cmajflt
)), attrs
);
3477 clocks_per_sec
= sysconf (_SC_CLK_TCK
);
3478 if (clocks_per_sec
< 0)
3479 clocks_per_sec
= 100;
3480 attrs
= Fcons (Fcons (Qutime
,
3481 ltime_from_jiffies (utime
, clocks_per_sec
)),
3483 attrs
= Fcons (Fcons (Qstime
,
3484 ltime_from_jiffies (stime
, clocks_per_sec
)),
3486 attrs
= Fcons (Fcons (Qtime
,
3487 ltime_from_jiffies (stime
+utime
, clocks_per_sec
)),
3489 attrs
= Fcons (Fcons (Qcutime
,
3490 ltime_from_jiffies (cutime
, clocks_per_sec
)),
3492 attrs
= Fcons (Fcons (Qcstime
,
3493 ltime_from_jiffies (cstime
, clocks_per_sec
)),
3495 attrs
= Fcons (Fcons (Qctime
,
3496 ltime_from_jiffies (cstime
+cutime
, clocks_per_sec
)),
3498 attrs
= Fcons (Fcons (Qpri
, make_number (priority
)), attrs
);
3499 attrs
= Fcons (Fcons (Qnice
, make_number (nice
)), attrs
);
3500 attrs
= Fcons (Fcons (Qthcount
, make_fixnum_or_float (thcount_eint
)), attrs
);
3501 EMACS_GET_TIME (tnow
);
3502 get_up_time (&sec
, &usec
);
3503 EMACS_SET_SECS (telapsed
, sec
);
3504 EMACS_SET_USECS (telapsed
, usec
);
3505 EMACS_SUB_TIME (tboot
, tnow
, telapsed
);
3506 time_from_jiffies (start
, clocks_per_sec
, &sec
, &usec
);
3507 EMACS_SET_SECS (tstart
, sec
);
3508 EMACS_SET_USECS (tstart
, usec
);
3509 EMACS_ADD_TIME (tstart
, tboot
, tstart
);
3510 attrs
= Fcons (Fcons (Qstart
,
3512 ((EMACS_SECS (tstart
) >> 16) & 0xffff),
3514 (EMACS_SECS (tstart
) & 0xffff),
3516 (EMACS_USECS (tstart
)))),
3518 attrs
= Fcons (Fcons (Qvsize
, make_fixnum_or_float (vsize
/1024)), attrs
);
3519 attrs
= Fcons (Fcons (Qrss
, make_fixnum_or_float (4*rss
)), attrs
);
3520 EMACS_SUB_TIME (telapsed
, tnow
, tstart
);
3521 attrs
= Fcons (Fcons (Qetime
,
3523 ((EMACS_SECS (telapsed
) >> 16) & 0xffff),
3525 (EMACS_SECS (telapsed
) & 0xffff),
3527 (EMACS_USECS (telapsed
)))),
3529 time_from_jiffies (utime
+ stime
, clocks_per_sec
, &sec
, &usec
);
3530 pcpu
= (sec
+ usec
/ 1000000.0) / (EMACS_SECS (telapsed
) + EMACS_USECS (telapsed
) / 1000000.0);
3533 attrs
= Fcons (Fcons (Qpcpu
, make_float (100 * pcpu
)), attrs
);
3534 pmem
= 4.0 * 100 * rss
/ procfs_get_total_memory ();
3537 attrs
= Fcons (Fcons (Qpmem
, make_float (pmem
)), attrs
);
3544 strcpy (procfn_end
, "/cmdline");
3545 fd
= emacs_open (fn
, O_RDONLY
, 0);
3548 for (cmdline_size
= 0; emacs_read (fd
, &c
, 1) == 1; cmdline_size
++)
3550 if (isspace (c
) || c
== '\\')
3551 cmdline_size
++; /* for later quoting, see below */
3555 cmdline
= xmalloc (cmdline_size
+ 1);
3556 lseek (fd
, 0L, SEEK_SET
);
3558 if ((nread
= read (fd
, cmdline
, cmdline_size
)) >= 0)
3559 cmdline
[nread
++] = '\0';
3562 /* Assigning zero to `nread' makes us skip the following
3563 two loops, assign zero to cmdline_size, and enter the
3564 following `if' clause that handles unknown command
3568 /* We don't want trailing null characters. */
3569 for (p
= cmdline
+ nread
- 1; p
> cmdline
&& !*p
; p
--)
3571 for (p
= cmdline
; p
< cmdline
+ nread
; p
++)
3573 /* Escape-quote whitespace and backslashes. */
3574 if (isspace (*p
) || *p
== '\\')
3576 memmove (p
+ 1, p
, nread
- (p
- cmdline
));
3580 else if (*p
== '\0')
3583 cmdline_size
= nread
;
3590 cmdsize
= strlen (cmd
);
3591 cmdline_size
= cmdsize
+ 2;
3592 cmdline
= xmalloc (cmdline_size
+ 1);
3593 strcpy (cmdline
, "[");
3594 strcat (strncat (cmdline
, cmd
, cmdsize
), "]");
3597 /* Command line is encoded in locale-coding-system; decode it. */
3598 cmd_str
= make_unibyte_string (cmdline
, cmdline_size
);
3599 decoded_cmd
= code_convert_string_norecord (cmd_str
,
3600 Vlocale_coding_system
, 0);
3602 attrs
= Fcons (Fcons (Qargs
, decoded_cmd
), attrs
);
3609 #elif defined (SOLARIS2) && defined (HAVE_PROCFS)
3611 /* The <procfs.h> header does not like to be included if _LP64 is defined and
3612 __FILE_OFFSET_BITS == 64. This is an ugly workaround that. */
3613 #if !defined (_LP64) && defined (_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
3614 #define PROCFS_FILE_OFFSET_BITS_HACK 1
3615 #undef _FILE_OFFSET_BITS
3617 #define PROCFS_FILE_OFFSET_BITS_HACK 0
3622 #if PROCFS_FILE_OFFSET_BITS_HACK == 1
3623 #define _FILE_OFFSET_BITS 64
3624 #endif /* PROCFS_FILE_OFFSET_BITS_HACK == 1 */
3627 system_process_attributes (Lisp_Object pid
)
3629 char procfn
[PATH_MAX
], fn
[PATH_MAX
];
3634 struct psinfo pinfo
;
3637 int proc_id
, uid
, gid
;
3638 Lisp_Object attrs
= Qnil
;
3639 Lisp_Object decoded_cmd
, tem
;
3640 struct gcpro gcpro1
, gcpro2
;
3641 EMACS_INT uid_eint
, gid_eint
;
3643 CHECK_NUMBER_OR_FLOAT (pid
);
3644 proc_id
= FLOATP (pid
) ? XFLOAT_DATA (pid
) : XINT (pid
);
3645 sprintf (procfn
, "/proc/%u", proc_id
);
3646 if (stat (procfn
, &st
) < 0)
3649 GCPRO2 (attrs
, decoded_cmd
);
3653 /* Use of EMACS_INT stops GCC whining about limited range of data type. */
3655 attrs
= Fcons (Fcons (Qeuid
, make_fixnum_or_float (uid_eint
)), attrs
);
3657 pw
= getpwuid (uid
);
3660 attrs
= Fcons (Fcons (Quser
, build_string (pw
->pw_name
)), attrs
);
3664 attrs
= Fcons (Fcons (Qegid
, make_fixnum_or_float (gid_eint
)), attrs
);
3666 gr
= getgrgid (gid
);
3669 attrs
= Fcons (Fcons (Qgroup
, build_string (gr
->gr_name
)), attrs
);
3671 strcpy (fn
, procfn
);
3672 procfn_end
= fn
+ strlen (fn
);
3673 strcpy (procfn_end
, "/psinfo");
3674 fd
= emacs_open (fn
, O_RDONLY
, 0);
3676 && (nread
= read (fd
, (char*)&pinfo
, sizeof(struct psinfo
)) > 0))
3678 attrs
= Fcons (Fcons (Qppid
, make_fixnum_or_float (pinfo
.pr_ppid
)), attrs
);
3679 attrs
= Fcons (Fcons (Qpgrp
, make_fixnum_or_float (pinfo
.pr_pgid
)), attrs
);
3680 attrs
= Fcons (Fcons (Qsess
, make_fixnum_or_float (pinfo
.pr_sid
)), attrs
);
3684 state_str
[0] = pinfo
.pr_lwp
.pr_sname
;
3685 state_str
[1] = '\0';
3686 tem
= build_string (state_str
);
3687 attrs
= Fcons (Fcons (Qstate
, tem
), attrs
);
3690 /* FIXME: missing Qttyname. psinfo.pr_ttydev is a dev_t,
3691 need to get a string from it. */
3693 /* FIXME: missing: Qtpgid */
3705 Are they available? */
3707 attrs
= Fcons (Fcons (Qtime
,
3708 list3 (make_number (pinfo
.pr_time
.tv_sec
>> 16),
3709 make_number (pinfo
.pr_time
.tv_sec
& 0xffff),
3710 make_number (pinfo
.pr_time
.tv_nsec
))),
3713 attrs
= Fcons (Fcons (Qctime
,
3714 list3 (make_number (pinfo
.pr_ctime
.tv_sec
>> 16),
3715 make_number (pinfo
.pr_ctime
.tv_sec
& 0xffff),
3716 make_number (pinfo
.pr_ctime
.tv_nsec
))),
3719 attrs
= Fcons (Fcons (Qpri
, make_number (pinfo
.pr_lwp
.pr_pri
)), attrs
);
3720 attrs
= Fcons (Fcons (Qnice
, make_number (pinfo
.pr_lwp
.pr_nice
)), attrs
);
3721 attrs
= Fcons (Fcons (Qthcount
, make_fixnum_or_float (pinfo
.pr_nlwp
)), attrs
);
3723 attrs
= Fcons (Fcons (Qstart
,
3724 list3 (make_number (pinfo
.pr_start
.tv_sec
>> 16),
3725 make_number (pinfo
.pr_start
.tv_sec
& 0xffff),
3726 make_number (pinfo
.pr_start
.tv_nsec
))),
3728 attrs
= Fcons (Fcons (Qvsize
, make_fixnum_or_float (pinfo
.pr_size
)), attrs
);
3729 attrs
= Fcons (Fcons (Qrss
, make_fixnum_or_float (pinfo
.pr_rssize
)), attrs
);
3731 /* pr_pctcpu and pr_pctmem are encoded as a fixed point 16 bit number in [0 ... 1]. */
3732 attrs
= Fcons (Fcons (Qpcpu
, (pinfo
.pr_pctcpu
* 100.0) / (double)0x8000), attrs
);
3733 attrs
= Fcons (Fcons (Qpmem
, (pinfo
.pr_pctmem
* 100.0) / (double)0x8000), attrs
);
3736 = code_convert_string_norecord (make_unibyte_string (pinfo
.pr_fname
,
3737 strlen (pinfo
.pr_fname
)),
3738 Vlocale_coding_system
, 0);
3739 attrs
= Fcons (Fcons (Qcomm
, decoded_cmd
), attrs
);
3741 = code_convert_string_norecord (make_unibyte_string (pinfo
.pr_psargs
,
3742 strlen (pinfo
.pr_psargs
)),
3743 Vlocale_coding_system
, 0);
3744 attrs
= Fcons (Fcons (Qargs
, decoded_cmd
), attrs
);
3754 /* The WINDOWSNT implementation is in w32.c.
3755 The MSDOS implementation is in dosfns.c. */
3756 #elif !defined (WINDOWSNT) && !defined (MSDOS)
3759 system_process_attributes (Lisp_Object pid
)
3764 #endif /* !defined (WINDOWSNT) */
3767 /* arch-tag: edb43589-4e09-4544-b325-978b5b121dcf
3768 (do not change this comment) */