nc: fix nc -ll; report vfork errors; make select loop faster
function old new delta nc_main 933 946 +13 Signed-off-by: Tomoya Adachi <adachi@il.is.s.u-tokyo.ac.jp> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
dc9495df03
commit
63416cc57d
@ -135,29 +135,27 @@ int nc_main(int argc, char **argv)
|
|||||||
|
|
||||||
/* -e given? */
|
/* -e given? */
|
||||||
if (execparam) {
|
if (execparam) {
|
||||||
signal(SIGCHLD, SIG_IGN);
|
pid_t pid;
|
||||||
// With more than one -l, repeatedly act as server.
|
/* With more than one -l, repeatedly act as server */
|
||||||
if (do_listen > 1 && vfork()) {
|
if (do_listen > 1 && (pid = vfork()) != 0) {
|
||||||
/* parent */
|
/* parent or error */
|
||||||
// This is a bit weird as cleanup goes, since we wind up with no
|
if (pid < 0)
|
||||||
// stdin/stdout/stderr. But it's small and shouldn't hurt anything.
|
bb_perror_msg_and_die("vfork");
|
||||||
// We check for cfd == 0 above.
|
/* prevent zombies */
|
||||||
logmode = LOGMODE_NONE;
|
signal(SIGCHLD, SIG_IGN);
|
||||||
close(0);
|
close(cfd);
|
||||||
close(1);
|
|
||||||
close(2);
|
|
||||||
goto accept_again;
|
goto accept_again;
|
||||||
}
|
}
|
||||||
/* child (or main thread if no multiple -l) */
|
/* child, or main thread if only one -l */
|
||||||
xmove_fd(cfd, 0);
|
xmove_fd(cfd, 0);
|
||||||
xdup2(0, 1);
|
xdup2(0, 1);
|
||||||
xdup2(0, 2);
|
xdup2(0, 2);
|
||||||
IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);)
|
IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);)
|
||||||
/* Don't print stuff or it will go over the wire.... */
|
/* Don't print stuff or it will go over the wire... */
|
||||||
_exit(127);
|
_exit(127);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select loop copying stdin to cfd, and cfd to stdout.
|
/* Select loop copying stdin to cfd, and cfd to stdout */
|
||||||
|
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(cfd, &readfds);
|
FD_SET(cfd, &readfds);
|
||||||
@ -170,11 +168,12 @@ int nc_main(int argc, char **argv)
|
|||||||
|
|
||||||
testfds = readfds;
|
testfds = readfds;
|
||||||
|
|
||||||
if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0)
|
if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0)
|
||||||
bb_perror_msg_and_die("select");
|
bb_perror_msg_and_die("select");
|
||||||
|
|
||||||
#define iobuf bb_common_bufsiz1
|
#define iobuf bb_common_bufsiz1
|
||||||
for (fd = 0; fd < FD_SETSIZE; fd++) {
|
fd = STDIN_FILENO;
|
||||||
|
while (1) {
|
||||||
if (FD_ISSET(fd, &testfds)) {
|
if (FD_ISSET(fd, &testfds)) {
|
||||||
nread = safe_read(fd, iobuf, sizeof(iobuf));
|
nread = safe_read(fd, iobuf, sizeof(iobuf));
|
||||||
if (fd == cfd) {
|
if (fd == cfd) {
|
||||||
@ -182,17 +181,21 @@ int nc_main(int argc, char **argv)
|
|||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
ofd = STDOUT_FILENO;
|
ofd = STDOUT_FILENO;
|
||||||
} else {
|
} else {
|
||||||
if (nread<1) {
|
if (nread < 1) {
|
||||||
// Close outgoing half-connection so they get EOF, but
|
/* Close outgoing half-connection so they get EOF,
|
||||||
// leave incoming alone so we can see response.
|
* but leave incoming alone so we can see response */
|
||||||
shutdown(cfd, 1);
|
shutdown(cfd, 1);
|
||||||
FD_CLR(STDIN_FILENO, &readfds);
|
FD_CLR(STDIN_FILENO, &readfds);
|
||||||
}
|
}
|
||||||
ofd = cfd;
|
ofd = cfd;
|
||||||
}
|
}
|
||||||
xwrite(ofd, iobuf, nread);
|
xwrite(ofd, iobuf, nread);
|
||||||
if (delay > 0) sleep(delay);
|
if (delay > 0)
|
||||||
|
sleep(delay);
|
||||||
}
|
}
|
||||||
|
if (fd == cfd)
|
||||||
|
break;
|
||||||
|
fd = cfd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user