diff options
author | Tomoya Adachi <adachi@il.is.s.u-tokyo.ac.jp> | 2009-08-03 02:59:22 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-08-03 02:59:22 +0200 |
commit | 63416cc57d5b2265952208425af377f252a7d0b4 (patch) | |
tree | ae53c90419fc4abd316a794a3921c530d0b1155f | |
parent | dc9495df03f411d67eb46002670ffea12bdd32ba (diff) | |
download | busybox-w32-63416cc57d5b2265952208425af377f252a7d0b4.tar.gz busybox-w32-63416cc57d5b2265952208425af377f252a7d0b4.tar.bz2 busybox-w32-63416cc57d5b2265952208425af377f252a7d0b4.zip |
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>
-rw-r--r-- | networking/nc.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/networking/nc.c b/networking/nc.c index e4db23895..243c47976 100644 --- a/networking/nc.c +++ b/networking/nc.c | |||
@@ -135,29 +135,27 @@ int nc_main(int argc, char **argv) | |||
135 | 135 | ||
136 | /* -e given? */ | 136 | /* -e given? */ |
137 | if (execparam) { | 137 | if (execparam) { |
138 | signal(SIGCHLD, SIG_IGN); | 138 | pid_t pid; |
139 | // With more than one -l, repeatedly act as server. | 139 | /* With more than one -l, repeatedly act as server */ |
140 | if (do_listen > 1 && vfork()) { | 140 | if (do_listen > 1 && (pid = vfork()) != 0) { |
141 | /* parent */ | 141 | /* parent or error */ |
142 | // This is a bit weird as cleanup goes, since we wind up with no | 142 | if (pid < 0) |
143 | // stdin/stdout/stderr. But it's small and shouldn't hurt anything. | 143 | bb_perror_msg_and_die("vfork"); |
144 | // We check for cfd == 0 above. | 144 | /* prevent zombies */ |
145 | logmode = LOGMODE_NONE; | 145 | signal(SIGCHLD, SIG_IGN); |
146 | close(0); | 146 | close(cfd); |
147 | close(1); | ||
148 | close(2); | ||
149 | goto accept_again; | 147 | goto accept_again; |
150 | } | 148 | } |
151 | /* child (or main thread if no multiple -l) */ | 149 | /* child, or main thread if only one -l */ |
152 | xmove_fd(cfd, 0); | 150 | xmove_fd(cfd, 0); |
153 | xdup2(0, 1); | 151 | xdup2(0, 1); |
154 | xdup2(0, 2); | 152 | xdup2(0, 2); |
155 | IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);) | 153 | IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);) |
156 | /* Don't print stuff or it will go over the wire.... */ | 154 | /* Don't print stuff or it will go over the wire... */ |
157 | _exit(127); | 155 | _exit(127); |
158 | } | 156 | } |
159 | 157 | ||
160 | // Select loop copying stdin to cfd, and cfd to stdout. | 158 | /* Select loop copying stdin to cfd, and cfd to stdout */ |
161 | 159 | ||
162 | FD_ZERO(&readfds); | 160 | FD_ZERO(&readfds); |
163 | FD_SET(cfd, &readfds); | 161 | FD_SET(cfd, &readfds); |
@@ -170,11 +168,12 @@ int nc_main(int argc, char **argv) | |||
170 | 168 | ||
171 | testfds = readfds; | 169 | testfds = readfds; |
172 | 170 | ||
173 | if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0) | 171 | if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0) |
174 | bb_perror_msg_and_die("select"); | 172 | bb_perror_msg_and_die("select"); |
175 | 173 | ||
176 | #define iobuf bb_common_bufsiz1 | 174 | #define iobuf bb_common_bufsiz1 |
177 | for (fd = 0; fd < FD_SETSIZE; fd++) { | 175 | fd = STDIN_FILENO; |
176 | while (1) { | ||
178 | if (FD_ISSET(fd, &testfds)) { | 177 | if (FD_ISSET(fd, &testfds)) { |
179 | nread = safe_read(fd, iobuf, sizeof(iobuf)); | 178 | nread = safe_read(fd, iobuf, sizeof(iobuf)); |
180 | if (fd == cfd) { | 179 | if (fd == cfd) { |
@@ -182,17 +181,21 @@ int nc_main(int argc, char **argv) | |||
182 | exit(EXIT_SUCCESS); | 181 | exit(EXIT_SUCCESS); |
183 | ofd = STDOUT_FILENO; | 182 | ofd = STDOUT_FILENO; |
184 | } else { | 183 | } else { |
185 | if (nread<1) { | 184 | if (nread < 1) { |
186 | // Close outgoing half-connection so they get EOF, but | 185 | /* Close outgoing half-connection so they get EOF, |
187 | // leave incoming alone so we can see response. | 186 | * but leave incoming alone so we can see response */ |
188 | shutdown(cfd, 1); | 187 | shutdown(cfd, 1); |
189 | FD_CLR(STDIN_FILENO, &readfds); | 188 | FD_CLR(STDIN_FILENO, &readfds); |
190 | } | 189 | } |
191 | ofd = cfd; | 190 | ofd = cfd; |
192 | } | 191 | } |
193 | xwrite(ofd, iobuf, nread); | 192 | xwrite(ofd, iobuf, nread); |
194 | if (delay > 0) sleep(delay); | 193 | if (delay > 0) |
194 | sleep(delay); | ||
195 | } | 195 | } |
196 | if (fd == cfd) | ||
197 | break; | ||
198 | fd = cfd; | ||
196 | } | 199 | } |
197 | } | 200 | } |
198 | } | 201 | } |