Page MenuHomeFreeBSD

D39641.id121290.diff
No OneTemporary

D39641.id121290.diff

diff --git a/bin/dd/dd.c b/bin/dd/dd.c
--- a/bin/dd/dd.c
+++ b/bin/dd/dd.c
@@ -64,6 +64,7 @@
#include <fcntl.h>
#include <inttypes.h>
#include <locale.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -91,12 +92,16 @@
size_t speed = 0; /* maximum speed, in bytes per second */
volatile sig_atomic_t need_summary;
volatile sig_atomic_t need_progress;
+volatile sig_atomic_t kill_signal;
int
main(int argc __unused, char *argv[])
{
struct itimerval itv = { { 1, 0 }, { 1, 0 } }; /* SIGALARM every second, if needed */
+ (void)siginterrupt(SIGINT, 1);
+ (void)signal(SIGINT, terminate);
+
(void)setlocale(LC_CTYPE, "");
jcl(argv);
setup();
@@ -110,7 +115,6 @@
(void)signal(SIGALRM, sigalarm_handler);
setitimer(ITIMER_REAL, &itv, NULL);
}
- (void)signal(SIGINT, terminate);
atexit(summary);
@@ -154,7 +158,9 @@
iflags = 0;
if (ddflags & C_IDIRECT)
iflags |= O_DIRECT;
+ check_terminate();
in.fd = open(in.name, O_RDONLY | iflags, 0);
+ check_terminate();
if (in.fd == -1)
err(1, "%s", in.name);
}
@@ -191,7 +197,9 @@
oflags |= O_FSYNC;
if (ddflags & C_ODIRECT)
oflags |= O_DIRECT;
+ check_terminate();
out.fd = open(out.name, O_RDWR | oflags, DEFFILEMODE);
+ check_terminate();
/*
* May not have read access, so try again with write only.
* Without read we may have a problem if output also does
@@ -199,6 +207,7 @@
*/
if (out.fd == -1) {
out.fd = open(out.name, O_WRONLY | oflags, DEFFILEMODE);
+ check_terminate();
out.flags |= NOREAD;
cap_rights_clear(&rights, CAP_READ);
}
@@ -415,7 +424,9 @@
in.dbrcnt = 0;
fill:
+ check_terminate();
n = read(in.fd, in.dbp + in.dbrcnt, in.dbsz - in.dbrcnt);
+ check_terminate();
/* EOF */
if (n == 0 && in.dbrcnt == 0)
@@ -596,7 +607,9 @@
pending = 0;
}
if (cnt) {
+ check_terminate();
nw = write(out.fd, outp, cnt);
+ check_terminate();
out.seek_offset = 0;
} else {
return;
diff --git a/bin/dd/extern.h b/bin/dd/extern.h
--- a/bin/dd/extern.h
+++ b/bin/dd/extern.h
@@ -50,6 +50,7 @@
void sigalarm_handler(int);
void siginfo_handler(int);
void terminate(int);
+void check_terminate(void);
void unblock(void);
void unblock_close(void);
@@ -69,3 +70,4 @@
extern char fill_char;
extern volatile sig_atomic_t need_summary;
extern volatile sig_atomic_t need_progress;
+extern volatile sig_atomic_t kill_signal;
diff --git a/bin/dd/misc.c b/bin/dd/misc.c
--- a/bin/dd/misc.c
+++ b/bin/dd/misc.c
@@ -147,11 +147,23 @@
need_progress = 1;
}
-/* ARGSUSED */
void
-terminate(int sig)
+terminate(int signo)
{
- summary();
- _exit(sig == 0 ? 0 : 1);
+ kill_signal = signo;
+}
+
+void
+check_terminate(void)
+{
+
+ if (kill_signal) {
+ summary();
+ (void)fflush(stderr);
+ signal(kill_signal, SIG_DFL);
+ raise(kill_signal);
+ /* NOT REACHED */
+ _exit(128 + kill_signal);
+ }
}
diff --git a/bin/dd/position.c b/bin/dd/position.c
--- a/bin/dd/position.c
+++ b/bin/dd/position.c
@@ -191,9 +191,10 @@
/* Read it. */
for (cnt = 0; cnt < out.offset; ++cnt) {
+ check_terminate();
if ((n = read(out.fd, out.db, out.dbsz)) > 0)
continue;
-
+ check_terminate();
if (n == -1)
err(1, "%s", out.name);
@@ -208,7 +209,9 @@
err(1, "%s", out.name);
while (cnt++ < out.offset) {
+ check_terminate();
n = write(out.fd, out.db, out.dbsz);
+ check_terminate();
if (n == -1)
err(1, "%s", out.name);
if (n != out.dbsz)
diff --git a/bin/dd/tests/dd2_test.sh b/bin/dd/tests/dd2_test.sh
--- a/bin/dd/tests/dd2_test.sh
+++ b/bin/dd/tests/dd2_test.sh
@@ -1,5 +1,6 @@
#
# Copyright (c) 2017 Spectra Logic Corporation
+# Copyright (c) 2023 Klara, Inc.
#
# SPDX-License-Identifier: BSD-2-Clause
#
@@ -46,8 +47,51 @@
dd if=f.in of=f.out bs=4096 seek=-1
}
+atf_test_case sigint
+sigint_open_head()
+{
+ atf_set "descr" "SIGINT while opening destination"
+}
+sigint_open_body()
+{
+ atf_check mkfifo fifo
+ set -m
+ dd if=fifo of=/dev/null 2>stderr &
+ pid=$!
+ sleep 3
+ kill -INT $pid
+ wait $pid
+ rv=$?
+ atf_check test "$rv" -gt 128
+ atf_check -o inline:"INT\n" kill -l $((rv-128))
+ atf_check test -s stderr
+}
+
+atf_test_case sigint
+sigint_read_head()
+{
+ atf_set "descr" "SIGINT while reading source"
+}
+sigint_read_body()
+{
+ atf_check mkfifo fifo
+ (sleep 30 >fifo &) # ensures that dd does not block on open
+ set -m
+ dd if=fifo of=/dev/null 2>stderr &
+ pid=$!
+ sleep 3
+ kill -INT $pid
+ wait $pid
+ rv=$?
+ atf_check test "$rv" -gt 128
+ atf_check -o inline:"INT\n" kill -l $((rv-128))
+ atf_check test -s stderr
+}
+
atf_init_test_cases()
{
atf_add_test_case max_seek
atf_add_test_case seek_overflow
+ atf_add_test_case sigint_open
+ atf_add_test_case sigint_read
}

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 18, 6:43 PM (8 m, 43 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14702935
Default Alt Text
D39641.id121290.diff (4 KB)

Event Timeline