[hackers] [ubase] dd: Use sigaction(2) to obviate select(2) || Eric Pruitt
commit 55795531f03ccb5a41cf80fd564b862c103252cc
Author: Eric Pruitt <eric.pruitt_AT_gmail.com>
AuthorDate: Tue Oct 10 16:27:27 2017 +0100
Commit: sin <sin_AT_2f30.org>
CommitDate: Tue Oct 10 16:28:15 2017 +0100
dd: Use sigaction(2) to obviate select(2)
By setting the SIGINT handler with sigaction(2), automatic retries of
the splice(2) syscall can be disabled by not setting SA_RESTART. This
makes it possible to use Ctrl+C even if the "if" operand refers to the
controlling terminal. The SIGINT message has also been moved outside
the signal handler since fprintf(3) is not an async-signal-safe
function.
diff --git a/dd.c b/dd.c
index cc05d40..2dce98e 100644
--- a/dd.c
+++ b/dd.c
_AT_@ -8,7 +8,6 @@
*/
#include <sys/ioctl.h>
#include <sys/mount.h>
-#include <sys/select.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
_AT_@ -38,6 +37,15 @@ struct dd_config {
static int sigint = 0;
+static void
+sig_int(int unused_1, siginfo_t *unused_2, void *unused_3)
+{
+ (void) unused_1;
+ (void) unused_2;
+ (void) unused_3;
+ sigint = 1;
+}
+
static int
prepare_copy(struct dd_config *ddc, int *ifd, int *ofd)
{
_AT_@ -147,7 +155,6 @@ copy_splice(struct dd_config *ddc)
int ifd, ofd, p[2] = {-1, -1};
ssize_t r = 0;
size_t n = 0;
- fd_set rfd, wfd;
if (prepare_copy(ddc, &ifd, &ofd) < 0)
return -1;
_AT_@ -165,27 +172,24 @@ copy_splice(struct dd_config *ddc)
#endif
n = ddc->bs;
for (;ddc->b_out != ddc->count && !sigint;) {
- FD_ZERO(&rfd);
- FD_ZERO(&wfd);
- FD_SET(ifd, &rfd);
- FD_SET(ofd, &wfd);
- r = select(ifd > ofd ? ifd + 1 : ofd + 1, &rfd, &wfd, NULL, NULL);
if (r < 0)
break;
- if (FD_ISSET(ifd, &rfd) == 1 && FD_ISSET(ofd, &wfd) == 1) {
- if (n > ddc->count - ddc->b_out)
- n = ddc->count - ddc->b_out;
- r = splice(ifd, NULL, p[1], NULL, n, SPLICE_F_MORE);
- if (r <= 0)
- break;
- ++ddc->rec_in;
- r = splice(p[0], NULL, ofd, NULL, r, SPLICE_F_MORE);
- if (r <= 0)
- break;
- ddc->b_out += r;
- ++ddc->rec_out;
- }
+ if (n > ddc->count - ddc->b_out)
+ n = ddc->count - ddc->b_out;
+ r = splice(ifd, NULL, p[1], NULL, n, SPLICE_F_MORE);
+ if (r <= 0)
+ break;
+ ++ddc->rec_in;
+ r = splice(p[0], NULL, ofd, NULL, r, SPLICE_F_MORE);
+ if (r <= 0)
+ break;
+ ddc->b_out += r;
+ ++ddc->rec_out;
}
+
+ if (sigint)
+ fprintf(stderr, "SIGINT! Aborting ...\n");
+
close(ifd);
close(ofd);
close(p[0]);
_AT_@ -227,14 +231,6 @@ print_stat(const struct dd_config *ddc)
}
static void
-sig_int(int unused)
-{
- (void) unused;
- fprintf(stderr, "SIGINT! Aborting ...\n");
- sigint = 1;
-}
-
-static void
usage(void)
{
eprintf("usage: %s [-h] [if=infile] [of=outfile] [bs[=N]] [seek=N] "
_AT_@ -248,6 +244,7 @@ main(int argc, char *argv[])
int i = 0;
char buf[1024];
struct dd_config config;
+ struct sigaction sa;
argv0 = argv[0];
memset(&config, 0, sizeof(config));
_AT_@ -286,7 +283,13 @@ main(int argc, char *argv[])
}
signal(SIGPIPE, SIG_IGN);
- signal(SIGINT, sig_int);
+
+ sa.sa_flags = SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_sigaction = sig_int;
+
+ if (sigaction(SIGINT, &sa, NULL) == -1)
+ weprintf("sigaction");
if (copy(&config) < 0)
weprintf("copy:");
Received on Tue Oct 10 2017 - 17:29:10 CEST
This archive was generated by hypermail 2.3.0
: Tue Oct 10 2017 - 17:36:44 CEST