Page MenuHomeFreeBSD

D40281.id122727.diff
No OneTemporary

D40281.id122727.diff

diff --git a/bin/dd/dd.c b/bin/dd/dd.c
--- a/bin/dd/dd.c
+++ b/bin/dd/dd.c
@@ -99,8 +99,7 @@
{
struct itimerval itv = { { 1, 0 }, { 1, 0 } }; /* SIGALARM every second, if needed */
- (void)siginterrupt(SIGINT, 1);
- (void)signal(SIGINT, terminate);
+ prepare_io();
(void)setlocale(LC_CTYPE, "");
jcl(argv);
@@ -158,9 +157,9 @@
iflags = 0;
if (ddflags & C_IDIRECT)
iflags |= O_DIRECT;
- check_terminate();
+ before_io();
in.fd = open(in.name, O_RDONLY | iflags, 0);
- check_terminate();
+ after_io();
if (in.fd == -1)
err(1, "%s", in.name);
}
@@ -197,17 +196,18 @@
oflags |= O_FSYNC;
if (ddflags & C_ODIRECT)
oflags |= O_DIRECT;
- check_terminate();
+ before_io();
out.fd = open(out.name, O_RDWR | oflags, DEFFILEMODE);
- check_terminate();
+ after_io();
/*
* May not have read access, so try again with write only.
* Without read we may have a problem if output also does
* not support seeks.
*/
if (out.fd == -1) {
+ before_io();
out.fd = open(out.name, O_WRONLY | oflags, DEFFILEMODE);
- check_terminate();
+ after_io();
out.flags |= NOREAD;
cap_rights_clear(&rights, CAP_READ);
}
@@ -424,9 +424,9 @@
in.dbrcnt = 0;
fill:
- check_terminate();
+ before_io();
n = read(in.fd, in.dbp + in.dbrcnt, in.dbsz - in.dbrcnt);
- check_terminate();
+ after_io();
/* EOF */
if (n == 0 && in.dbrcnt == 0)
@@ -607,9 +607,9 @@
pending = 0;
}
if (cnt) {
- check_terminate();
+ before_io();
nw = write(out.fd, outp, cnt);
- check_terminate();
+ after_io();
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
@@ -49,8 +49,9 @@
void summary(void);
void sigalarm_handler(int);
void siginfo_handler(int);
-void terminate(int);
-void check_terminate(void);
+void prepare_io(void);
+void before_io(void);
+void after_io(void);
void unblock(void);
void unblock_close(void);
diff --git a/bin/dd/misc.c b/bin/dd/misc.c
--- a/bin/dd/misc.c
+++ b/bin/dd/misc.c
@@ -48,6 +48,7 @@
#include <inttypes.h>
#include <libutil.h>
#include <signal.h>
+#include <stdatomic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -147,23 +148,58 @@
need_progress = 1;
}
-void
+static void terminate(int signo) __dead2;
+static void
terminate(int signo)
{
-
kill_signal = signo;
+ summary();
+ (void)fflush(stderr);
+ raise(kill_signal);
+ /* NOT REACHED */
+ _exit(1);
+}
+
+static sig_atomic_t in_io = 0;
+static sig_atomic_t sigint_seen = 0;
+
+static void
+sigint_handler(int signo __unused)
+{
+ atomic_signal_fence(memory_order_acquire);
+ if (in_io)
+ terminate(SIGINT);
+ sigint_seen = 1;
+}
+
+void
+prepare_io(void)
+{
+ struct sigaction sa;
+ int error;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_flags = SA_NODEFER | SA_RESETHAND;
+ sa.sa_handler = sigint_handler;
+ error = sigaction(SIGINT, &sa, 0);
+ if (error != 0)
+ err(1, "sigaction");
}
void
-check_terminate(void)
+before_io(void)
{
+ in_io = 1;
+ atomic_signal_fence(memory_order_seq_cst);
+ if (sigint_seen)
+ terminate(SIGINT);
+}
- if (kill_signal) {
- summary();
- (void)fflush(stderr);
- signal(kill_signal, SIG_DFL);
- raise(kill_signal);
- /* NOT REACHED */
- _exit(128 + kill_signal);
- }
+void
+after_io(void)
+{
+ in_io = 0;
+ atomic_signal_fence(memory_order_seq_cst);
+ if (sigint_seen)
+ terminate(SIGINT);
}
diff --git a/bin/dd/position.c b/bin/dd/position.c
--- a/bin/dd/position.c
+++ b/bin/dd/position.c
@@ -191,10 +191,11 @@
/* Read it. */
for (cnt = 0; cnt < out.offset; ++cnt) {
- check_terminate();
- if ((n = read(out.fd, out.db, out.dbsz)) > 0)
+ before_io();
+ n = read(out.fd, out.db, out.dbsz);
+ after_io();
+ if (n > 0)
continue;
- check_terminate();
if (n == -1)
err(1, "%s", out.name);
@@ -209,9 +210,9 @@
err(1, "%s", out.name);
while (cnt++ < out.offset) {
- check_terminate();
+ before_io();
n = write(out.fd, out.db, out.dbsz);
- check_terminate();
+ after_io();
if (n == -1)
err(1, "%s", out.name);
if (n != out.dbsz)

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 19, 8:33 PM (20 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14723169
Default Alt Text
D40281.id122727.diff (4 KB)

Event Timeline