Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102833697
D39641.id121290.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D39641.id121290.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D39641: dd: Fix SIGINT handling.
Attached
Detach File
Event Timeline
Log In to Comment