Ncat: Attempt to reopen fd 0 if stdin is closed by parent process. Fixes #143

This commit is contained in:
dmiller 2015-11-12 05:07:33 +00:00
parent 5c425fa6fd
commit 50c7837c5b

View file

@ -260,6 +260,23 @@ static int ncat_listen_stream(int proto)
setup_ssl_listen();
#endif
/* Check whether stdin is closed. Because we treat this fd specially, we
* can't risk it being reopened for an incoming connection, so we'll hold
* it open instead. */
if (fcntl(STDIN_FILENO, F_GETFD) == -1 && errno == EBADF) {
logdebug("stdin is closed, attempting to reserve STDIN_FILENO\n");
#ifdef WIN32
rc = open("NUL", O_RDONLY);
#else
rc = open("/dev/null", O_RDONLY);
#endif
if (rc >= 0 && rc != STDIN_FILENO) {
/* Oh well, we tried */
logdebug("Couldn't reserve STDIN_FILENO\n");
close(rc);
}
}
/* We need a list of fds to keep current fdmax. The second parameter is a
number added to the supplied connection limit, that will compensate
maxfds for the added by default listen and stdin sockets. */
@ -673,6 +690,23 @@ static int ncat_listen_dgram(int proto)
Signal(SIGPIPE, SIG_IGN);
#endif
/* Check whether stdin is closed. Because we treat this fd specially, we
* can't risk it being reopened for an incoming connection, so we'll hold
* it open instead. */
if (fcntl(STDIN_FILENO, F_GETFD) == -1 && errno == EBADF) {
logdebug("stdin is closed, attempting to reserve STDIN_FILENO\n");
#ifdef WIN32
i = open("NUL", O_RDONLY);
#else
i = open("/dev/null", O_RDONLY);
#endif
if (i >= 0 && i != STDIN_FILENO) {
/* Oh well, we tried */
logdebug("Couldn't reserve STDIN_FILENO\n");
close(i);
}
}
/* set for selecting udp listening sockets */
fd_set listen_fds;
fd_list_t listen_fdlist;
@ -858,11 +892,16 @@ static int ncat_listen_dgram(int proto)
if (FD_ISSET(STDIN_FILENO, &fds)) {
nbytes = Read(STDIN_FILENO, buf, sizeof(buf));
if (nbytes < 0) {
loguser("%s.\n", strerror(errno));
return 1;
} else if (nbytes == 0) {
return 0;
if (nbytes <= 0) {
if (nbytes < 0 && o.verbose) {
logdebug("Error reading from stdin: %s\n", strerror(errno));
} else if (nbytes == 0 && o.debug) {
logdebug("EOF on stdin\n");
}
FD_CLR(STDIN_FILENO, &read_fds);
if (nbytes < 0)
return 1;
continue;
}
if (o.crlf)
fix_line_endings((char *) buf, &nbytes, &tempbuf, &crlf_state);