|
|
f43afa |
From b48894ebfc1e123ec9030bb7a31a269d13995ce0 Mon Sep 17 00:00:00 2001
|
|
|
f43afa |
From: Jonathan Lebon <jlebon@redhat.com>
|
|
|
f43afa |
Date: Sat, 30 Nov 2013 11:14:25 -0500
|
|
|
f43afa |
Subject: BZ1054956: stapsh.c: fix handling of POLLIN to indicate EOF
|
|
|
f43afa |
|
|
|
f43afa |
We previously relied on POLLHUP to indicate EOF. However, it is also
|
|
|
f43afa |
possible to receive POLLIN when EOF is reached. With this patch, upon
|
|
|
f43afa |
receiving POLLIN and reading from the associated fd, if EOF is found, we
|
|
|
f43afa |
modify the polling array to indicate we're no longer interested.
|
|
|
f43afa |
---
|
|
|
f43afa |
staprun/stapsh.c | 27 ++++++++++++++++++++-------
|
|
|
f43afa |
1 file changed, 20 insertions(+), 7 deletions(-)
|
|
|
f43afa |
|
|
|
f43afa |
diff --git a/staprun/stapsh.c b/staprun/stapsh.c
|
|
|
f43afa |
index 3d88537..5c3229b 100644
|
|
|
f43afa |
--- a/staprun/stapsh.c
|
|
|
f43afa |
+++ b/staprun/stapsh.c
|
|
|
f43afa |
@@ -638,7 +638,11 @@ process_command(void)
|
|
|
f43afa |
// stap commands are short and always end in \n. Even if we do block it's not
|
|
|
f43afa |
// so bad a thing.
|
|
|
f43afa |
if (fgets(command, sizeof(command), stapsh_in) == NULL)
|
|
|
f43afa |
- return;
|
|
|
f43afa |
+ {
|
|
|
f43afa |
+ if (feof(stapsh_in)) // no more stap commands coming
|
|
|
f43afa |
+ pfds[PFD_STAP_OUT].events = 0;
|
|
|
f43afa |
+ return;
|
|
|
f43afa |
+ }
|
|
|
f43afa |
|
|
|
f43afa |
dbug(1, "command: %s", command);
|
|
|
f43afa |
const char* arg = strtok(command, STAPSH_TOK_DELIM) ?: "(null)";
|
|
|
f43afa |
@@ -665,10 +669,10 @@ process_command(void)
|
|
|
f43afa |
}
|
|
|
f43afa |
|
|
|
f43afa |
static void
|
|
|
f43afa |
-prefix_staprun(int fdin, FILE *out, const char *stream)
|
|
|
f43afa |
+prefix_staprun(int i, FILE *out, const char *stream)
|
|
|
f43afa |
{
|
|
|
f43afa |
char buf[4096];
|
|
|
f43afa |
- ssize_t n = read(fdin, buf, sizeof buf);
|
|
|
f43afa |
+ ssize_t n = read(pfds[i].fd, buf, sizeof buf);
|
|
|
f43afa |
if (n > 0)
|
|
|
f43afa |
{
|
|
|
f43afa |
// actually check if we need to prefix data (we could also be piping for
|
|
|
f43afa |
@@ -679,6 +683,8 @@ prefix_staprun(int fdin, FILE *out, const char *stream)
|
|
|
f43afa |
dbug(2, "failed fwrite\n"); // appease older gccs (don't ignore fwrite rc)
|
|
|
f43afa |
fflush(out);
|
|
|
f43afa |
}
|
|
|
f43afa |
+ else if (n == 0) // eof
|
|
|
f43afa |
+ pfds[i].events = 0;
|
|
|
f43afa |
}
|
|
|
f43afa |
|
|
|
f43afa |
int
|
|
|
f43afa |
@@ -751,17 +757,24 @@ main(int argc, char* const argv[])
|
|
|
f43afa |
sleep(2); // Once we support only platforms with guaranteed SIGIO support,
|
|
|
f43afa |
// we could replace this with a pause().
|
|
|
f43afa |
|
|
|
f43afa |
- for (;;)
|
|
|
f43afa |
+ // keep polling as long as we're listening for stap commands
|
|
|
f43afa |
+ while (pfds[PFD_STAP_OUT].events)
|
|
|
f43afa |
{
|
|
|
f43afa |
- poll(pfds, staprun_pid > 0 ? 3 : 1, -1);
|
|
|
f43afa |
+ if (poll(pfds, 3, -1) < 0)
|
|
|
f43afa |
+ {
|
|
|
f43afa |
+ if (errno == EINTR)
|
|
|
f43afa |
+ continue; // go back to poll()
|
|
|
f43afa |
+ else
|
|
|
f43afa |
+ die ("poll() failed with critical error");
|
|
|
f43afa |
+ }
|
|
|
f43afa |
if (pfds[PFD_STAP_OUT].revents & POLLHUP)
|
|
|
f43afa |
break;
|
|
|
f43afa |
if (pfds[PFD_STAP_OUT].revents & POLLIN)
|
|
|
f43afa |
process_command();
|
|
|
f43afa |
if (pfds[PFD_STAPRUN_OUT].revents & POLLIN)
|
|
|
f43afa |
- prefix_staprun(pfds[PFD_STAPRUN_OUT].fd, stapsh_out, "stdout");
|
|
|
f43afa |
+ prefix_staprun(PFD_STAPRUN_OUT, stapsh_out, "stdout");
|
|
|
f43afa |
if (pfds[PFD_STAPRUN_ERR].revents & POLLIN)
|
|
|
f43afa |
- prefix_staprun(pfds[PFD_STAPRUN_ERR].fd, stapsh_err, "stderr");
|
|
|
f43afa |
+ prefix_staprun(PFD_STAPRUN_ERR, stapsh_err, "stderr");
|
|
|
f43afa |
}
|
|
|
f43afa |
|
|
|
f43afa |
cleanup(0);
|
|
|
f43afa |
--
|
|
|
f43afa |
1.8.3.1
|
|
|
f43afa |
|