diff options
Diffstat (limited to 'src/sysdep.c')
-rw-r--r-- | src/sysdep.c | 465 |
1 files changed, 246 insertions, 219 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index b2aecc0ddac..4f89e8aba10 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -30,6 +30,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #include <unistd.h> #include <c-ctype.h> +#include <pathmax.h> #include <utimens.h> #include "lisp.h" @@ -91,13 +92,19 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #include <sys/file.h> #include <fcntl.h> +#include "syssignal.h" +#include "systime.h" #include "systty.h" #include "syswait.h" +#ifdef HAVE_SYS_RESOURCE_H +# include <sys/resource.h> +#endif + #ifdef HAVE_SYS_UTSNAME_H -#include <sys/utsname.h> -#include <memory.h> -#endif /* HAVE_SYS_UTSNAME_H */ +# include <sys/utsname.h> +# include <memory.h> +#endif #include "keyboard.h" #include "frame.h" @@ -118,18 +125,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #endif #ifdef WINDOWSNT -#include <direct.h> +# include <direct.h> /* In process.h which conflicts with the local copy. */ -#define _P_WAIT 0 +# define _P_WAIT 0 int _cdecl _spawnlp (int, const char *, const char *, ...); /* The following is needed for O_CLOEXEC, F_SETFD, FD_CLOEXEC, and several prototypes of functions called below. */ -#include <sys/socket.h> +# include <sys/socket.h> #endif -#include "syssignal.h" -#include "systime.h" - /* ULLONG_MAX is missing on Red Hat Linux 7.3; see Bug#11781. */ #ifndef ULLONG_MAX #define ULLONG_MAX TYPE_MAXIMUM (unsigned long long int) @@ -147,22 +151,52 @@ static const int baud_convert[] = #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE # include <sys/personality.h> -/* Disable address randomization in the current process. Return true - if addresses were randomized but this has been disabled, false - otherwise. */ -bool -disable_address_randomization (void) +/* If not -1, the personality that should be restored before exec. */ +static int exec_personality; + +/* Try to disable randomization if the current process needs it and + does not appear to have it already. */ +int +maybe_disable_address_randomization (bool dumping, int argc, char **argv) { - int pers = personality (0xffffffff); - if (pers < 0) - return false; - int desired_pers = pers | ADDR_NO_RANDOMIZE; + /* Undocumented Emacs option used only by this function. */ + static char const aslr_disabled_option[] = "--__aslr-disabled"; + + if (argc < 2 || strcmp (argv[1], aslr_disabled_option) != 0) + { + bool disable_aslr = dumping; +# ifdef __PPC64__ + disable_aslr = true; +# endif + exec_personality = disable_aslr ? personality (0xffffffff) : -1; + if (exec_personality & ADDR_NO_RANDOMIZE) + exec_personality = -1; + if (exec_personality != -1 + && personality (exec_personality | ADDR_NO_RANDOMIZE) != -1) + { + char **newargv = malloc ((argc + 2) * sizeof *newargv); + if (newargv) + { + /* Invoke self with undocumented option. */ + newargv[0] = argv[0]; + newargv[1] = (char *) aslr_disabled_option; + memcpy (&newargv[2], &argv[1], argc * sizeof *newargv); + execvp (newargv[0], newargv); + } - /* Call 'personality' twice, to detect buggy platforms like WSL - where 'personality' always returns 0. */ - return (pers != desired_pers - && personality (desired_pers) == pers - && personality (0xffffffff) == desired_pers); + /* If malloc or execvp fails, warn and then try anyway. */ + perror (argv[0]); + free (newargv); + } + } + else + { + /* Our earlier incarnation already disabled ASLR. */ + argc--; + memmove (&argv[1], &argv[2], argc * sizeof *argv); + } + + return argc; } #endif @@ -174,21 +208,12 @@ int emacs_exec_file (char const *file, char *const *argv, char *const *envp) { #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE - int pers = getenv ("EMACS_HEAP_EXEC") ? personality (0xffffffff) : -1; - bool change_personality = 0 <= pers && pers & ADDR_NO_RANDOMIZE; - if (change_personality) - personality (pers & ~ADDR_NO_RANDOMIZE); + if (exec_personality != -1) + personality (exec_personality); #endif execve (file, argv, envp); - int err = errno; - -#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE - if (change_personality) - personality (pers); -#endif - - return err; + return errno; } /* If FD is not already open, arrange for it to be open with FLAGS. */ @@ -233,20 +258,20 @@ get_current_dir_name_or_unreachable (void) char *pwd; - /* The maximum size of a directory name, including the terminating null. + /* The maximum size of a directory name, including the terminating NUL. Leave room so that the caller can append a trailing slash. */ ptrdiff_t dirsize_max = min (PTRDIFF_MAX, SIZE_MAX) - 1; /* The maximum size of a buffer for a file name, including the - terminating null. This is bounded by MAXPATHLEN, if available. */ + terminating NUL. This is bounded by PATH_MAX, if available. */ ptrdiff_t bufsize_max = dirsize_max; -#ifdef MAXPATHLEN - bufsize_max = min (bufsize_max, MAXPATHLEN); +#ifdef PATH_MAX + bufsize_max = min (bufsize_max, PATH_MAX); #endif # if HAVE_GET_CURRENT_DIR_NAME && !BROKEN_GET_CURRENT_DIR_NAME # ifdef HYBRID_MALLOC - bool use_libc = bss_sbrk_did_unexec; + bool use_libc = will_dump_with_unexec_p (); # else bool use_libc = true; # endif @@ -257,7 +282,7 @@ get_current_dir_name_or_unreachable (void) pwd = get_current_dir_name (); if (pwd) { - if (strlen (pwd) < dirsize_max) + if (strnlen (pwd, dirsize_max) < dirsize_max) return pwd; free (pwd); errno = ERANGE; @@ -274,7 +299,7 @@ get_current_dir_name_or_unreachable (void) sometimes a nicer name, and using it may avoid a fatal error if a parent directory is searchable but not readable. */ if (pwd - && (pwdlen = strlen (pwd)) < bufsize_max + && (pwdlen = strnlen (pwd, bufsize_max)) < bufsize_max && IS_DIRECTORY_SEP (pwd[pwdlen && IS_DEVICE_SEP (pwd[1]) ? 2 : 0]) && stat (pwd, &pwdstat) == 0 && stat (".", &dotstat) == 0 @@ -1043,16 +1068,6 @@ emacs_set_tty (int fd, struct emacs_tty *settings, bool flushp) static int old_fcntl_owner[FD_SETSIZE]; #endif /* F_SETOWN */ -/* This may also be defined in stdio, - but if so, this does no harm, - and using the same name avoids wasting the other one's space. */ - -#if defined (USG) -unsigned char _sobuf[BUFSIZ+8]; -#else -char _sobuf[BUFSIZ]; -#endif - /* Initialize the terminal mode on all tty devices that are currently open. */ @@ -1272,14 +1287,7 @@ init_sys_modes (struct tty_display_info *tty_out) } #endif /* F_GETOWN */ -#ifdef _IOFBF - /* This symbol is defined on recent USG systems. - Someone says without this call USG won't really buffer the file - even with a call to setbuf. */ - setvbuf (tty_out->output, (char *) _sobuf, _IOFBF, sizeof _sobuf); -#else - setbuf (tty_out->output, (char *) _sobuf); -#endif + setvbuf (tty_out->output, NULL, _IOFBF, BUFSIZ); if (tty_out->terminal->set_terminal_modes_hook) tty_out->terminal->set_terminal_modes_hook (tty_out->terminal); @@ -1496,18 +1504,18 @@ reset_sys_modes (struct tty_display_info *tty_out) tty_out->terminal->reset_terminal_modes_hook (tty_out->terminal); /* Avoid possible loss of output when changing terminal modes. */ - while (fdatasync (fileno (tty_out->output)) != 0 && errno == EINTR) + while (tcdrain (fileno (tty_out->output)) != 0 && errno == EINTR) continue; #ifndef DOS_NT -#ifdef F_SETOWN +# ifdef F_SETOWN if (interrupt_input) { reset_sigio (fileno (tty_out->input)); fcntl (fileno (tty_out->input), F_SETOWN, old_fcntl_owner[fileno (tty_out->input)]); } -#endif /* F_SETOWN */ +# endif /* F_SETOWN */ fcntl (fileno (tty_out->input), F_SETFL, fcntl (fileno (tty_out->input), F_GETFL, 0) & ~O_NONBLOCK); #endif @@ -1671,7 +1679,7 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler) } #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD -pthread_t main_thread_id; +static pthread_t main_thread_id; #endif /* SIG has arrived at the current process. Deliver it to the main @@ -1781,7 +1789,7 @@ deliver_fatal_thread_signal (int sig) deliver_thread_signal (sig, handle_fatal_signal); } -static _Noreturn void +static AVOID handle_arith_signal (int sig) { pthread_sigmask (SIG_SETMASK, &empty_mask, 0); @@ -1826,8 +1834,8 @@ stack_overflow (siginfo_t *siginfo) /* The known top and bottom of the stack. The actual stack may extend a bit beyond these boundaries. */ - char *bot = stack_bottom; - char *top = current_thread->stack_top; + char const *bot = stack_bottom; + char const *top = current_thread->stack_top; /* Log base 2 of the stack heuristic ratio. This ratio is the size of the known stack divided by the size of the guard area past the @@ -1884,7 +1892,10 @@ init_sigsegv (void) sigfillset (&sa.sa_mask); sa.sa_sigaction = handle_sigsegv; sa.sa_flags = SA_SIGINFO | SA_ONSTACK | emacs_sigaction_flags (); - return sigaction (SIGSEGV, &sa, NULL) < 0 ? 0 : 1; + if (sigaction (SIGSEGV, &sa, NULL) < 0) + return 0; + + return 1; } #else /* not HAVE_STACK_OVERFLOW_HANDLING or WINDOWSNT */ @@ -1939,7 +1950,7 @@ maybe_fatal_sig (int sig) } void -init_signals (bool dumping) +init_signals (void) { struct sigaction thread_fatal_action; struct sigaction action; @@ -2090,7 +2101,7 @@ init_signals (bool dumping) /* Don't alter signal handlers if dumping. On some machines, changing signal handlers sets static data that would make signals fail to work right when the dumped Emacs is run. */ - if (dumping) + if (will_dump_p ()) return; sigfillset (&process_fatal_action.sa_mask); @@ -2554,6 +2565,22 @@ emacs_close (int fd) #define MAX_RW_COUNT (INT_MAX >> 18 << 18) #endif +/* Verify that MAX_RW_COUNT fits in the relevant standard types. */ +#ifndef SSIZE_MAX +# define SSIZE_MAX TYPE_MAXIMUM (ssize_t) +#endif +verify (MAX_RW_COUNT <= PTRDIFF_MAX); +verify (MAX_RW_COUNT <= SIZE_MAX); +verify (MAX_RW_COUNT <= SSIZE_MAX); + +#ifdef WINDOWSNT +/* Verify that Emacs read requests cannot cause trouble, even in + 64-bit builds. The last argument of 'read' is 'unsigned int', and + the return value's type (see 'sys_read') is 'int'. */ +verify (MAX_RW_COUNT <= INT_MAX); +verify (MAX_RW_COUNT <= UINT_MAX); +#endif + /* Read from FD to a buffer BUF with size NBYTE. If interrupted, process any quits and pending signals immediately if INTERRUPTIBLE, and then retry the read unless quitting. @@ -2562,10 +2589,11 @@ emacs_close (int fd) static ptrdiff_t emacs_intr_read (int fd, void *buf, ptrdiff_t nbyte, bool interruptible) { + /* No caller should ever pass a too-large size to emacs_read. */ + eassert (nbyte <= MAX_RW_COUNT); + ssize_t result; - /* There is no need to check against MAX_RW_COUNT, since no caller ever - passes a size that large to emacs_read. */ do { if (interruptible) @@ -2687,30 +2715,6 @@ emacs_perror (char const *message) errno = err; } -/* Return a struct timeval that is roughly equivalent to T. - Use the least timeval not less than T. - Return an extremal value if the result would overflow. */ -struct timeval -make_timeval (struct timespec t) -{ - struct timeval tv; - tv.tv_sec = t.tv_sec; - tv.tv_usec = t.tv_nsec / 1000; - - if (t.tv_nsec % 1000 != 0) - { - if (tv.tv_usec < 999999) - tv.tv_usec++; - else if (tv.tv_sec < TYPE_MAXIMUM (time_t)) - { - tv.tv_sec++; - tv.tv_usec = 0; - } - } - - return tv; -} - /* Set the access and modification time stamps of FD (a.k.a. FILE) to be ATIME and MTIME, respectively. FD must be either negative -- in which case it is ignored -- @@ -2833,8 +2837,8 @@ serial_configure (struct Lisp_Process *p, tem = Fplist_get (contact, QCspeed); else tem = Fplist_get (p->childp, QCspeed); - CHECK_NUMBER (tem); - err = cfsetspeed (&attr, XINT (tem)); + CHECK_FIXNUM (tem); + err = cfsetspeed (&attr, XFIXNUM (tem)); if (err != 0) report_file_error ("Failed cfsetspeed", tem); childp2 = Fplist_put (childp2, QCspeed, tem); @@ -2845,17 +2849,17 @@ serial_configure (struct Lisp_Process *p, else tem = Fplist_get (p->childp, QCbytesize); if (NILP (tem)) - tem = make_number (8); - CHECK_NUMBER (tem); - if (XINT (tem) != 7 && XINT (tem) != 8) + tem = make_fixnum (8); + CHECK_FIXNUM (tem); + if (XFIXNUM (tem) != 7 && XFIXNUM (tem) != 8) error (":bytesize must be nil (8), 7, or 8"); - summary[0] = XINT (tem) + '0'; + summary[0] = XFIXNUM (tem) + '0'; #if defined (CSIZE) && defined (CS7) && defined (CS8) attr.c_cflag &= ~CSIZE; - attr.c_cflag |= ((XINT (tem) == 7) ? CS7 : CS8); + attr.c_cflag |= ((XFIXNUM (tem) == 7) ? CS7 : CS8); #else /* Don't error on bytesize 8, which should be set by cfmakeraw. */ - if (XINT (tem) != 8) + if (XFIXNUM (tem) != 8) error ("Bytesize cannot be changed"); #endif childp2 = Fplist_put (childp2, QCbytesize, tem); @@ -2899,18 +2903,18 @@ serial_configure (struct Lisp_Process *p, else tem = Fplist_get (p->childp, QCstopbits); if (NILP (tem)) - tem = make_number (1); - CHECK_NUMBER (tem); - if (XINT (tem) != 1 && XINT (tem) != 2) + tem = make_fixnum (1); + CHECK_FIXNUM (tem); + if (XFIXNUM (tem) != 1 && XFIXNUM (tem) != 2) error (":stopbits must be nil (1 stopbit), 1, or 2"); - summary[2] = XINT (tem) + '0'; + summary[2] = XFIXNUM (tem) + '0'; #if defined (CSTOPB) attr.c_cflag &= ~CSTOPB; - if (XINT (tem) == 2) + if (XFIXNUM (tem) == 2) attr.c_cflag |= CSTOPB; #else /* Don't error on 1 stopbit, which should be set by cfmakeraw. */ - if (XINT (tem) != 1) + if (XFIXNUM (tem) != 1) error ("Stopbits cannot be configured"); #endif childp2 = Fplist_put (childp2, QCstopbits, tem); @@ -3028,9 +3032,9 @@ list_system_processes (void) for (i = 0; i < len; i++) { #ifdef DARWIN_OS - proclist = Fcons (make_fixnum_or_float (procs[i].kp_proc.p_pid), proclist); + proclist = Fcons (INT_TO_INTEGER (procs[i].kp_proc.p_pid), proclist); #else - proclist = Fcons (make_fixnum_or_float (procs[i].ki_pid), proclist); + proclist = Fcons (INT_TO_INTEGER (procs[i].ki_pid), proclist); #endif } @@ -3051,6 +3055,22 @@ list_system_processes (void) #endif /* !defined (WINDOWSNT) */ + +#if defined __FreeBSD__ || defined DARWIN_OS + +static struct timespec +timeval_to_timespec (struct timeval t) +{ + return make_timespec (t.tv_sec, t.tv_usec * 1000); +} +static Lisp_Object +make_lisp_timeval (struct timeval t) +{ + return make_lisp_time (timeval_to_timespec (t)); +} + +#endif + #if defined GNU_LINUX && defined HAVE_LONG_LONG_INT static struct timespec time_from_jiffies (unsigned long long tval, long hz) @@ -3061,16 +3081,15 @@ time_from_jiffies (unsigned long long tval, long hz) if (TYPE_MAXIMUM (time_t) < s) time_overflow (); - if (LONG_MAX - 1 <= ULLONG_MAX / TIMESPEC_RESOLUTION - || frac <= ULLONG_MAX / TIMESPEC_RESOLUTION) - ns = frac * TIMESPEC_RESOLUTION / hz; + if (LONG_MAX - 1 <= ULLONG_MAX / TIMESPEC_HZ + || frac <= ULLONG_MAX / TIMESPEC_HZ) + ns = frac * TIMESPEC_HZ / hz; else { /* This is reachable only in the unlikely case that HZ * HZ exceeds ULLONG_MAX. It calculates an approximation that is guaranteed to be in range. */ - long hz_per_ns = (hz / TIMESPEC_RESOLUTION - + (hz % TIMESPEC_RESOLUTION != 0)); + long hz_per_ns = hz / TIMESPEC_HZ + (hz % TIMESPEC_HZ != 0); ns = frac / hz_per_ns; } @@ -3095,27 +3114,26 @@ get_up_time (void) if (fup) { - unsigned long long upsec, upfrac, idlesec, idlefrac; - int upfrac_start, upfrac_end, idlefrac_start, idlefrac_end; + unsigned long long upsec, upfrac; + int upfrac_start, upfrac_end; - if (fscanf (fup, "%llu.%n%llu%n %llu.%n%llu%n", - &upsec, &upfrac_start, &upfrac, &upfrac_end, - &idlesec, &idlefrac_start, &idlefrac, &idlefrac_end) - == 4) + if (fscanf (fup, "%llu.%n%llu%n", + &upsec, &upfrac_start, &upfrac, &upfrac_end) + == 2) { if (TYPE_MAXIMUM (time_t) < upsec) { upsec = TYPE_MAXIMUM (time_t); - upfrac = TIMESPEC_RESOLUTION - 1; + upfrac = TIMESPEC_HZ - 1; } else { int upfraclen = upfrac_end - upfrac_start; - for (; upfraclen < LOG10_TIMESPEC_RESOLUTION; upfraclen++) + for (; upfraclen < LOG10_TIMESPEC_HZ; upfraclen++) upfrac *= 10; - for (; LOG10_TIMESPEC_RESOLUTION < upfraclen; upfraclen--) + for (; LOG10_TIMESPEC_HZ < upfraclen; upfraclen--) upfrac /= 10; - upfrac = min (upfrac, TIMESPEC_RESOLUTION - 1); + upfrac = min (upfrac, TIMESPEC_HZ - 1); } up = make_timespec (upsec, upfrac); } @@ -3222,7 +3240,7 @@ system_process_attributes (Lisp_Object pid) struct group *gr; long clocks_per_sec; char *procfn_end; - char procbuf[1025], *p, *q; + char procbuf[1025], *p, *q UNINIT; int fd; ssize_t nread; static char const default_cmd[] = "???"; @@ -3244,7 +3262,7 @@ system_process_attributes (Lisp_Object pid) Lisp_Object decoded_cmd; ptrdiff_t count; - CHECK_NUMBER_OR_FLOAT (pid); + CHECK_NUMBER (pid); CONS_TO_INTEGER (pid, pid_t, proc_id); sprintf (procfn, "/proc/%"pMd, proc_id); if (stat (procfn, &st) < 0) @@ -3252,7 +3270,7 @@ system_process_attributes (Lisp_Object pid) /* euid egid */ uid = st.st_uid; - attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs); + attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (uid)), attrs); block_input (); pw = getpwuid (uid); unblock_input (); @@ -3260,7 +3278,7 @@ system_process_attributes (Lisp_Object pid) attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs); gid = st.st_gid; - attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs); + attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (gid)), attrs); block_input (); gr = getgrgid (gid); unblock_input (); @@ -3318,17 +3336,15 @@ system_process_attributes (Lisp_Object pid) state_str[0] = c; state_str[1] = '\0'; attrs = Fcons (Fcons (Qstate, build_string (state_str)), attrs); - attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (ppid)), attrs); - attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pgrp)), attrs); - attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (sess)), attrs); + attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (ppid)), attrs); + attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (pgrp)), attrs); + attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (sess)), attrs); attrs = Fcons (Fcons (Qttname, procfs_ttyname (tty)), attrs); - attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (tpgid)), attrs); - attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (minflt)), attrs); - attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (majflt)), attrs); - attrs = Fcons (Fcons (Qcminflt, make_fixnum_or_float (cminflt)), - attrs); - attrs = Fcons (Fcons (Qcmajflt, make_fixnum_or_float (cmajflt)), - attrs); + attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (tpgid)), attrs); + attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (minflt)), attrs); + attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (majflt)), attrs); + attrs = Fcons (Fcons (Qcminflt, INT_TO_INTEGER (cminflt)), attrs); + attrs = Fcons (Fcons (Qcmajflt, INT_TO_INTEGER (cmajflt)), attrs); clocks_per_sec = sysconf (_SC_CLK_TCK); if (clocks_per_sec < 0) clocks_per_sec = 100; @@ -3352,19 +3368,17 @@ system_process_attributes (Lisp_Object pid) ltime_from_jiffies (cstime + cutime, clocks_per_sec)), attrs); - attrs = Fcons (Fcons (Qpri, make_number (priority)), attrs); - attrs = Fcons (Fcons (Qnice, make_number (niceness)), attrs); - attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (thcount)), - attrs); + attrs = Fcons (Fcons (Qpri, make_fixnum (priority)), attrs); + attrs = Fcons (Fcons (Qnice, make_fixnum (niceness)), attrs); + attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (thcount)), attrs); tnow = current_timespec (); telapsed = get_up_time (); tboot = timespec_sub (tnow, telapsed); tstart = time_from_jiffies (start, clocks_per_sec); tstart = timespec_add (tboot, tstart); attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs); - attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (vsize / 1024)), - attrs); - attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (4 * rss)), attrs); + attrs = Fcons (Fcons (Qvsize, INT_TO_INTEGER (vsize / 1024)), attrs); + attrs = Fcons (Fcons (Qrss, INT_TO_INTEGER (4 * rss)), attrs); telapsed = timespec_sub (tnow, tstart); attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs); us_time = time_from_jiffies (u_time + s_time, clocks_per_sec); @@ -3405,7 +3419,7 @@ system_process_attributes (Lisp_Object pid) if (nread) { - /* We don't want trailing null characters. */ + /* We don't want trailing NUL characters. */ for (p = cmdline + nread; cmdline < p && !p[-1]; p--) continue; @@ -3478,7 +3492,7 @@ system_process_attributes (Lisp_Object pid) Lisp_Object decoded_cmd; ptrdiff_t count; - CHECK_NUMBER_OR_FLOAT (pid); + CHECK_NUMBER (pid); CONS_TO_INTEGER (pid, pid_t, proc_id); sprintf (procfn, "/proc/%"pMd, proc_id); if (stat (procfn, &st) < 0) @@ -3486,7 +3500,7 @@ system_process_attributes (Lisp_Object pid) /* euid egid */ uid = st.st_uid; - attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs); + attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (uid)), attrs); block_input (); pw = getpwuid (uid); unblock_input (); @@ -3494,7 +3508,7 @@ system_process_attributes (Lisp_Object pid) attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs); gid = st.st_gid; - attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs); + attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (gid)), attrs); block_input (); gr = getgrgid (gid); unblock_input (); @@ -3516,9 +3530,9 @@ system_process_attributes (Lisp_Object pid) if (nread == sizeof pinfo) { - attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (pinfo.pr_ppid)), attrs); - attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (pinfo.pr_pgid)), attrs); - attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (pinfo.pr_sid)), attrs); + attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (pinfo.pr_ppid)), attrs); + attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (pinfo.pr_pgid)), attrs); + attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (pinfo.pr_sid)), attrs); { char state_str[2]; @@ -3546,16 +3560,13 @@ system_process_attributes (Lisp_Object pid) attrs = Fcons (Fcons (Qtime, make_lisp_time (pinfo.pr_time)), attrs); attrs = Fcons (Fcons (Qctime, make_lisp_time (pinfo.pr_ctime)), attrs); - attrs = Fcons (Fcons (Qpri, make_number (pinfo.pr_lwp.pr_pri)), attrs); - attrs = Fcons (Fcons (Qnice, make_number (pinfo.pr_lwp.pr_nice)), attrs); - attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (pinfo.pr_nlwp)), - attrs); + attrs = Fcons (Fcons (Qpri, make_fixnum (pinfo.pr_lwp.pr_pri)), attrs); + attrs = Fcons (Fcons (Qnice, make_fixnum (pinfo.pr_lwp.pr_nice)), attrs); + attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (pinfo.pr_nlwp)), attrs); attrs = Fcons (Fcons (Qstart, make_lisp_time (pinfo.pr_start)), attrs); - attrs = Fcons (Fcons (Qvsize, make_fixnum_or_float (pinfo.pr_size)), - attrs); - attrs = Fcons (Fcons (Qrss, make_fixnum_or_float (pinfo.pr_rssize)), - attrs); + attrs = Fcons (Fcons (Qvsize, INT_TO_INTEGER (pinfo.pr_size)), attrs); + attrs = Fcons (Fcons (Qrss, INT_TO_INTEGER (pinfo.pr_rssize)), attrs); /* pr_pctcpu and pr_pctmem are unsigned integers in the range 0 .. 2**15, representing 0.0 .. 1.0. */ @@ -3575,24 +3586,11 @@ system_process_attributes (Lisp_Object pid) Vlocale_coding_system, 0); attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs); } - unbind_to (count, Qnil); - return attrs; + return unbind_to (count, attrs); } #elif defined __FreeBSD__ -static struct timespec -timeval_to_timespec (struct timeval t) -{ - return make_timespec (t.tv_sec, t.tv_usec * 1000); -} - -static Lisp_Object -make_lisp_timeval (struct timeval t) -{ - return make_lisp_time (timeval_to_timespec (t)); -} - Lisp_Object system_process_attributes (Lisp_Object pid) { @@ -3614,14 +3612,14 @@ system_process_attributes (Lisp_Object pid) Lisp_Object attrs = Qnil; Lisp_Object decoded_comm; - CHECK_NUMBER_OR_FLOAT (pid); + CHECK_NUMBER (pid); CONS_TO_INTEGER (pid, int, proc_id); mib[3] = proc_id; if (sysctl (mib, 4, &proc, &proclen, NULL, 0) != 0 || proclen == 0) return attrs; - attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (proc.ki_uid)), attrs); + attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (proc.ki_uid)), attrs); block_input (); pw = getpwuid (proc.ki_uid); @@ -3629,7 +3627,7 @@ system_process_attributes (Lisp_Object pid) if (pw) attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs); - attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (proc.ki_svgid)), attrs); + attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (proc.ki_svgid)), attrs); block_input (); gr = getgrgid (proc.ki_svgid); @@ -3668,9 +3666,9 @@ system_process_attributes (Lisp_Object pid) attrs = Fcons (Fcons (Qstate, build_string (state)), attrs); } - attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (proc.ki_ppid)), attrs); - attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (proc.ki_pgid)), attrs); - attrs = Fcons (Fcons (Qsess, make_fixnum_or_float (proc.ki_sid)), attrs); + attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.ki_ppid)), attrs); + attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.ki_pgid)), attrs); + attrs = Fcons (Fcons (Qsess, INT_TO_INTEGER (proc.ki_sid)), attrs); block_input (); ttyname = proc.ki_tdev == NODEV ? NULL : devname (proc.ki_tdev, S_IFCHR); @@ -3678,11 +3676,13 @@ system_process_attributes (Lisp_Object pid) if (ttyname) attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs); - attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (proc.ki_tpgid)), attrs); - attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (proc.ki_rusage.ru_minflt)), attrs); - attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (proc.ki_rusage.ru_majflt)), attrs); - attrs = Fcons (Fcons (Qcminflt, make_number (proc.ki_rusage_ch.ru_minflt)), attrs); - attrs = Fcons (Fcons (Qcmajflt, make_number (proc.ki_rusage_ch.ru_majflt)), attrs); + attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.ki_tpgid)), attrs); + attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (proc.ki_rusage.ru_minflt)), + attrs); + attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (proc.ki_rusage.ru_majflt)), + attrs); + attrs = Fcons (Fcons (Qcminflt, make_fixnum (proc.ki_rusage_ch.ru_minflt)), attrs); + attrs = Fcons (Fcons (Qcmajflt, make_fixnum (proc.ki_rusage_ch.ru_majflt)), attrs); attrs = Fcons (Fcons (Qutime, make_lisp_timeval (proc.ki_rusage.ru_utime)), attrs); @@ -3702,13 +3702,12 @@ system_process_attributes (Lisp_Object pid) timeval_to_timespec (proc.ki_rusage_ch.ru_stime)); attrs = Fcons (Fcons (Qctime, make_lisp_time (t)), attrs); - attrs = Fcons (Fcons (Qthcount, make_fixnum_or_float (proc.ki_numthreads)), - attrs); - attrs = Fcons (Fcons (Qpri, make_number (proc.ki_pri.pri_native)), attrs); - attrs = Fcons (Fcons (Qnice, make_number (proc.ki_nice)), attrs); + attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (proc.ki_numthreads)), attrs); + attrs = Fcons (Fcons (Qpri, make_fixnum (proc.ki_pri.pri_native)), attrs); + attrs = Fcons (Fcons (Qnice, make_fixnum (proc.ki_nice)), attrs); attrs = Fcons (Fcons (Qstart, make_lisp_timeval (proc.ki_start)), attrs); - attrs = Fcons (Fcons (Qvsize, make_number (proc.ki_size >> 10)), attrs); - attrs = Fcons (Fcons (Qrss, make_number (proc.ki_rssize * pagesize >> 10)), + attrs = Fcons (Fcons (Qvsize, make_fixnum (proc.ki_size >> 10)), attrs); + attrs = Fcons (Fcons (Qrss, make_fixnum (proc.ki_rssize * pagesize >> 10)), attrs); now = current_timespec (); @@ -3725,7 +3724,7 @@ system_process_attributes (Lisp_Object pid) { pcpu = (100.0 * proc.ki_pctcpu / fscale / (1 - exp (proc.ki_swtime * log ((double) ccpu / fscale)))); - attrs = Fcons (Fcons (Qpcpu, make_fixnum_or_float (pcpu)), attrs); + attrs = Fcons (Fcons (Qpcpu, INT_TO_INTEGER (pcpu)), attrs); } } @@ -3735,7 +3734,7 @@ system_process_attributes (Lisp_Object pid) double pmem = (proc.ki_flag & P_INMEM ? 100.0 * proc.ki_rssize / npages : 0); - attrs = Fcons (Fcons (Qpmem, make_fixnum_or_float (pmem)), attrs); + attrs = Fcons (Fcons (Qpmem, INT_TO_INTEGER (pmem)), attrs); } mib[2] = KERN_PROC_ARGS; @@ -3761,18 +3760,6 @@ system_process_attributes (Lisp_Object pid) #elif defined DARWIN_OS -static struct timespec -timeval_to_timespec (struct timeval t) -{ - return make_timespec (t.tv_sec, t.tv_usec * 1000); -} - -static Lisp_Object -make_lisp_timeval (struct timeval t) -{ - return make_lisp_time (timeval_to_timespec (t)); -} - Lisp_Object system_process_attributes (Lisp_Object pid) { @@ -3794,7 +3781,7 @@ system_process_attributes (Lisp_Object pid) Lisp_Object attrs = Qnil; Lisp_Object decoded_comm; - CHECK_NUMBER_OR_FLOAT (pid); + CHECK_NUMBER (pid); CONS_TO_INTEGER (pid, int, proc_id); mib[3] = proc_id; @@ -3802,7 +3789,7 @@ system_process_attributes (Lisp_Object pid) return attrs; uid = proc.kp_eproc.e_ucred.cr_uid; - attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs); + attrs = Fcons (Fcons (Qeuid, INT_TO_INTEGER (uid)), attrs); block_input (); pw = getpwuid (uid); @@ -3811,7 +3798,7 @@ system_process_attributes (Lisp_Object pid) attrs = Fcons (Fcons (Quser, build_string (pw->pw_name)), attrs); gid = proc.kp_eproc.e_pcred.p_svgid; - attrs = Fcons (Fcons (Qegid, make_fixnum_or_float (gid)), attrs); + attrs = Fcons (Fcons (Qegid, INT_TO_INTEGER (gid)), attrs); block_input (); gr = getgrgid (gid); @@ -3851,10 +3838,8 @@ system_process_attributes (Lisp_Object pid) attrs = Fcons (Fcons (Qstate, build_string (state)), attrs); } - attrs = Fcons (Fcons (Qppid, make_fixnum_or_float (proc.kp_eproc.e_ppid)), - attrs); - attrs = Fcons (Fcons (Qpgrp, make_fixnum_or_float (proc.kp_eproc.e_pgid)), - attrs); + attrs = Fcons (Fcons (Qppid, INT_TO_INTEGER (proc.kp_eproc.e_ppid)), attrs); + attrs = Fcons (Fcons (Qpgrp, INT_TO_INTEGER (proc.kp_eproc.e_pgid)), attrs); tdev = proc.kp_eproc.e_tdev; block_input (); @@ -3863,15 +3848,15 @@ system_process_attributes (Lisp_Object pid) if (ttyname) attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs); - attrs = Fcons (Fcons (Qtpgid, make_fixnum_or_float (proc.kp_eproc.e_tpgid)), + attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.kp_eproc.e_tpgid)), attrs); rusage = proc.kp_proc.p_ru; if (rusage) { - attrs = Fcons (Fcons (Qminflt, make_fixnum_or_float (rusage->ru_minflt)), + attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (rusage->ru_minflt)), attrs); - attrs = Fcons (Fcons (Qmajflt, make_fixnum_or_float (rusage->ru_majflt)), + attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (rusage->ru_majflt)), attrs); attrs = Fcons (Fcons (Qutime, make_lisp_timeval (rusage->ru_utime)), @@ -3884,7 +3869,7 @@ system_process_attributes (Lisp_Object pid) } starttime = proc.kp_proc.p_starttime; - attrs = Fcons (Fcons (Qnice, make_number (proc.kp_proc.p_nice)), attrs); + attrs = Fcons (Fcons (Qnice, make_fixnum (proc.kp_proc.p_nice)), attrs); attrs = Fcons (Fcons (Qstart, make_lisp_timeval (starttime)), attrs); now = current_timespec (); @@ -3905,6 +3890,42 @@ system_process_attributes (Lisp_Object pid) } #endif /* !defined (WINDOWSNT) */ + +DEFUN ("get-internal-run-time", Fget_internal_run_time, Sget_internal_run_time, + 0, 0, 0, + doc: /* Return the current run time used by Emacs. +The time is returned as in the style of `current-time'. + +On systems that can't determine the run time, `get-internal-run-time' +does the same thing as `current-time'. */) + (void) +{ +#ifdef HAVE_GETRUSAGE + struct rusage usage; + time_t secs; + int usecs; + + if (getrusage (RUSAGE_SELF, &usage) < 0) + /* This shouldn't happen. What action is appropriate? */ + xsignal0 (Qerror); + + /* Sum up user time and system time. */ + secs = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec; + usecs = usage.ru_utime.tv_usec + usage.ru_stime.tv_usec; + if (usecs >= 1000000) + { + usecs -= 1000000; + secs++; + } + return make_lisp_time (make_timespec (secs, usecs * 1000)); +#else /* ! HAVE_GETRUSAGE */ +#ifdef WINDOWSNT + return w32_get_internal_run_time (); +#else /* ! WINDOWSNT */ + return Fcurrent_time (); +#endif /* WINDOWSNT */ +#endif /* HAVE_GETRUSAGE */ +} /* Wide character string collation. */ @@ -4110,3 +4131,9 @@ str_collate (Lisp_Object s1, Lisp_Object s2, return res; } #endif /* WINDOWSNT */ + +void +syms_of_sysdep (void) +{ + defsubr (&Sget_internal_run_time); +} |