aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomoya Adachi <adachi@il.is.s.u-tokyo.ac.jp>2009-08-03 02:59:22 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-08-03 02:59:22 +0200
commit63416cc57d5b2265952208425af377f252a7d0b4 (patch)
treeae53c90419fc4abd316a794a3921c530d0b1155f
parentdc9495df03f411d67eb46002670ffea12bdd32ba (diff)
downloadbusybox-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.c43
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}