Page MenuHomeFreeBSD

D40281.id122463.diff
No OneTemporary

D40281.id122463.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
@@ -147,23 +147,53 @@
need_progress = 1;
}
-void
+static void
terminate(int signo)
{
-
kill_signal = signo;
+ summary();
+ (void)fflush(stderr);
+ raise(kill_signal);
+ /* NOT REACHED */
}
+static sigset_t blocked_sigset, orig_sigset;
+
void
-check_terminate(void)
+prepare_io(void)
{
+ struct sigaction sa;
+ int error;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_flags = SA_NODEFER | SA_RESETHAND;
+ sa.sa_handler = terminate;
+ error = sigaction(SIGINT, &sa, 0);
+ if (error != 0)
+ err(1, "sigaction");
+ sigemptyset(&blocked_sigset);
+ sigaddset(&blocked_sigset, SIGINT);
+ error = sigprocmask(SIG_BLOCK, &blocked_sigset, &orig_sigset);
+ if (error != 0)
+ err(1, "sigprocmask initial block");
+}
- if (kill_signal) {
- summary();
- (void)fflush(stderr);
- signal(kill_signal, SIG_DFL);
- raise(kill_signal);
- /* NOT REACHED */
- _exit(128 + kill_signal);
- }
+void
+before_io(void)
+{
+ int error;
+
+ error = sigprocmask(SIG_UNBLOCK, &blocked_sigset, &orig_sigset);
+ if (error != 0)
+ err(1, "sigprocmask unblock");
+}
+
+void
+after_io(void)
+{
+ int error;
+
+ error = sigprocmask(SIG_SETMASK, &orig_sigset, NULL);
+ if (error != 0)
+ err(1, "sigprocmask block");
}
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:41 PM (20 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14723261
Default Alt Text
D40281.id122463.diff (3 KB)

Event Timeline