Make it build\!
[become] / src / noise.c
index 88b4de5..2945be0 100644 (file)
@@ -1,10 +1,10 @@
 /* -*-c-*-
  *
- * $Id: noise.c,v 1.2 1997/08/20 16:19:57 mdw Exp $
+ * $Id: noise.c,v 1.6 1998/06/18 15:08:14 mdw Exp $
  *
  * Collection of environmental noise
  *
- * (c) 1997 EBI
+ * (c) 1998 EBI
  */
 
 /*----- Licensing notice --------------------------------------------------*
 /*----- Revision history --------------------------------------------------*
  *
  * $Log: noise.c,v $
- * Revision 1.2  1997/08/20 16:19:57  mdw
+ * Revision 1.6  1998/06/18 15:08:14  mdw
+ * Improve signal handling when accumulating noise from child processes.
+ *
+ * Revision 1.5  1998/04/23 13:25:23  mdw
+ * Try to reduce the amount of `ps'ing done under OSF/1, because /dev/kmem
+ * seems very slow.
+ *
+ * Revision 1.4  1998/02/20 17:52:32  mdw
+ * Don't use `df' for noise gathering, because it gets upset when NFS
+ * servers aren't responding.
+ *
+ * Revision 1.3  1998/01/12 16:46:19  mdw
+ * Fix copyright date.
+ *
+ * Revision 1.2  1997/08/20  16:19:57  mdw
  * Fix test for `/dev/random' so that it doesn't close `stdin' if it fails!
  *
  * Revision 1.1  1997/08/07 09:45:26  mdw
@@ -44,6 +58,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -89,16 +104,36 @@ static void noise__shell(const char *cmd)
   int pfd[2];
   pid_t pid;
 
+#ifdef HAVE_SIGPROCMASK
+  sigset_t ob, nb;
+#endif
+
   /* --- Create a pipe for talking to the child --- */
 
   if (pipe(pfd))
     return;
 
+  /* --- Sort out the signal handling for the parent --- *
+   *
+   * Block @SIGCHLD@ while this is going on.  Unlike the standard @system@
+   * function, I won't disable @SIGINT@ and @SIGQUIT@.  Then, if the user
+   * stops the child with a terminal signal, the parent (i.e., me) gets
+   * killed too, and I don't end up with a tiny dribble of entropy when I'm
+   * expecting quite a lot.
+   */
+
+#ifdef HAVE_SIGPROCMASK
+  sigemptyset(&nb);
+  sigaddset(&nb, SIGCHLD);
+  if (sigprocmask(SIG_BLOCK, &nb, &ob))
+    goto fail_0;
+#endif
+
   /* --- Create the child process --- */
 
   pid = fork();
   if (pid < 0)
-    return;
+    goto fail_1;
 
   if (pid == 0) {
     int fd;
@@ -108,9 +143,22 @@ static void noise__shell(const char *cmd)
       0
     };
 
-    /* --- Become whoever I'm being run as --- */
+    /* --- Restore signal handling things --- */
+
+#ifdef HAVE_SIGPROCMASK
+    sigprocmask(SIG_SETMASK, &nb, 0);
+#endif
+
+    /* --- Become nobody --- *
+     *
+     * This assumes that @-2@ is a safe user to be.  It shouldn't be root,
+     * because it doesn't need to be, and nothing should be done as root
+     * which could be done as someone else.  It shouldn't be the user who
+     * invoked me, because that would enable her to kill the children before
+     * I've read enough entropy from them, and that wouldn't be good.
+     */
 
-    setuid(getuid());
+    setuid(-2);
 
     /* --- Close the old standard streams --- */
 
@@ -166,11 +214,18 @@ static void noise__shell(const char *cmd)
 
   {
     int st;
-
     wait(&st);
     rand_add(&st, sizeof(st));
     rand_add(&pid, sizeof(pid));
   }
+
+  /* --- Restore signals --- */
+
+fail_1:
+#ifdef HAVE_SIGPROCMASK
+  sigprocmask(SIG_SETMASK, &ob, 0);
+#endif
+fail_0:;
 }
 
 /* --- @noise_acquire@ --- *
@@ -225,10 +280,7 @@ void noise_acquire(void)
 
   /* --- Try some commands which ask the outside world some questions --- */
 
-  noise__shell("ps auxww");
-  noise__shell("ps -ef");
-  noise__shell("df");
-  /* @noise__shell("netstat -a");@ -- takes too long */
+  noise__shell("ps auxww || ps -ef; netstat -an");
 
   /* --- Get our resource usage to see if that's at all interesting --- */