From: Sami Kerola <kerolasa@iki.fi>
To: util-linux@vger.kernel.org
Cc: Sami Kerola <kerolasa@iki.fi>, Wolfgang Richter <wolf@cs.cmu.edu>,
Ruediger Meier <ruediger.meier@ga-group.nl>
Subject: [PATCH 15/22] script: use signalfd() to catch signals
Date: Sat, 27 Dec 2014 17:17:28 +0000 [thread overview]
Message-ID: <1419700655-19107-2-git-send-email-kerolasa@iki.fi> (raw)
In-Reply-To: <1419700655-19107-1-git-send-email-kerolasa@iki.fi>
This is incomplete change. Working command requires the subsequent
select() to poll() change as well.
Addresses: https://github.com/karelzak/util-linux/pull/62
CC: Wolfgang Richter <wolf@cs.cmu.edu>
CC: Ruediger Meier <ruediger.meier@ga-group.nl>
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
term-utils/script.c | 47 ++++++++++++++---------------------------------
1 file changed, 14 insertions(+), 33 deletions(-)
diff --git a/term-utils/script.c b/term-utils/script.c
index 8f59fe8..315c46b 100644
--- a/term-utils/script.c
+++ b/term-utils/script.c
@@ -63,6 +63,8 @@
#include <stddef.h>
#include <sys/wait.h>
#include <poll.h>
+#include <sys/signalfd.h>
+#include <assert.h>
#include "closestream.h"
#include "nls.h"
@@ -106,8 +108,8 @@ struct script_control {
isterm:1, /* is child process running as terminal */
resized:1, /* has terminal been resized */
die:1; /* terminate program */
- sigset_t block_mask; /* signals that are blocked */
- sigset_t unblock_mask; /* original signal mask */
+ sigset_t sigset; /* catch SIGCHLD and SIGWINCH with signalfd() */
+ int sigfd; /* file descriptor for signalfd() */
};
struct script_control *gctl; /* global control structure, used in signal handlers */
@@ -245,16 +247,13 @@ static void doinput(struct script_control *ctl)
FD_ZERO(&readfds);
- /* block SIGCHLD */
- sigprocmask(SIG_SETMASK, &ctl->block_mask, &ctl->unblock_mask);
-
while (!ctl->die) {
FD_SET(STDIN_FILENO, &readfds);
errno = 0;
/* wait for input or signal (including SIGCHLD) */
if ((cc = pselect(STDIN_FILENO + 1, &readfds, NULL, NULL, NULL,
- &ctl->unblock_mask)) > 0) {
+ NULL)) > 0) {
if ((cc = read(STDIN_FILENO, ibuf, BUFSIZ)) > 0) {
if (write_all(ctl->master, ibuf, cc)) {
@@ -278,9 +277,6 @@ static void doinput(struct script_control *ctl)
}
}
- /* unblock SIGCHLD */
- sigprocmask(SIG_SETMASK, &ctl->unblock_mask, NULL);
-
/* To be sure that we don't miss any data */
wait_for_empty_fd(ctl, ctl->slave);
wait_for_empty_fd(ctl, ctl->master);
@@ -349,29 +345,24 @@ static void dooutput(struct script_control *ctl)
do {
if (ctl->die || errsv == EINTR) {
struct pollfd fds[] = {
+ {.fd = ctl->sigfd, .events = POLLIN | POLLERR | POLLHUP},
{.fd = ctl->master, .events = POLLIN}
};
if (poll(fds, 1, 50) <= 0)
break;
}
- /* block SIGCHLD */
- sigprocmask(SIG_SETMASK, &ctl->block_mask, &ctl->unblock_mask);
-
FD_SET(ctl->master, &readfds);
errno = 0;
/* wait for input or signal (including SIGCHLD) */
if ((cc = pselect(ctl->master + 1, &readfds, NULL, NULL, NULL,
- &ctl->unblock_mask)) > 0) {
+ NULL)) > 0) {
cc = read(ctl->master, obuf, sizeof(obuf));
}
errsv = errno;
- /* unblock SIGCHLD */
- sigprocmask(SIG_SETMASK, &ctl->unblock_mask, NULL);
-
if (ctl->tflg)
gettimeofday(&tv, NULL);
@@ -562,7 +553,6 @@ int main(int argc, char **argv)
.master = -1,
0
};
- struct sigaction sa;
int ch;
enum { FORCE_OPTION = CHAR_MAX + 1 };
@@ -650,19 +640,15 @@ int main(int argc, char **argv)
#ifdef HAVE_LIBUTEMPTER
utempter_add_record(master, NULL);
#endif
- /* setup SIGCHLD handler */
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = sig_finish;
- sigaction(SIGCHLD, &sa, NULL);
-
- /* init mask for SIGCHLD */
- sigprocmask(SIG_SETMASK, NULL, &ctl.block_mask);
- sigaddset(&ctl.block_mask, SIGCHLD);
+ /* setup signal handler */
+ assert(sigemptyset(&ctl.sigset) == 0);
+ assert(sigaddset(&ctl.sigset, SIGCHLD) == 0);
+ assert(sigaddset(&ctl.sigset, SIGWINCH) == 0);
+ assert(sigprocmask(SIG_BLOCK, &ctl.sigset, NULL) == 0);
+ if ((ctl.sigfd = signalfd(-1, &ctl.sigset, 0)) < 0)
+ err(EXIT_FAILURE, _("cannot set signal handler"));
- sigprocmask(SIG_SETMASK, &ctl.block_mask, &ctl.unblock_mask);
ctl.child = fork();
- sigprocmask(SIG_SETMASK, &ctl.unblock_mask, NULL);
if (ctl.child < 0) {
warn(_("fork failed"));
@@ -670,9 +656,7 @@ int main(int argc, char **argv)
}
if (ctl.child == 0) {
- sigprocmask(SIG_SETMASK, &ctl.block_mask, NULL);
ctl.subchild = ctl.child = fork();
- sigprocmask(SIG_SETMASK, &ctl.unblock_mask, NULL);
if (ctl.child < 0) {
warn(_("fork failed"));
@@ -682,9 +666,6 @@ int main(int argc, char **argv)
dooutput(&ctl);
else
doshell(&ctl);
- } else {
- sa.sa_handler = resize;
- sigaction(SIGWINCH, &sa, NULL);
}
doinput(&ctl);
--
2.2.1
next prev parent reply other threads:[~2014-12-27 17:17 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-27 17:17 [PATCH 00/22] pull: follow-up to chsh, newgrp, and script changes Sami Kerola
2014-12-27 17:17 ` Sami Kerola [this message]
2014-12-27 17:17 ` [PATCH 16/22] script: use poll() rather than select() Sami Kerola
2014-12-27 17:17 ` [PATCH 17/22] script: merge doinput() and output() functions to do_io() Sami Kerola
2014-12-27 17:17 ` [PATCH 18/22] script: remove io vs signal race Sami Kerola
2014-12-27 17:17 ` [PATCH 19/22] script: add 'Script started' line always to capture file Sami Kerola
2014-12-27 17:17 ` [PATCH 20/22] script: move do_io() content to small functions Sami Kerola
2014-12-27 17:17 ` [PATCH 21/22] script: replace strftime() workaround with CFLAGS = -Wno-format-y2k Sami Kerola
2014-12-27 17:17 ` [PATCH 22/22] script: use correct input type, move comment, and so on Sami Kerola
2015-01-06 11:11 ` Karel Zak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1419700655-19107-2-git-send-email-kerolasa@iki.fi \
--to=kerolasa@iki.fi \
--cc=ruediger.meier@ga-group.nl \
--cc=util-linux@vger.kernel.org \
--cc=wolf@cs.cmu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.