From: Lennart Poettering Date: Fri, 26 Feb 2021 14:10:24 +0000 (+0100) Subject: copy: add COPY_SIGTERM, matching the existing COPY_SIGINT X-Git-Tag: v250-rc1~887^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1ac404cac095f1aaf581b107895e8b06fa8db6d0;p=thirdparty%2Fsystemd.git copy: add COPY_SIGTERM, matching the existing COPY_SIGINT --- diff --git a/src/shared/copy.c b/src/shared/copy.c index e47b56ce915..a01b6df1b22 100644 --- a/src/shared/copy.c +++ b/src/shared/copy.c @@ -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; diff --git a/src/shared/copy.h b/src/shared/copy.h index 0c81760d8fd..f8992843e45 100644 --- a/src/shared/copy.h +++ b/src/shared/copy.h @@ -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);