summaryrefslogtreecommitdiff
path: root/serverloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'serverloop.c')
-rw-r--r--serverloop.c85
1 files changed, 42 insertions, 43 deletions
diff --git a/serverloop.c b/serverloop.c
index a7f8e72b5..bdac6a0d2 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.42 2001/01/21 19:05:55 markus Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.43 2001/01/29 16:55:37 markus Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -73,7 +73,6 @@ static int fderr_eof = 0; /* EOF encountered readung from fderr. */
73static int connection_in; /* Connection to client (input). */ 73static int connection_in; /* Connection to client (input). */
74static int connection_out; /* Connection to client (output). */ 74static int connection_out; /* Connection to client (output). */
75static u_int buffer_high;/* "Soft" max buffer size. */ 75static u_int buffer_high;/* "Soft" max buffer size. */
76static int max_fd; /* Max file descriptor number for select(). */
77 76
78/* 77/*
79 * This SIGCHLD kludge is used to detect when the child exits. The server 78 * This SIGCHLD kludge is used to detect when the child exits. The server
@@ -180,8 +179,8 @@ make_packets_from_stdout_data()
180 * for the duration of the wait (0 = infinite). 179 * for the duration of the wait (0 = infinite).
181 */ 180 */
182void 181void
183wait_until_can_do_something(fd_set * readset, fd_set * writeset, 182wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
184 u_int max_time_milliseconds) 183 u_int max_time_milliseconds)
185{ 184{
186 struct timeval tv, *tvp; 185 struct timeval tv, *tvp;
187 int ret; 186 int ret;
@@ -189,14 +188,13 @@ wait_until_can_do_something(fd_set * readset, fd_set * writeset,
189 /* When select fails we restart from here. */ 188 /* When select fails we restart from here. */
190retry_select: 189retry_select:
191 190
192 /* Initialize select() masks. */ 191 /* Allocate and update select() masks for channel descriptors. */
193 FD_ZERO(readset); 192 channel_prepare_select(readsetp, writesetp, maxfdp);
194 FD_ZERO(writeset);
195 193
196 if (compat20) { 194 if (compat20) {
197 /* wrong: bad condition XXX */ 195 /* wrong: bad condition XXX */
198 if (channel_not_very_much_buffered_data()) 196 if (channel_not_very_much_buffered_data())
199 FD_SET(connection_in, readset); 197 FD_SET(connection_in, *readsetp);
200 } else { 198 } else {
201 /* 199 /*
202 * Read packets from the client unless we have too much 200 * Read packets from the client unless we have too much
@@ -204,37 +202,31 @@ retry_select:
204 */ 202 */
205 if (buffer_len(&stdin_buffer) < buffer_high && 203 if (buffer_len(&stdin_buffer) < buffer_high &&
206 channel_not_very_much_buffered_data()) 204 channel_not_very_much_buffered_data())
207 FD_SET(connection_in, readset); 205 FD_SET(connection_in, *readsetp);
208 /* 206 /*
209 * If there is not too much data already buffered going to 207 * If there is not too much data already buffered going to
210 * the client, try to get some more data from the program. 208 * the client, try to get some more data from the program.
211 */ 209 */
212 if (packet_not_very_much_data_to_write()) { 210 if (packet_not_very_much_data_to_write()) {
213 if (!fdout_eof) 211 if (!fdout_eof)
214 FD_SET(fdout, readset); 212 FD_SET(fdout, *readsetp);
215 if (!fderr_eof) 213 if (!fderr_eof)
216 FD_SET(fderr, readset); 214 FD_SET(fderr, *readsetp);
217 } 215 }
218 /* 216 /*
219 * If we have buffered data, try to write some of that data 217 * If we have buffered data, try to write some of that data
220 * to the program. 218 * to the program.
221 */ 219 */
222 if (fdin != -1 && buffer_len(&stdin_buffer) > 0) 220 if (fdin != -1 && buffer_len(&stdin_buffer) > 0)
223 FD_SET(fdin, writeset); 221 FD_SET(fdin, *writesetp);
224 } 222 }
225 /* Set masks for channel descriptors. */
226 channel_prepare_select(readset, writeset);
227 223
228 /* 224 /*
229 * If we have buffered packet data going to the client, mark that 225 * If we have buffered packet data going to the client, mark that
230 * descriptor. 226 * descriptor.
231 */ 227 */
232 if (packet_have_data_to_write()) 228 if (packet_have_data_to_write())
233 FD_SET(connection_out, writeset); 229 FD_SET(connection_out, *writesetp);
234
235 /* Update the maximum descriptor number if appropriate. */
236 if (channel_max_fd() > max_fd)
237 max_fd = channel_max_fd();
238 230
239 /* 231 /*
240 * If child has terminated and there is enough buffer space to read 232 * If child has terminated and there is enough buffer space to read
@@ -255,7 +247,7 @@ retry_select:
255 debug2("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds); 247 debug2("tvp!=NULL kid %d mili %d", child_terminated, max_time_milliseconds);
256 248
257 /* Wait for something to happen, or the timeout to expire. */ 249 /* Wait for something to happen, or the timeout to expire. */
258 ret = select(max_fd + 1, readset, writeset, NULL, tvp); 250 ret = select((*maxfdp)+1, *readsetp, *writesetp, NULL, tvp);
259 251
260 if (ret < 0) { 252 if (ret < 0) {
261 if (errno != EINTR) 253 if (errno != EINTR)
@@ -400,7 +392,8 @@ process_buffered_input_packets()
400void 392void
401server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) 393server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
402{ 394{
403 fd_set readset, writeset; 395 fd_set *readset = NULL, *writeset = NULL;
396 int max_fd;
404 int wait_status; /* Status returned by wait(). */ 397 int wait_status; /* Status returned by wait(). */
405 pid_t wait_pid; /* pid returned by wait(). */ 398 pid_t wait_pid; /* pid returned by wait(). */
406 int waiting_termination = 0; /* Have displayed waiting close message. */ 399 int waiting_termination = 0; /* Have displayed waiting close message. */
@@ -441,15 +434,11 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
441 buffer_high = 64 * 1024; 434 buffer_high = 64 * 1024;
442 435
443 /* Initialize max_fd to the maximum of the known file descriptors. */ 436 /* Initialize max_fd to the maximum of the known file descriptors. */
444 max_fd = fdin; 437 max_fd = MAX(fdin, fdout);
445 if (fdout > max_fd) 438 if (fderr != -1)
446 max_fd = fdout; 439 max_fd = MAX(max_fd, fderr);
447 if (fderr != -1 && fderr > max_fd) 440 max_fd = MAX(max_fd, connection_in);
448 max_fd = fderr; 441 max_fd = MAX(max_fd, connection_out);
449 if (connection_in > max_fd)
450 max_fd = connection_in;
451 if (connection_out > max_fd)
452 max_fd = connection_out;
453 442
454 /* Initialize Initialize buffers. */ 443 /* Initialize Initialize buffers. */
455 buffer_init(&stdin_buffer); 444 buffer_init(&stdin_buffer);
@@ -536,18 +525,22 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
536 } 525 }
537 } 526 }
538 /* Sleep in select() until we can do something. */ 527 /* Sleep in select() until we can do something. */
539 wait_until_can_do_something(&readset, &writeset, 528 wait_until_can_do_something(&readset, &writeset, &max_fd,
540 max_time_milliseconds); 529 max_time_milliseconds);
541 530
542 /* Process any channel events. */ 531 /* Process any channel events. */
543 channel_after_select(&readset, &writeset); 532 channel_after_select(readset, writeset);
544 533
545 /* Process input from the client and from program stdout/stderr. */ 534 /* Process input from the client and from program stdout/stderr. */
546 process_input(&readset); 535 process_input(readset);
547 536
548 /* Process output to the client and to program stdin. */ 537 /* Process output to the client and to program stdin. */
549 process_output(&writeset); 538 process_output(writeset);
550 } 539 }
540 if (readset)
541 xfree(readset);
542 if (writeset)
543 xfree(writeset);
551 544
552 /* Cleanup and termination code. */ 545 /* Cleanup and termination code. */
553 546
@@ -638,7 +631,8 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
638void 631void
639server_loop2(void) 632server_loop2(void)
640{ 633{
641 fd_set readset, writeset; 634 fd_set *readset = NULL, *writeset = NULL;
635 int max_fd;
642 int had_channel = 0; 636 int had_channel = 0;
643 int status; 637 int status;
644 pid_t pid; 638 pid_t pid;
@@ -650,9 +644,9 @@ server_loop2(void)
650 child_terminated = 0; 644 child_terminated = 0;
651 connection_in = packet_get_connection_in(); 645 connection_in = packet_get_connection_in();
652 connection_out = packet_get_connection_out(); 646 connection_out = packet_get_connection_out();
653 max_fd = connection_in; 647
654 if (connection_out > max_fd) 648 max_fd = MAX(connection_in, connection_out);
655 max_fd = connection_out; 649
656 server_init_dispatch(); 650 server_init_dispatch();
657 651
658 for (;;) { 652 for (;;) {
@@ -665,16 +659,21 @@ server_loop2(void)
665 } 659 }
666 if (packet_not_very_much_data_to_write()) 660 if (packet_not_very_much_data_to_write())
667 channel_output_poll(); 661 channel_output_poll();
668 wait_until_can_do_something(&readset, &writeset, 0); 662 wait_until_can_do_something(&readset, &writeset, &max_fd, 0);
669 if (child_terminated) { 663 if (child_terminated) {
670 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) 664 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
671 session_close_by_pid(pid, status); 665 session_close_by_pid(pid, status);
672 child_terminated = 0; 666 child_terminated = 0;
673 } 667 }
674 channel_after_select(&readset, &writeset); 668 channel_after_select(readset, writeset);
675 process_input(&readset); 669 process_input(readset);
676 process_output(&writeset); 670 process_output(writeset);
677 } 671 }
672 if (readset)
673 xfree(readset);
674 if (writeset)
675 xfree(writeset);
676
678 signal(SIGCHLD, SIG_DFL); 677 signal(SIGCHLD, SIG_DFL);
679 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) 678 while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
680 session_close_by_pid(pid, status); 679 session_close_by_pid(pid, status);