diff options
author | Ashley Hedberg <ashley.hedberg@gmail.com> | 2023-02-02 21:13:04 -0500 |
---|---|---|
committer | Alex Chernyakhovsky <achernya@mit.edu> | 2023-08-07 20:59:47 -0400 |
commit | 4306b7cd42a9606a32b95181f50dd3b23d78998b (patch) | |
tree | 87359f623e64f5ad1fa1822c7791a309b9b0463f | |
parent | cf542739cc6a11ae92404964fa3f246af4f89d0c (diff) |
Use pipe to communicate between client and server at startup
Fixes empty line on login
-rw-r--r-- | src/frontend/mosh-server.cc | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/src/frontend/mosh-server.cc b/src/frontend/mosh-server.cc index cfbd170..e258d1c 100644 --- a/src/frontend/mosh-server.cc +++ b/src/frontend/mosh-server.cc @@ -99,6 +99,7 @@ using ServerConnection = Network::Transport<Terminal::Complete, Network::UserStream>; static void serve( int host_fd, + int pipe_fd, Terminal::Complete &terminal, ServerConnection &network, long network_timeout, @@ -509,6 +510,12 @@ static int run_server( const char *desired_ip, const char *desired_port, snprintf( utmp_entry, 64, "mosh [%ld]", static_cast<long int>( getpid() ) ); /* Fork child process */ + int pipes[2]; + int success = pipe(pipes); + if (success == -1) { + perror( "pipe" ); + exit( 1 ); + } pid_t child = forkpty( &master, NULL, NULL, &window_size ); if ( child == -1 ) { @@ -518,6 +525,10 @@ static int run_server( const char *desired_ip, const char *desired_port, if ( child == 0 ) { /* child */ + if ( close( pipes[1] ) < 0 ) { + perror( "child write pipe close" ); + exit( 1 ); + } /* reenable signals */ struct sigaction sa; @@ -593,8 +604,12 @@ static int run_server( const char *desired_ip, const char *desired_port, /* Wait for parent to release us. */ char linebuf[81]; - if (fgets(linebuf, sizeof linebuf, stdin) == NULL) { - err( 1, "parent signal" ); + // -1, errno == EINTR -- retry + // otherwise, give up + while ( read( pipes[0], linebuf, sizeof( linebuf ) ) == -1 ) { + if ( errno != EINTR ) { + err( 1, "parent signal" ); + } } Crypto::reenable_dumping_core(); @@ -604,8 +619,17 @@ static int run_server( const char *desired_ip, const char *desired_port, sleep( 3 ); exit( 1 ); } + + if ( close( pipes[0] ) < 0 ) { + perror( "child read pipe close" ); + exit( 1 ); + } } else { - /* parent */ + /* parent */ + if ( close(pipes[0]) < 0 ) { + perror( "parent read pipe close" ); + exit( 1 ); + } /* Drop unnecessary privileges */ #ifdef HAVE_PLEDGE @@ -622,7 +646,7 @@ static int run_server( const char *desired_ip, const char *desired_port, #endif try { - serve( master, terminal, *network, network_timeout, network_signaled_timeout ); + serve( master, pipes[1], terminal, *network, network_timeout, network_signaled_timeout ); } catch ( const Network::NetworkException &e ) { fprintf( stderr, "Network exception: %s\n", e.what() ); @@ -646,7 +670,7 @@ static int run_server( const char *desired_ip, const char *desired_port, return 0; } -static void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network, long network_timeout, long network_signaled_timeout ) +static void serve( int host_fd, int pipe_fd, Terminal::Complete &terminal, ServerConnection &network, long network_timeout, long network_signaled_timeout ) { /* scale timeouts */ const uint64_t network_timeout_ms = static_cast<uint64_t>( network_timeout ) * 1000; @@ -822,8 +846,8 @@ static void serve( int host_fd, Terminal::Complete &terminal, ServerConnection & /* Tell child to start login session. */ if ( !child_released ) { - if ( swrite( host_fd, "\n", 1 ) < 0) { - err( 1, "child release" ); + if ( close( pipe_fd ) < 0 ) { + err( 1, "child release" ); } child_released = true; } |