Use Select in mosh-{client,server}
This commit is contained in:
committed by
Keith Winstein
parent
0019b9d92a
commit
2112a3865c
+15
-23
@@ -25,7 +25,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@@ -51,6 +50,7 @@
|
|||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "fatal_assert.h"
|
#include "fatal_assert.h"
|
||||||
#include "locale_utils.h"
|
#include "locale_utils.h"
|
||||||
|
#include "select.h"
|
||||||
|
|
||||||
#if HAVE_PTY_H
|
#if HAVE_PTY_H
|
||||||
#include <pty.h>
|
#include <pty.h>
|
||||||
@@ -479,16 +479,10 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network
|
|||||||
fatal_assert( sigfd_trap( SIGINT ) == 0 );
|
fatal_assert( sigfd_trap( SIGINT ) == 0 );
|
||||||
|
|
||||||
/* prepare to poll for events */
|
/* prepare to poll for events */
|
||||||
struct pollfd pollfds[ 3 ];
|
Select sel;
|
||||||
|
sel.add_fd( network.fd() );
|
||||||
pollfds[ 0 ].fd = network.fd();
|
sel.add_fd( host_fd );
|
||||||
pollfds[ 0 ].events = POLLIN;
|
sel.add_fd( signal_fd );
|
||||||
|
|
||||||
pollfds[ 1 ].fd = host_fd;
|
|
||||||
pollfds[ 1 ].events = POLLIN;
|
|
||||||
|
|
||||||
pollfds[ 2 ].fd = signal_fd;
|
|
||||||
pollfds[ 2 ].events = POLLIN;
|
|
||||||
|
|
||||||
uint64_t last_remote_num = network.get_remote_state_num();
|
uint64_t last_remote_num = network.get_remote_state_num();
|
||||||
|
|
||||||
@@ -504,23 +498,23 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network
|
|||||||
uint64_t now = Network::timestamp();
|
uint64_t now = Network::timestamp();
|
||||||
|
|
||||||
const int timeout_if_no_client = 60000;
|
const int timeout_if_no_client = 60000;
|
||||||
int poll_timeout = min( network.wait_time(), terminal.wait_time( now ) );
|
int timeout = min( network.wait_time(), terminal.wait_time( now ) );
|
||||||
if ( !network.has_remote_addr() ) {
|
if ( !network.has_remote_addr() ) {
|
||||||
poll_timeout = min( poll_timeout, timeout_if_no_client );
|
timeout = min( timeout, timeout_if_no_client );
|
||||||
}
|
}
|
||||||
|
|
||||||
int active_fds = poll( pollfds, 3, poll_timeout );
|
int active_fds = sel.select( timeout );
|
||||||
if ( active_fds < 0 && errno == EINTR ) {
|
if ( active_fds < 0 && errno == EINTR ) {
|
||||||
continue;
|
continue;
|
||||||
} else if ( active_fds < 0 ) {
|
} else if ( active_fds < 0 ) {
|
||||||
perror( "poll" );
|
perror( "select" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
now = Network::timestamp();
|
now = Network::timestamp();
|
||||||
uint64_t time_since_remote_state = now - network.get_latest_remote_state().timestamp;
|
uint64_t time_since_remote_state = now - network.get_latest_remote_state().timestamp;
|
||||||
|
|
||||||
if ( pollfds[ 0 ].revents & POLLIN ) {
|
if ( sel.read( network.fd() ) ) {
|
||||||
/* packet received from the network */
|
/* packet received from the network */
|
||||||
network.recv();
|
network.recv();
|
||||||
|
|
||||||
@@ -585,13 +579,13 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pollfds[ 1 ].revents & POLLIN ) {
|
if ( sel.read( host_fd ) ) {
|
||||||
/* input from the host needs to be fed to the terminal */
|
/* input from the host needs to be fed to the terminal */
|
||||||
const int buf_size = 16384;
|
const int buf_size = 16384;
|
||||||
char buf[ buf_size ];
|
char buf[ buf_size ];
|
||||||
|
|
||||||
/* fill buffer if possible */
|
/* fill buffer if possible */
|
||||||
ssize_t bytes_read = read( pollfds[ 1 ].fd, buf, buf_size );
|
ssize_t bytes_read = read( host_fd, buf, buf_size );
|
||||||
|
|
||||||
/* If the pty slave is closed, reading from the master can fail with
|
/* If the pty slave is closed, reading from the master can fail with
|
||||||
EIO (see #264). So we treat errors on read() like EOF. */
|
EIO (see #264). So we treat errors on read() like EOF. */
|
||||||
@@ -617,7 +611,7 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pollfds[ 2 ].revents & POLLIN ) {
|
if ( sel.read( signal_fd ) ) {
|
||||||
/* shutdown signal */
|
/* shutdown signal */
|
||||||
int signo = sigfd_read();
|
int signo = sigfd_read();
|
||||||
if ( signo == 0 ) {
|
if ( signo == 0 ) {
|
||||||
@@ -634,14 +628,12 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (pollfds[ 0 ].revents)
|
if ( sel.error( network.fd() ) ) {
|
||||||
& (POLLERR | POLLHUP | POLLNVAL) ) {
|
|
||||||
/* network problem */
|
/* network problem */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (pollfds[ 1 ].revents)
|
if ( sel.error( host_fd ) ) {
|
||||||
& (POLLERR | POLLHUP | POLLNVAL) ) {
|
|
||||||
/* host problem */
|
/* host problem */
|
||||||
if ( network.has_remote_addr() ) {
|
if ( network.has_remote_addr() ) {
|
||||||
network.start_shutdown();
|
network.start_shutdown();
|
||||||
|
|||||||
+13
-21
@@ -24,7 +24,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@@ -44,6 +43,7 @@
|
|||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "fatal_assert.h"
|
#include "fatal_assert.h"
|
||||||
#include "locale_utils.h"
|
#include "locale_utils.h"
|
||||||
|
#include "select.h"
|
||||||
|
|
||||||
#include "networktransport.cc"
|
#include "networktransport.cc"
|
||||||
|
|
||||||
@@ -299,16 +299,10 @@ void STMClient::main( void )
|
|||||||
main_init();
|
main_init();
|
||||||
|
|
||||||
/* prepare to poll for events */
|
/* prepare to poll for events */
|
||||||
struct pollfd pollfds[ 3 ];
|
Select sel;
|
||||||
|
sel.add_fd( network->fd() );
|
||||||
pollfds[ 0 ].fd = network->fd();
|
sel.add_fd( STDIN_FILENO );
|
||||||
pollfds[ 0 ].events = POLLIN;
|
sel.add_fd( signal_fd );
|
||||||
|
|
||||||
pollfds[ 1 ].fd = STDIN_FILENO;
|
|
||||||
pollfds[ 1 ].events = POLLIN;
|
|
||||||
|
|
||||||
pollfds[ 2 ].fd = signal_fd;
|
|
||||||
pollfds[ 2 ].events = POLLIN;
|
|
||||||
|
|
||||||
while ( 1 ) {
|
while ( 1 ) {
|
||||||
try {
|
try {
|
||||||
@@ -321,22 +315,22 @@ void STMClient::main( void )
|
|||||||
wait_time = min( 250, wait_time );
|
wait_time = min( 250, wait_time );
|
||||||
}
|
}
|
||||||
|
|
||||||
int active_fds = poll( pollfds, 3, wait_time );
|
int active_fds = sel.select( wait_time );
|
||||||
if ( active_fds < 0 && errno == EINTR ) {
|
if ( active_fds < 0 && errno == EINTR ) {
|
||||||
continue;
|
continue;
|
||||||
} else if ( active_fds < 0 ) {
|
} else if ( active_fds < 0 ) {
|
||||||
perror( "poll" );
|
perror( "select" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pollfds[ 0 ].revents & POLLIN ) {
|
if ( sel.read( network->fd() ) ) {
|
||||||
/* packet received from the network */
|
/* packet received from the network */
|
||||||
if ( !process_network_input() ) { return; }
|
if ( !process_network_input() ) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pollfds[ 1 ].revents & POLLIN ) {
|
if ( sel.read( STDIN_FILENO ) ) {
|
||||||
/* input from the user needs to be fed to the network */
|
/* input from the user needs to be fed to the network */
|
||||||
if ( !process_user_input( pollfds[ 1 ].fd ) ) {
|
if ( !process_user_input( STDIN_FILENO ) ) {
|
||||||
if ( !network->has_remote_addr() ) {
|
if ( !network->has_remote_addr() ) {
|
||||||
break;
|
break;
|
||||||
} else if ( !network->shutdown_in_progress() ) {
|
} else if ( !network->shutdown_in_progress() ) {
|
||||||
@@ -346,7 +340,7 @@ void STMClient::main( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pollfds[ 2 ].revents & POLLIN ) {
|
if ( sel.read( signal_fd ) ) {
|
||||||
int signo = sigfd_read();
|
int signo = sigfd_read();
|
||||||
|
|
||||||
if ( signo == SIGWINCH ) {
|
if ( signo == SIGWINCH ) {
|
||||||
@@ -364,14 +358,12 @@ void STMClient::main( void )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (pollfds[ 0 ].revents)
|
if ( sel.error( network->fd() ) ) {
|
||||||
& (POLLERR | POLLHUP | POLLNVAL) ) {
|
|
||||||
/* network problem */
|
/* network problem */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (pollfds[ 1 ].revents)
|
if ( sel.error( STDIN_FILENO ) ) {
|
||||||
& (POLLERR | POLLHUP | POLLNVAL) ) {
|
|
||||||
/* user problem */
|
/* user problem */
|
||||||
if ( !network->has_remote_addr() ) {
|
if ( !network->has_remote_addr() ) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user