]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
copy: add COPY_SIGTERM, matching the existing COPY_SIGINT
authorLennart Poettering <lennart@poettering.net>
Fri, 26 Feb 2021 14:10:24 +0000 (15:10 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 2 Aug 2021 15:24:18 +0000 (17:24 +0200)
src/shared/copy.c
src/shared/copy.h

index e47b56ce915f2e97de8671767b3d08d7d51be865..a01b6df1b22354f86ab9dc49f5d2b4d949702752 100644 (file)
@@ -88,6 +88,23 @@ static int fd_is_nonblock_pipe(int fd) {
         return FLAGS_SET(flags, O_NONBLOCK) ? FD_IS_NONBLOCKING_PIPE : FD_IS_BLOCKING_PIPE;
 }
 
+static int look_for_signals(CopyFlags copy_flags) {
+        int r;
+
+        if ((copy_flags & (COPY_SIGINT|COPY_SIGTERM)) == 0)
+                return 0;
+
+        r = pop_pending_signal(copy_flags & COPY_SIGINT ? SIGINT : 0,
+                               copy_flags & COPY_SIGTERM ? SIGTERM : 0);
+        if (r < 0)
+                return r;
+        if (r != 0)
+                return log_debug_errno(SYNTHETIC_ERRNO(EINTR),
+                                       "Got %s, cancelling copy operation.", signal_to_string(r));
+
+        return 0;
+}
+
 int copy_bytes_full(
                 int fdf, int fdt,
                 uint64_t max_bytes,
@@ -176,13 +193,9 @@ int copy_bytes_full(
                 if (max_bytes <= 0)
                         return 1; /* return > 0 if we hit the max_bytes limit */
 
-                if (FLAGS_SET(copy_flags, COPY_SIGINT)) {
-                        r = pop_pending_signal(SIGINT);
-                        if (r < 0)
-                                return r;
-                        if (r > 0)
-                                return -EINTR;
-                }
+                r = look_for_signals(copy_flags);
+                if (r < 0)
+                        return r;
 
                 if (max_bytes != UINT64_MAX && m > max_bytes)
                         m = max_bytes;
@@ -852,13 +865,9 @@ static int fd_copy_directory(
                 if (dot_or_dot_dot(de->d_name))
                         continue;
 
-                if (FLAGS_SET(copy_flags, COPY_SIGINT)) {
-                        r = pop_pending_signal(SIGINT);
-                        if (r < 0)
-                                return r;
-                        if (r > 0)
-                                return -EINTR;
-                }
+                r = look_for_signals(copy_flags);
+                if (r < 0)
+                        return r;
 
                 if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) {
                         r = -errno;
@@ -919,7 +928,7 @@ static int fd_copy_directory(
                 else
                         q = -EOPNOTSUPP;
 
-                if (q == -EINTR) /* Propagate SIGINT up instantly */
+                if (q == -EINTR) /* Propagate SIGINT/SIGTERM up instantly */
                         return q;
                 if (q == -EEXIST && (copy_flags & COPY_MERGE))
                         q = 0;
index 0c81760d8fd2b0221c6b73f6b47e49b2ec842f77..f8992843e4594f78a52d548d58e8e0c16cfd10b9 100644 (file)
@@ -17,11 +17,12 @@ typedef enum CopyFlags {
         COPY_MERGE_EMPTY = 1 << 4,  /* Merge an existing, empty directory with our new tree to copy */
         COPY_CRTIME      = 1 << 5,  /* Generate a user.crtime_usec xattr off the source crtime if there is one, on copying */
         COPY_SIGINT      = 1 << 6,  /* Check for SIGINT regularly and return EINTR if seen (caller needs to block SIGINT) */
-        COPY_MAC_CREATE  = 1 << 7,  /* Create files with the correct MAC label (currently SELinux only) */
-        COPY_HARDLINKS   = 1 << 8,  /* Try to reproduce hard links */
-        COPY_FSYNC       = 1 << 9,  /* fsync() after we are done */
-        COPY_FSYNC_FULL  = 1 << 10, /* fsync_full() after we are done */
-        COPY_SYNCFS      = 1 << 11, /* syncfs() the *top-level* dir after we are done */
+        COPY_SIGTERM     = 1 << 7,  /* ditto, but for SIGTERM */
+        COPY_MAC_CREATE  = 1 << 8,  /* Create files with the correct MAC label (currently SELinux only) */
+        COPY_HARDLINKS   = 1 << 9,  /* Try to reproduce hard links */
+        COPY_FSYNC       = 1 << 10, /* fsync() after we are done */
+        COPY_FSYNC_FULL  = 1 << 11, /* fsync_full() after we are done */
+        COPY_SYNCFS      = 1 << 12, /* syncfs() the *top-level* dir after we are done */
 } CopyFlags;
 
 typedef int (*copy_progress_bytes_t)(uint64_t n_bytes, void *userdata);