changeset 719:428df726cf7f

Have system-image.sh do its own setsid variant so when it does dienow() it can kill all its own backgrounded processes, but won't take down the parent shell that ran it.
author Rob Landley <rob@landley.net>
date Fri, 24 Apr 2009 22:33:31 -0500
parents f63119db5afa
children 74850275fe41
files build.sh sources/toys/mysetsid.c system-image.sh
diffstat 3 files changed, 34 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/build.sh	Sun Apr 19 06:24:23 2009 -0500
+++ b/build.sh	Fri Apr 24 22:33:31 2009 -0500
@@ -43,9 +43,6 @@
   then
     echo "=== Skipping system-image-$i (already there)"
   else
-    # We need to run this in a new session because the error handling behavior
-    # of this kills everything in its current session, which can kill a wrapper
-    # shell running us if we're not careful.
-    time setsid ./system-image.sh $i || exit 1
+    time ./system-image.sh $i || exit 1
   fi
 done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sources/toys/mysetsid.c	Fri Apr 24 22:33:31 2009 -0500
@@ -0,0 +1,14 @@
+#include <unistd.h>
+
+// This is a more thorough version of setsid, which sets up both a session
+// ID and a process group, and points the stdin signal handling to the new
+// process group.
+
+int main(int argc, char *argv[])
+{
+  setsid();
+  setpgid(0,0);
+  tcsetpgrp(0, getpid());
+  if (argc>1) execvp(argv[1], argv+1);
+  return 127;
+}
--- a/system-image.sh	Sun Apr 19 06:24:23 2009 -0500
+++ b/system-image.sh	Fri Apr 24 22:33:31 2009 -0500
@@ -4,6 +4,21 @@
 
 source sources/include.sh || exit 1
 
+# A little song and dance so we run in our own session, to prevent the "kill 0"
+# below from taking down the shell that called us.
+
+if [ -z "$SYSTEM_IMAGE_SETSID" ]
+then
+  export SYSTEM_IMAGE_SETSID=1
+
+  # Can't use setsid because it does setsid() but not setpgrp() or tcsetpgrp()
+  # so stdin's signal handling doesn't get moved to the new session id, so
+  # ctrl-c won't work.  This little C program does it right.
+
+  $CC -s -Os "$SOURCES/toys/mysetsid.c" -o "$WORK/mysetsid" &&
+  exec "$WORK/mysetsid" "$0" "$@"
+fi
+
 echo -e "$PACKAGE_COLOR"
 echo "=== Packaging system image from root-filesystem"
 
@@ -42,14 +57,16 @@
     $VERBOSITY || dienow ) &
 
 # If we exit before removing this handler, kill everything in the current
-# process group, which should take out backgrounded kernel make.
+# process group, which should take out backgrounded kernel make no matter
+# how many child processes it's spawned.
 trap "kill 0" EXIT
 
 # Embed an initramfs image in the kernel?
 
+echo "Generating root filesystem of type: $SYSIMAGE_TYPE"
+
 if [ "$SYSIMAGE_TYPE" == "initramfs" ]
 then
-  echo "Generating initramfs (in background)"
   $CC usr/gen_init_cpio.c -o my_gen_init_cpio || dienow
   (./my_gen_init_cpio <(
       "$SOURCES"/toys/gen_initramfs_list.sh "$NATIVE_ROOT"
@@ -86,8 +103,6 @@
   # directory, with a temporary file defining the /dev nodes for the new
   # filesystem.
 
-  echo "Generating ext2 image (in background)"
-
   [ -z "$SYSIMAGE_HDA_MEGS" ] && SYSIMAGE_HDA_MEGS=64
 
   IMAGE="image-${ARCH}.ext2"
@@ -118,8 +133,6 @@
 
 elif [ "$SYSIMAGE_TYPE" == "squashfs" ]
 then
-  echo "Creating squashfs image (in background)"
-
   IMAGE="image-${ARCH}.sqf"
   mksquashfs "${NATIVE_ROOT}" "$SYSIMAGE/$IMAGE" -noappend -all-root \
     -no-progress || dienow