Use pipe to communicate between client and server at startup
Fixes empty line on login
This commit is contained in:
committed by
Alex Chernyakhovsky
parent
cf542739cc
commit
4306b7cd42
@@ -99,6 +99,7 @@
|
|||||||
using ServerConnection = Network::Transport<Terminal::Complete, Network::UserStream>;
|
using ServerConnection = Network::Transport<Terminal::Complete, Network::UserStream>;
|
||||||
|
|
||||||
static void serve( int host_fd,
|
static void serve( int host_fd,
|
||||||
|
int pipe_fd,
|
||||||
Terminal::Complete &terminal,
|
Terminal::Complete &terminal,
|
||||||
ServerConnection &network,
|
ServerConnection &network,
|
||||||
long network_timeout,
|
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() ) );
|
snprintf( utmp_entry, 64, "mosh [%ld]", static_cast<long int>( getpid() ) );
|
||||||
|
|
||||||
/* Fork child process */
|
/* 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 );
|
pid_t child = forkpty( &master, NULL, NULL, &window_size );
|
||||||
|
|
||||||
if ( child == -1 ) {
|
if ( child == -1 ) {
|
||||||
@@ -518,6 +525,10 @@ static int run_server( const char *desired_ip, const char *desired_port,
|
|||||||
|
|
||||||
if ( child == 0 ) {
|
if ( child == 0 ) {
|
||||||
/* child */
|
/* child */
|
||||||
|
if ( close( pipes[1] ) < 0 ) {
|
||||||
|
perror( "child write pipe close" );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
/* reenable signals */
|
/* reenable signals */
|
||||||
struct sigaction sa;
|
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. */
|
/* Wait for parent to release us. */
|
||||||
char linebuf[81];
|
char linebuf[81];
|
||||||
if (fgets(linebuf, sizeof linebuf, stdin) == NULL) {
|
// -1, errno == EINTR -- retry
|
||||||
err( 1, "parent signal" );
|
// otherwise, give up
|
||||||
|
while ( read( pipes[0], linebuf, sizeof( linebuf ) ) == -1 ) {
|
||||||
|
if ( errno != EINTR ) {
|
||||||
|
err( 1, "parent signal" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Crypto::reenable_dumping_core();
|
Crypto::reenable_dumping_core();
|
||||||
@@ -604,8 +619,17 @@ static int run_server( const char *desired_ip, const char *desired_port,
|
|||||||
sleep( 3 );
|
sleep( 3 );
|
||||||
exit( 1 );
|
exit( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( close( pipes[0] ) < 0 ) {
|
||||||
|
perror( "child read pipe close" );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* parent */
|
/* parent */
|
||||||
|
if ( close(pipes[0]) < 0 ) {
|
||||||
|
perror( "parent read pipe close" );
|
||||||
|
exit( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
/* Drop unnecessary privileges */
|
/* Drop unnecessary privileges */
|
||||||
#ifdef HAVE_PLEDGE
|
#ifdef HAVE_PLEDGE
|
||||||
@@ -622,7 +646,7 @@ static int run_server( const char *desired_ip, const char *desired_port,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
try {
|
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 ) {
|
} catch ( const Network::NetworkException &e ) {
|
||||||
fprintf( stderr, "Network exception: %s\n",
|
fprintf( stderr, "Network exception: %s\n",
|
||||||
e.what() );
|
e.what() );
|
||||||
@@ -646,7 +670,7 @@ static int run_server( const char *desired_ip, const char *desired_port,
|
|||||||
return 0;
|
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 */
|
/* scale timeouts */
|
||||||
const uint64_t network_timeout_ms = static_cast<uint64_t>( network_timeout ) * 1000;
|
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. */
|
/* Tell child to start login session. */
|
||||||
if ( !child_released ) {
|
if ( !child_released ) {
|
||||||
if ( swrite( host_fd, "\n", 1 ) < 0) {
|
if ( close( pipe_fd ) < 0 ) {
|
||||||
err( 1, "child release" );
|
err( 1, "child release" );
|
||||||
}
|
}
|
||||||
child_released = true;
|
child_released = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user