diff --git a/ncat/ncat_posix.c b/ncat/ncat_posix.c index 12207c066..3db875b19 100644 --- a/ncat/ncat_posix.c +++ b/ncat/ncat_posix.c @@ -190,6 +190,7 @@ void netexec(struct fdinfo *info, char *cmdexec) int child_stdout[2]; int pid; int crlf_state; + int eof_fd, eof_child; char buf[DEFAULT_TCP_BUF_LEN]; int maxfd; @@ -268,13 +269,17 @@ void netexec(struct fdinfo *info, char *cmdexec) writes to the socket. We exit the loop on any read error (or EOF). On a write error we just close the opposite side of the conversation. */ crlf_state = 0; - for (;;) { + eof_fd = 0; + eof_child = 0; + while (!eof_fd || !eof_child) { fd_set fds; int r, n_r; FD_ZERO(&fds); - FD_SET(info->fd, &fds); - FD_SET(child_stdout[0], &fds); + if (!eof_fd) + FD_SET(info->fd, &fds); + if (!eof_child) + FD_SET(child_stdout[0], &fds); r = fselect(maxfd + 1, &fds, NULL, NULL, NULL); if (r == -1) { @@ -288,16 +293,23 @@ void netexec(struct fdinfo *info, char *cmdexec) do { n_r = ncat_recv(info, buf, sizeof(buf), &pending); - if (n_r <= 0) - goto loop_end; + if (n_r <= 0) { + if (!o.noshutdown) + close(child_stdin[1]); + eof_fd = 1; + break; + } write_loop(child_stdin[1], buf, n_r); } while (pending); } if (FD_ISSET(child_stdout[0], &fds)) { char *crlf = NULL, *wbuf; n_r = read(child_stdout[0], buf, sizeof(buf)); - if (n_r <= 0) - break; + if (n_r <= 0) { + if (!o.noshutdown) + shutdown(info->fd, SHUT_WR); + eof_child = 1; + } wbuf = buf; if (o.crlf) { if (fix_line_endings((char *) buf, &n_r, &crlf, &crlf_state)) @@ -308,7 +320,6 @@ void netexec(struct fdinfo *info, char *cmdexec) free(crlf); } } -loop_end: #ifdef HAVE_OPENSSL if (info->ssl != NULL) {