[Pkg-privacy-commits] [libgsecuredelete] 05/25: Add support for pausing and resuming operations

Intrigeri intrigeri at moszumanska.debian.org
Wed Dec 7 17:10:34 UTC 2016


This is an automated email from the git hooks/post-receive script.

intrigeri pushed a commit to branch master
in repository libgsecuredelete.

commit 70f53c76b09f7bc883cf66b1b88625b13ef40f9a
Author: Colomban Wendling <ban at herbesfolles.org>
Date:   Fri Jul 15 00:53:41 2016 +0200

    Add support for pausing and resuming operations
    
    To implement it we send SIGSTOP/SIGCONT to the child.
    
    However, in order to support gsd-sfill-helper's grandchildren spawning
    we need not only to send the signal to the child but also the
    grandchildren.  As this is not directly possible, we set a separate
    PGID on the child, which allows us to use killpg() which does just what
    we want.  It even makes the wrapper script simpler, not having to proxy
    signal to its children itself, as they will now receive the signal
    directly.
---
 gsd-sfill-helper.sh.in                 | 26 ++--------------
 gsecuredelete/gsd-async-operation.vala | 54 +++++++++++++++++++++++++++++-----
 2 files changed, 49 insertions(+), 31 deletions(-)

diff --git a/gsd-sfill-helper.sh.in b/gsd-sfill-helper.sh.in
index a619bb9..9be3a7a 100644
--- a/gsd-sfill-helper.sh.in
+++ b/gsd-sfill-helper.sh.in
@@ -73,30 +73,10 @@ shift $(expr $OPTIND - 1)
 # don't leave the user with tons of temp files but a single directory
 dir=$(mktemp -d --tmpdir="$1") || die "$(gettext "failed to create temporary directory")"
 
-# runs a command asynchronously and wait for the trap handler to run
-# immediately.  the pid of the launched command is in $cmdpid
-#
-# this allows for trap handlers to run while the command is running rather than
-# to wait until command termination before running.  since we expect the user
-# to maybe kill us to abort, we better react immediately rather than waiting
-# for a command that can take several minutes to complete -- and that the user
-# wants to stop.
-cmdpid=
-launch_cmd() {
-  "$@" &
-  cmdpid=$!
-  wait $cmdpid
-  cmdpid=
-}
-
 cleanup() {
   echo "$(gettext 'Terminated by signal. Clean exit.')" >&2
   rm -rf '$dir'
   
-  # kill current background job if any
-  # using kill %1 would be better but it doesn't seem to work with dash
-  [ -n "$cmdpid" ] && kill $cmdpid
-  
   exit 1
 }
 
@@ -156,7 +136,7 @@ if [ -z "$OPT_i" ]; then
   while [ 1 ]; do
     file=$(mktemp --tmpdir="$dir") || die "failed to create temp file"
     
-    launch_cmd dd if="$input" of="$file" bs=8M conv=fdatasync 2>&1
+    dd if="$input" of="$file" bs=8M conv=fdatasync 2>&1
     
     # if the file we tried to create has size 0, guess there's actually no
     # space left on device
@@ -171,11 +151,11 @@ fi
 sfill_v=$OPT_v
 # don't report progress if we're also filling disk space
 [ -z "$OPT_i" ] && sfill_v=
-launch_cmd "$SFILL" $OPT_f $OPT_i $OPT_I $OPT_l $sfill_v $OPT_z "$dir"
+"$SFILL" $OPT_f $OPT_i $OPT_I $OPT_l $sfill_v $OPT_z "$dir"
 
 # and finally securely remove temporary files created earlier
 if [ -z "$OPT_i" ]; then
-  launch_cmd "$SRM" -r $OPT_f $OPT_l $OPT_z "$dir"
+  "$SRM" -r $OPT_f $OPT_l $OPT_z "$dir"
   
   progress_step
 fi
diff --git a/gsecuredelete/gsd-async-operation.vala b/gsecuredelete/gsd-async-operation.vala
index 6f1c8bc..4b5ca98 100644
--- a/gsecuredelete/gsd-async-operation.vala
+++ b/gsecuredelete/gsd-async-operation.vala
@@ -342,17 +342,12 @@ namespace Gsd
       return ! finished;
     }
     
-    /**
-     * Tries to cancel the operation.
-     * 
-     * @return true if successfully canceled, false otherwise.
-     */
-    public bool cancel ()
+    private bool signal_child (ProcessSignal signum)
       requires (this.busy)
     {
       int kill_status;
       
-      kill_status = Posix.kill ((Posix.pid_t)this.pid, ProcessSignal.TERM);
+      kill_status = Posix.killpg ((Posix.pid_t)this.pid, signum);
       if (kill_status < 0) {
         critical ("kill() failed: %s", strerror (errno));
       }
@@ -361,6 +356,49 @@ namespace Gsd
     }
     
     /**
+     * Tries to cancel the operation.
+     * 
+     * @return true if successfully canceled, false otherwise.
+     */
+    public bool cancel ()
+    {
+      return signal_child (ProcessSignal.TERM);
+    }
+    
+    /**
+     * Tries to pause the operation.
+     * 
+     * @return true if successfully paused, false otherwise.
+     */
+    public bool pause ()
+    {
+      return signal_child (ProcessSignal.STOP);
+    }
+    
+    /**
+     * Tries to resume the operation.
+     * 
+     * @return true if successfully resumed, false otherwise.
+     */
+    public bool resume ()
+    {
+      return signal_child (ProcessSignal.CONT);
+    }
+    
+    private void child_setup ()
+    {
+      /* Set the process group ID (PGID) of the child to its PID.
+       * This allows us to use killpg(), which is needed if we want to be able
+       * to stop grandchildren (assuming they didn't live the group).
+       * 
+       * We need this for the gsd-sfill-helper case so we can send SIGSTOP not
+       * only to the controlling script but also all its asynchronous children.
+       * It also simplifies the script implementation for cancellation as it
+       * allows us to cancel all children at once ourselves. */
+      Posix.setpgid (0, 0);
+    }
+    
+    /**
      * Launches an operation asynchronously.
      * 
      * @param working_directory the working directory of the child process, or
@@ -391,7 +429,7 @@ namespace Gsd
         this.passes = 0;
         success = Process.spawn_async_with_pipes (
           working_directory, this.do_build_args (), this.build_env (),
-          spawn_flags | SpawnFlags.DO_NOT_REAP_CHILD, null,
+          spawn_flags | SpawnFlags.DO_NOT_REAP_CHILD, this.child_setup,
           out this.pid, out this.fd_in, out this.fd_out, out this.fd_err
         );
         if (success) {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/libgsecuredelete.git



More information about the Pkg-privacy-commits mailing list