/* Interfaces to system-dependent kernel and library entries.
- Copyright (C) 1985-1988, 1993-1995, 1999-2015 Free Software
+ Copyright (C) 1985-1988, 1993-1995, 1999-2016 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
#include "keyboard.h"
#include "frame.h"
-#include "window.h"
#include "termhooks.h"
#include "termchar.h"
#include "termopts.h"
-#include "dispextern.h"
#include "process.h"
-#include "cm.h" /* for reset_sys_modes */
+#include "cm.h"
+
+#include "gnutls.h"
+/* MS-Windows loads GnuTLS at run time, if available; we don't want to
+ do that during startup just to call gnutls_rnd. */
+#if 0x020c00 <= GNUTLS_VERSION_NUMBER && !defined WINDOWSNT
+# include <gnutls/crypto.h>
+#else
+# define emacs_gnutls_global_init() Qnil
+# define gnutls_rnd(level, data, len) (-1)
+#endif
#ifdef WINDOWSNT
#include <direct.h>
interrupts_deferred = 1;
#endif
}
-
-void
-ignore_sigio (void)
-{
-#ifdef USABLE_SIGIO
- signal (SIGIO, SIG_IGN);
-#endif
-}
\f
#ifndef MSDOS
/* Block SIGCHLD. */
xsignal0 (Qarith_error);
}
-#ifdef HAVE_STACK_OVERFLOW_HANDLING
+#if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT
/* Alternate stack used by SIGSEGV handler below. */
return sigaction (SIGSEGV, &sa, NULL) < 0 ? 0 : 1;
}
-#else /* not HAVE_STACK_OVERFLOW_HANDLING */
+#else /* not HAVE_STACK_OVERFLOW_HANDLING or WINDOWSNT */
static bool
init_sigsegv (void)
return 0;
}
-#endif /* HAVE_STACK_OVERFLOW_HANDLING */
+#endif /* HAVE_STACK_OVERFLOW_HANDLING && !WINDOWSNT */
static void
deliver_arith_signal (int sig)
# endif /* !HAVE_RANDOM */
#endif /* !RAND_BITS */
+#ifdef HAVE_RANDOM
+typedef unsigned int random_seed;
+static void set_random_seed (random_seed arg) { srandom (arg); }
+#elif defined HAVE_LRAND48
+/* Although srand48 uses a long seed, this is unsigned long to avoid
+ undefined behavior on signed integer overflow in init_random. */
+typedef unsigned long int random_seed;
+static void set_random_seed (random_seed arg) { srand48 (arg); }
+#else
+typedef unsigned int random_seed;
+static void set_random_seed (random_seed arg) { srand (arg); }
+#endif
+
void
seed_random (void *seed, ptrdiff_t seed_size)
{
-#if defined HAVE_RANDOM || ! defined HAVE_LRAND48
- unsigned int arg = 0;
-#else
- long int arg = 0;
-#endif
+ random_seed arg = 0;
unsigned char *argp = (unsigned char *) &arg;
unsigned char *seedp = seed;
- ptrdiff_t i;
- for (i = 0; i < seed_size; i++)
+ for (ptrdiff_t i = 0; i < seed_size; i++)
argp[i % sizeof arg] ^= seedp[i];
-#ifdef HAVE_RANDOM
- srandom (arg);
-#else
-# ifdef HAVE_LRAND48
- srand48 (arg);
-# else
- srand (arg);
-# endif
-#endif
+ set_random_seed (arg);
}
void
init_random (void)
{
- struct timespec t = current_timespec ();
- uintmax_t v = getpid () ^ t.tv_sec ^ t.tv_nsec;
- seed_random (&v, sizeof v);
+ random_seed v;
+ if (! (EQ (emacs_gnutls_global_init (), Qt)
+ && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0))
+ {
+ bool success = false;
+#ifndef WINDOWSNT
+ int fd = emacs_open ("/dev/urandom", O_RDONLY | O_BINARY, 0);
+ if (0 <= fd)
+ {
+ success = emacs_read (fd, &v, sizeof v) == sizeof v;
+ emacs_close (fd);
+ }
+#else
+ success = w32_init_random (&v, sizeof v) == 0;
+#endif
+ if (! success)
+ {
+ /* Fall back to current time value + PID. */
+ struct timespec t = current_timespec ();
+ v = getpid () ^ t.tv_sec ^ t.tv_nsec;
+ }
+ }
+ set_random_seed (v);
}
/*
list_system_processes (void)
{
Lisp_Object procdir, match, proclist, next;
- struct gcpro gcpro1, gcpro2;
- register Lisp_Object tail;
+ Lisp_Object tail;
- GCPRO2 (procdir, match);
/* For every process on the system, there's a directory in the
"/proc" pseudo-directory whose name is the numeric ID of that
process. */
next = XCDR (tail);
XSETCAR (tail, Fstring_to_number (XCAR (tail), Qnil));
}
- UNGCPRO;
/* directory_files_internal returns the files in reverse order; undo
that. */
struct kinfo_proc *procs;
size_t i;
- struct gcpro gcpro1;
Lisp_Object proclist = Qnil;
if (sysctl (mib, 3, NULL, &len, NULL, 0) != 0)
return proclist;
}
- GCPRO1 (proclist);
len /= sizeof (struct kinfo_proc);
for (i = 0; i < len; i++)
{
proclist = Fcons (make_fixnum_or_float (procs[i].ki_pid), proclist);
#endif
}
- UNGCPRO;
xfree (procs);
Lisp_Object attrs = Qnil;
Lisp_Object cmd_str, decoded_cmd;
ptrdiff_t count;
- struct gcpro gcpro1, gcpro2;
CHECK_NUMBER_OR_FLOAT (pid);
CONS_TO_INTEGER (pid, pid_t, proc_id);
if (stat (procfn, &st) < 0)
return attrs;
- GCPRO2 (attrs, decoded_cmd);
-
/* euid egid */
uid = st.st_uid;
attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs);
attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
}
- UNGCPRO;
return attrs;
}
gid_t gid;
Lisp_Object attrs = Qnil;
Lisp_Object decoded_cmd;
- struct gcpro gcpro1, gcpro2;
ptrdiff_t count;
CHECK_NUMBER_OR_FLOAT (pid);
if (stat (procfn, &st) < 0)
return attrs;
- GCPRO2 (attrs, decoded_cmd);
-
/* euid egid */
uid = st.st_uid;
attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (uid)), attrs);
attrs = Fcons (Fcons (Qargs, decoded_cmd), attrs);
}
unbind_to (count, Qnil);
- UNGCPRO;
return attrs;
}
struct kinfo_proc proc;
size_t proclen = sizeof proc;
- struct gcpro gcpro1, gcpro2;
Lisp_Object attrs = Qnil;
Lisp_Object decoded_comm;
if (sysctl (mib, 4, &proc, &proclen, NULL, 0) != 0)
return attrs;
- GCPRO2 (attrs, decoded_comm);
-
attrs = Fcons (Fcons (Qeuid, make_fixnum_or_float (proc.ki_uid)), attrs);
block_input ();
attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
}
- UNGCPRO;
return attrs;
}