diff options
Diffstat (limited to 'clientloop.c')
-rw-r--r-- | clientloop.c | 67 |
1 files changed, 32 insertions, 35 deletions
diff --git a/clientloop.c b/clientloop.c index aade8606b..49a943a73 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -59,7 +59,7 @@ | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include "includes.h" | 61 | #include "includes.h" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.45 2001/01/21 19:05:47 markus Exp $"); | 62 | RCSID("$OpenBSD: clientloop.c,v 1.46 2001/01/29 16:55:36 markus Exp $"); |
63 | 63 | ||
64 | #include "ssh.h" | 64 | #include "ssh.h" |
65 | #include "ssh1.h" | 65 | #include "ssh1.h" |
@@ -124,7 +124,6 @@ static Buffer stdout_buffer; /* Buffer for stdout data. */ | |||
124 | static Buffer stderr_buffer; /* Buffer for stderr data. */ | 124 | static Buffer stderr_buffer; /* Buffer for stderr data. */ |
125 | static u_long stdin_bytes, stdout_bytes, stderr_bytes; | 125 | static u_long stdin_bytes, stdout_bytes, stderr_bytes; |
126 | static u_int buffer_high;/* Soft max buffer size. */ | 126 | static u_int buffer_high;/* Soft max buffer size. */ |
127 | static int max_fd; /* Maximum file descriptor number in select(). */ | ||
128 | static int connection_in; /* Connection to server (input). */ | 127 | static int connection_in; /* Connection to server (input). */ |
129 | static int connection_out; /* Connection to server (output). */ | 128 | static int connection_out; /* Connection to server (output). */ |
130 | 129 | ||
@@ -365,45 +364,37 @@ client_check_window_change() | |||
365 | */ | 364 | */ |
366 | 365 | ||
367 | void | 366 | void |
368 | client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) | 367 | client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, |
368 | int *maxfdp) | ||
369 | { | 369 | { |
370 | /* Initialize select masks. */ | 370 | /* Add any selections by the channel mechanism. */ |
371 | FD_ZERO(readset); | 371 | channel_prepare_select(readsetp, writesetp, maxfdp); |
372 | FD_ZERO(writeset); | ||
373 | 372 | ||
374 | if (!compat20) { | 373 | if (!compat20) { |
375 | /* Read from the connection, unless our buffers are full. */ | 374 | /* Read from the connection, unless our buffers are full. */ |
376 | if (buffer_len(&stdout_buffer) < buffer_high && | 375 | if (buffer_len(&stdout_buffer) < buffer_high && |
377 | buffer_len(&stderr_buffer) < buffer_high && | 376 | buffer_len(&stderr_buffer) < buffer_high && |
378 | channel_not_very_much_buffered_data()) | 377 | channel_not_very_much_buffered_data()) |
379 | FD_SET(connection_in, readset); | 378 | FD_SET(connection_in, *readsetp); |
380 | /* | 379 | /* |
381 | * Read from stdin, unless we have seen EOF or have very much | 380 | * Read from stdin, unless we have seen EOF or have very much |
382 | * buffered data to send to the server. | 381 | * buffered data to send to the server. |
383 | */ | 382 | */ |
384 | if (!stdin_eof && packet_not_very_much_data_to_write()) | 383 | if (!stdin_eof && packet_not_very_much_data_to_write()) |
385 | FD_SET(fileno(stdin), readset); | 384 | FD_SET(fileno(stdin), *readsetp); |
386 | 385 | ||
387 | /* Select stdout/stderr if have data in buffer. */ | 386 | /* Select stdout/stderr if have data in buffer. */ |
388 | if (buffer_len(&stdout_buffer) > 0) | 387 | if (buffer_len(&stdout_buffer) > 0) |
389 | FD_SET(fileno(stdout), writeset); | 388 | FD_SET(fileno(stdout), *writesetp); |
390 | if (buffer_len(&stderr_buffer) > 0) | 389 | if (buffer_len(&stderr_buffer) > 0) |
391 | FD_SET(fileno(stderr), writeset); | 390 | FD_SET(fileno(stderr), *writesetp); |
392 | } else { | 391 | } else { |
393 | FD_SET(connection_in, readset); | 392 | FD_SET(connection_in, *readsetp); |
394 | } | 393 | } |
395 | 394 | ||
396 | /* Add any selections by the channel mechanism. */ | ||
397 | channel_prepare_select(readset, writeset); | ||
398 | |||
399 | /* Select server connection if have data to write to the server. */ | 395 | /* Select server connection if have data to write to the server. */ |
400 | if (packet_have_data_to_write()) | 396 | if (packet_have_data_to_write()) |
401 | FD_SET(connection_out, writeset); | 397 | FD_SET(connection_out, *writesetp); |
402 | |||
403 | /* move UP XXX */ | ||
404 | /* Update maximum file descriptor number, if appropriate. */ | ||
405 | if (channel_max_fd() > max_fd) | ||
406 | max_fd = channel_max_fd(); | ||
407 | 398 | ||
408 | /* | 399 | /* |
409 | * Wait for something to happen. This will suspend the process until | 400 | * Wait for something to happen. This will suspend the process until |
@@ -414,11 +405,8 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) | |||
414 | * SSH_MSG_IGNORE packet when the timeout expires. | 405 | * SSH_MSG_IGNORE packet when the timeout expires. |
415 | */ | 406 | */ |
416 | 407 | ||
417 | if (select(max_fd + 1, readset, writeset, NULL, NULL) < 0) { | 408 | if (select((*maxfdp)+1, *readsetp, *writesetp, NULL, NULL) < 0) { |
418 | char buf[100]; | 409 | char buf[100]; |
419 | /* Some systems fail to clear these automatically. */ | ||
420 | FD_ZERO(readset); | ||
421 | FD_ZERO(writeset); | ||
422 | if (errno == EINTR) | 410 | if (errno == EINTR) |
423 | return; | 411 | return; |
424 | /* Note: we might still have data in the buffers. */ | 412 | /* Note: we might still have data in the buffers. */ |
@@ -797,6 +785,8 @@ simple_escape_filter(Channel *c, char *buf, int len) | |||
797 | int | 785 | int |
798 | client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | 786 | client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) |
799 | { | 787 | { |
788 | fd_set *readset = NULL, *writeset = NULL; | ||
789 | int max_fd = 0; | ||
800 | double start_time, total_time; | 790 | double start_time, total_time; |
801 | int len; | 791 | int len; |
802 | char buf[100]; | 792 | char buf[100]; |
@@ -813,9 +803,13 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
813 | buffer_high = 64 * 1024; | 803 | buffer_high = 64 * 1024; |
814 | connection_in = packet_get_connection_in(); | 804 | connection_in = packet_get_connection_in(); |
815 | connection_out = packet_get_connection_out(); | 805 | connection_out = packet_get_connection_out(); |
816 | max_fd = connection_in; | 806 | max_fd = MAX(connection_in, connection_out); |
817 | if (connection_out > max_fd) | 807 | |
818 | max_fd = connection_out; | 808 | if (!compat20) { |
809 | max_fd = MAX(max_fd, fileno(stdin)); | ||
810 | max_fd = MAX(max_fd, fileno(stdout)); | ||
811 | max_fd = MAX(max_fd, fileno(stderr)); | ||
812 | } | ||
819 | stdin_bytes = 0; | 813 | stdin_bytes = 0; |
820 | stdout_bytes = 0; | 814 | stdout_bytes = 0; |
821 | stderr_bytes = 0; | 815 | stderr_bytes = 0; |
@@ -849,7 +843,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
849 | 843 | ||
850 | /* Main loop of the client for the interactive session mode. */ | 844 | /* Main loop of the client for the interactive session mode. */ |
851 | while (!quit_pending) { | 845 | while (!quit_pending) { |
852 | fd_set readset, writeset; | ||
853 | 846 | ||
854 | /* Process buffered packets sent by the server. */ | 847 | /* Process buffered packets sent by the server. */ |
855 | client_process_buffered_input_packets(); | 848 | client_process_buffered_input_packets(); |
@@ -867,7 +860,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
867 | client_make_packets_from_stdin_data(); | 860 | client_make_packets_from_stdin_data(); |
868 | 861 | ||
869 | /* | 862 | /* |
870 | * Make packets from buffered channel data, and buffer them | 863 | * Make packets from buffered channel data, and enqueue them |
871 | * for sending to the server. | 864 | * for sending to the server. |
872 | */ | 865 | */ |
873 | if (packet_not_very_much_data_to_write()) | 866 | if (packet_not_very_much_data_to_write()) |
@@ -886,34 +879,38 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) | |||
886 | * Wait until we have something to do (something becomes | 879 | * Wait until we have something to do (something becomes |
887 | * available on one of the descriptors). | 880 | * available on one of the descriptors). |
888 | */ | 881 | */ |
889 | client_wait_until_can_do_something(&readset, &writeset); | 882 | client_wait_until_can_do_something(&readset, &writeset, &max_fd); |
890 | 883 | ||
891 | if (quit_pending) | 884 | if (quit_pending) |
892 | break; | 885 | break; |
893 | 886 | ||
894 | /* Do channel operations. */ | 887 | /* Do channel operations. */ |
895 | channel_after_select(&readset, &writeset); | 888 | channel_after_select(readset, writeset); |
896 | 889 | ||
897 | /* Buffer input from the connection. */ | 890 | /* Buffer input from the connection. */ |
898 | client_process_net_input(&readset); | 891 | client_process_net_input(readset); |
899 | 892 | ||
900 | if (quit_pending) | 893 | if (quit_pending) |
901 | break; | 894 | break; |
902 | 895 | ||
903 | if (!compat20) { | 896 | if (!compat20) { |
904 | /* Buffer data from stdin */ | 897 | /* Buffer data from stdin */ |
905 | client_process_input(&readset); | 898 | client_process_input(readset); |
906 | /* | 899 | /* |
907 | * Process output to stdout and stderr. Output to | 900 | * Process output to stdout and stderr. Output to |
908 | * the connection is processed elsewhere (above). | 901 | * the connection is processed elsewhere (above). |
909 | */ | 902 | */ |
910 | client_process_output(&writeset); | 903 | client_process_output(writeset); |
911 | } | 904 | } |
912 | 905 | ||
913 | /* Send as much buffered packet data as possible to the sender. */ | 906 | /* Send as much buffered packet data as possible to the sender. */ |
914 | if (FD_ISSET(connection_out, &writeset)) | 907 | if (FD_ISSET(connection_out, writeset)) |
915 | packet_write_poll(); | 908 | packet_write_poll(); |
916 | } | 909 | } |
910 | if (readset) | ||
911 | xfree(readset); | ||
912 | if (writeset) | ||
913 | xfree(writeset); | ||
917 | 914 | ||
918 | /* Terminate the session. */ | 915 | /* Terminate the session. */ |
919 | 916 | ||