diff options
author | Nathan Straz <nstraz@redhat.com> | 2014-07-22 13:07:19 -0400 |
---|---|---|
committer | Nathan Straz <nstraz@redhat.com> | 2014-07-22 13:07:19 -0400 |
commit | 3ee89ea3fa03f6f98a92d38e68946de29db98f54 (patch) | |
tree | d2c130f47fd57265e236294a9c72f544b51bc6ac /qarshd.c | |
parent | 10a03d9299757a14525e1177ef34f68b316be1f0 (diff) | |
download | qarsh-3ee89ea3fa03f6f98a92d38e68946de29db98f54.tar.gz qarsh-3ee89ea3fa03f6f98a92d38e68946de29db98f54.tar.xz qarsh-3ee89ea3fa03f6f98a92d38e68946de29db98f54.zip |
[qarshd] Fix timeout when child exits
We ran into an issue where qarsh would wait for 3 seconds
after a command ran. This was traced back to the select()
in handle_qarsh() being restarted when SIGCHLD was received.
I moved the waitpid() to just before the select() and turned off
the signal restart. This closes those timing windows and allows
qarshd to quickly finish after the child exits.
Diffstat (limited to 'qarshd.c')
-rw-r--r-- | qarshd.c | 10 |
1 files changed, 8 insertions, 2 deletions
@@ -246,8 +246,12 @@ handle_qarsh() int z_in = 0; /* Number of bytes in stdin buffer */ int eof_in = 0; /* Have we seen EOF on stdin yet? */ int nbytes; + struct sigaction chldact; signal(SIGPIPE, SIG_IGN); + chldact.sa_handler = sig_handler; + chldact.sa_flags = 0; /* Make sure SA_RESTART is NOT set so select doesn't timeout on SIGCHLD */ + sigaction(SIGCHLD, &chldact, NULL); qp = make_qp_data_allow(0, QARSHD_BUFSIZE); send_packet(qoutfd, qp); @@ -273,14 +277,16 @@ handle_qarsh() maxfd = childfds[2] > maxfd ? childfds[2] : maxfd; } - nfd = select(maxfd+1, &rfds, &wfds, NULL, &timeout); - + /* Check the child just before we do the select so there's no time + * for the child to exit before the select, causing the select to hang */ if (child_pid && waitpid(child_pid, &child_status, WNOHANG) == child_pid) { rp = make_qp_cmdexit(child_pid, child_status); send_packet(qoutfd, rp); qpfree(rp); child_pid = 0; } + + nfd = select(maxfd+1, &rfds, &wfds, NULL, &timeout); if (nfd < 0) { if (errno == EINTR) { /* signals handled above here */ |