summaryrefslogtreecommitdiff
path: root/src/sysdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sysdep.c')
-rw-r--r--src/sysdep.c414
1 files changed, 227 insertions, 187 deletions
diff --git a/src/sysdep.c b/src/sysdep.c
index 1e35e06b633..a477ec892ec 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -91,13 +91,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 +124,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 +150,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);
+ }
+
+ /* 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);
+ }
- /* 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);
+ return argc;
}
#endif
@@ -174,21 +207,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. */
@@ -1496,18 +1520,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 +1695,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
@@ -2554,6 +2578,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 +2602,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 +2728,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 +2850,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 +2862,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 +2916,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 +3045,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 +3068,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 +3094,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 +3127,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 +3253,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 +3275,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 +3283,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 +3291,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 +3349,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 +3381,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);
@@ -3478,7 +3505,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 +3513,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 +3521,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 +3543,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 +3573,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 +3599,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 +3625,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)
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 +3640,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 +3679,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 +3689,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 +3715,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 +3737,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 +3747,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 +3773,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 +3794,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 +3802,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 +3811,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 +3851,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 +3861,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 +3882,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 +3903,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 +4144,9 @@ str_collate (Lisp_Object s1, Lisp_Object s2,
return res;
}
#endif /* WINDOWSNT */
+
+void
+syms_of_sysdep (void)
+{
+ defsubr (&Sget_internal_run_time);
+}