From 9a3ab83783939b298fdd2e5bae6cbe1819ffd484 Mon Sep 17 00:00:00 2001 From: Quentin Smith Date: Sun, 26 Feb 2012 20:50:17 -0500 Subject: [PATCH] Use libstddjb's selfpipe instead of signalfd Use selfpipe in our client, server, and examples. --- src/examples/Makefile.am | 2 + src/examples/termemu.cc | 30 ++++++------ src/frontend/Makefile.am | 2 + src/frontend/mosh-server.cc | 43 ++++++++++-------- src/frontend/stmclient.cc | 91 ++++++++++++++----------------------- src/frontend/stmclient.h | 4 +- 6 files changed, 79 insertions(+), 93 deletions(-) diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am index 21ad2da..a02a391 100644 --- a/src/examples/Makefile.am +++ b/src/examples/Makefile.am @@ -18,6 +18,8 @@ parse_LDADD = ../terminal/libmoshterminal.a ../util/libmoshutil.a -lutil $(BOOST termemu_SOURCES = termemu.cc termemu_CPPFLAGS = -I$(srcdir)/../terminal -I$(srcdir)/../util -I$(srcdir)/../statesync -I$(builddir)/../protobufs termemu_LDADD = ../terminal/libmoshterminal.a ../util/libmoshutil.a ../statesync/libmoshstatesync.a ../protobufs/libmoshprotos.a -lutil $(BOOST_LDFLAGS) $(protobuf_LIBS) +termemu_CPPFLAGS += $(STDDJB_CPPFLAGS) +termemu_LDADD += $(STDDJB_LDFLAGS) ntester_SOURCES = ntester.cc ntester_CPPFLAGS = -I$(srcdir)/../statesync -I$(srcdir)/../terminal -I$(srcdir)/../network -I$(srcdir)/../crypto -I$(builddir)/../protobufs $(BOOST_CPPFLAGS) diff --git a/src/examples/termemu.cc b/src/examples/termemu.cc index f1b5bea..0732137 100644 --- a/src/examples/termemu.cc +++ b/src/examples/termemu.cc @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -51,6 +50,10 @@ #include "completeterminal.h" #include "swrite.h" +extern "C" { +#include "selfpipe.h" +} + const size_t buf_size = 16384; void emulate_terminal( int fd ); @@ -193,19 +196,14 @@ bool tick( Terminal::Framebuffer &state, const Terminal::Framebuffer &new_frame void emulate_terminal( int fd ) { /* establish WINCH fd and start listening for signal */ - sigset_t signal_mask; - assert( sigemptyset( &signal_mask ) == 0 ); - assert( sigaddset( &signal_mask, SIGWINCH ) == 0 ); - - /* stop "ignoring" WINCH signal */ - assert( sigprocmask( SIG_BLOCK, &signal_mask, NULL ) == 0 ); - - int winch_fd = signalfd( -1, &signal_mask, 0 ); - if ( winch_fd < 0 ) { - perror( "signalfd" ); + int signal_fd = selfpipe_init(); + if ( signal_fd < 0 ) { + perror( "selfpipe" ); return; } + assert( selfpipe_trap(SIGWINCH) == 0 ); + /* get current window size */ struct winsize window_size; if ( ioctl( STDIN_FILENO, TIOCGWINSZ, &window_size ) < 0 ) { @@ -231,7 +229,7 @@ void emulate_terminal( int fd ) pollfds[ 1 ].fd = fd; pollfds[ 1 ].events = POLLIN; - pollfds[ 2 ].fd = winch_fd; + pollfds[ 2 ].fd = signal_fd; pollfds[ 2 ].events = POLLIN; swrite( STDOUT_FILENO, Terminal::Emulator::open().c_str() ); @@ -240,7 +238,9 @@ void emulate_terminal( int fd ) while ( 1 ) { int active_fds = poll( pollfds, 3, poll_timeout ); - if ( active_fds < 0 ) { + if ( active_fds < 0 && errno == EINTR ) { + continue; + } else if ( active_fds < 0 ) { perror( "poll" ); break; } @@ -287,9 +287,7 @@ void emulate_terminal( int fd ) } } else if ( pollfds[ 2 ].revents & POLLIN ) { /* resize */ - struct signalfd_siginfo info; - assert( read( winch_fd, &info, sizeof( info ) ) == sizeof( info ) ); - assert( info.ssi_signo == SIGWINCH ); + assert( selfpipe_read() == SIGWINCH ); /* get new size */ if ( ioctl( STDIN_FILENO, TIOCGWINSZ, &window_size ) < 0 ) { diff --git a/src/frontend/Makefile.am b/src/frontend/Makefile.am index 8be429a..66abb02 100644 --- a/src/frontend/Makefile.am +++ b/src/frontend/Makefile.am @@ -1,6 +1,8 @@ AM_CPPFLAGS = -I$(srcdir)/../statesync -I$(srcdir)/../terminal -I$(srcdir)/../network -I$(srcdir)/../crypto -I$(builddir)/../protobufs -I$(srcdir)/../util $(BOOST_CPPFLAGS) $(protobuf_CFLAGS) AM_CXXFLAGS = $(WARNING_CXXFLAGS) $(PICKY_CXXFLAGS) -fno-default-inline -pipe LDADD = ../crypto/libmoshcrypto.a ../network/libmoshnetwork.a ../statesync/libmoshstatesync.a ../terminal/libmoshterminal.a ../util/libmoshutil.a ../protobufs/libmoshprotos.a -lutil -lm $(protobuf_LIBS) +AM_CPPFLAGS += $(STDDJB_CPPFLAGS) +LDADD += $(STDDJB_LDFLAGS) bin_PROGRAMS = mosh-client mosh-server diff --git a/src/frontend/mosh-server.cc b/src/frontend/mosh-server.cc index 4ca4d99..7fc2d48 100644 --- a/src/frontend/mosh-server.cc +++ b/src/frontend/mosh-server.cc @@ -18,13 +18,13 @@ #include "config.h" +#include #include #include #include #include #include #include -#include #include #include #include @@ -32,7 +32,6 @@ #include #include #include -#include #ifdef HAVE_UTEMPTER #include #endif @@ -40,10 +39,20 @@ #include #include +extern "C" { +#include "selfpipe.h" +} + #include "completeterminal.h" #include "swrite.h" #include "user.h" +#if HAVE_PTY_H +#include +#elif HAVE_UTIL_H +#include +#endif + #include "networktransport.cc" typedef Network::Transport< Terminal::Complete, Network::UserStream > ServerConnection; @@ -222,18 +231,15 @@ int main( int argc, char *argv[] ) void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network ) { /* establish fd for shutdown signals */ - sigset_t signal_mask; - - assert( sigemptyset( &signal_mask ) == 0 ); - assert( sigaddset( &signal_mask, SIGTERM ) == 0 ); - assert( sigaddset( &signal_mask, SIGINT ) == 0 ); - - int shutdown_signal_fd = signalfd( -1, &signal_mask, 0 ); - if ( shutdown_signal_fd < 0 ) { - perror( "signalfd" ); + int signal_fd = selfpipe_init(); + if ( signal_fd < 0 ) { + perror( "selfpipe" ); return; } + assert( selfpipe_trap( SIGTERM ) == 0 ); + assert( selfpipe_trap( SIGINT ) == 0 ); + /* prepare to poll for events */ struct pollfd pollfds[ 3 ]; @@ -243,7 +249,7 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network pollfds[ 1 ].fd = host_fd; pollfds[ 1 ].events = POLLIN; - pollfds[ 2 ].fd = shutdown_signal_fd; + pollfds[ 2 ].fd = signal_fd; pollfds[ 2 ].events = POLLIN; uint64_t last_remote_num = network.get_remote_state_num(); @@ -266,7 +272,9 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network } int active_fds = poll( pollfds, 3, poll_timeout ); - if ( active_fds < 0 ) { + if ( active_fds < 0 && errno == EINTR ) { + continue; + } else if ( active_fds < 0 ) { perror( "poll" ); break; } @@ -364,12 +372,11 @@ void serve( int host_fd, Terminal::Complete &terminal, ServerConnection &network if ( pollfds[ 2 ].revents & POLLIN ) { /* shutdown signal */ - struct signalfd_siginfo the_siginfo; - ssize_t bytes_read = read( pollfds[ 2 ].fd, &the_siginfo, sizeof( the_siginfo ) ); - if ( bytes_read == 0 ) { + int signo = selfpipe_read(); + if ( signo == 0 ) { break; - } else if ( bytes_read < 0 ) { - perror( "read" ); + } else if ( signo < 0 ) { + perror( "selfpipe_read" ); break; } diff --git a/src/frontend/stmclient.cc b/src/frontend/stmclient.cc index fc02ffd..5f8c33a 100644 --- a/src/frontend/stmclient.cc +++ b/src/frontend/stmclient.cc @@ -18,6 +18,7 @@ #include "config.h" +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #if HAVE_PTY_H @@ -38,6 +38,10 @@ #include #endif +extern "C" { +#include "selfpipe.h" +} + #include "stmclient.h" #include "swrite.h" #include "completeterminal.h" @@ -101,37 +105,21 @@ void STMClient::shutdown( void ) void STMClient::main_init( void ) { /* establish WINCH fd and start listening for signal */ - sigset_t signal_mask; - assert( sigemptyset( &signal_mask ) == 0 ); - assert( sigaddset( &signal_mask, SIGWINCH ) == 0 ); - - /* stop "ignoring" WINCH signal */ - assert( sigprocmask( SIG_BLOCK, &signal_mask, NULL ) == 0 ); - - winch_fd = signalfd( -1, &signal_mask, 0 ); - if ( winch_fd < 0 ) { - perror( "signalfd" ); + signal_fd = selfpipe_init(); + if ( signal_fd < 0 ) { + perror( "selfpipe" ); return; } + assert( selfpipe_trap(SIGWINCH) == 0 ); + /* establish fd for shutdown signals */ - assert( sigemptyset( &signal_mask ) == 0 ); - assert( sigaddset( &signal_mask, SIGTERM ) == 0 ); - assert( sigaddset( &signal_mask, SIGINT ) == 0 ); - assert( sigaddset( &signal_mask, SIGHUP ) == 0 ); - assert( sigaddset( &signal_mask, SIGPIPE ) == 0 ); - assert( sigaddset( &signal_mask, SIGTSTP ) == 0 ); - assert( sigaddset( &signal_mask, SIGSTOP ) == 0 ); - assert( sigaddset( &signal_mask, SIGCONT ) == 0 ); - - /* don't let signals kill us */ - assert( sigprocmask( SIG_BLOCK, &signal_mask, NULL ) == 0 ); - - shutdown_signal_fd = signalfd( -1, &signal_mask, 0 ); - if ( shutdown_signal_fd < 0 ) { - perror( "signalfd" ); - return; - } + assert( selfpipe_trap( SIGTERM ) == 0 ); + assert( selfpipe_trap( SIGINT ) == 0 ); + assert( selfpipe_trap( SIGHUP ) == 0 ); + assert( selfpipe_trap( SIGPIPE ) == 0 ); + assert( selfpipe_trap( SIGTSTP ) == 0 ); + assert( selfpipe_trap( SIGCONT ) == 0 ); /* get initial window size */ if ( ioctl( STDIN_FILENO, TIOCGWINSZ, &window_size ) < 0 ) { @@ -256,10 +244,6 @@ bool STMClient::process_user_input( int fd ) bool STMClient::process_resize( void ) { - struct signalfd_siginfo info; - assert( read( winch_fd, &info, sizeof( info ) ) == sizeof( info ) ); - assert( info.ssi_signo == SIGWINCH ); - /* get new size */ if ( ioctl( STDIN_FILENO, TIOCGWINSZ, &window_size ) < 0 ) { perror( "ioctl TIOCGWINSZ" ); @@ -287,7 +271,7 @@ void STMClient::main( void ) main_init(); /* prepare to poll for events */ - struct pollfd pollfds[ 4 ]; + struct pollfd pollfds[ 3 ]; pollfds[ 0 ].fd = network->fd(); pollfds[ 0 ].events = POLLIN; @@ -295,18 +279,17 @@ void STMClient::main( void ) pollfds[ 1 ].fd = STDIN_FILENO; pollfds[ 1 ].events = POLLIN; - pollfds[ 2 ].fd = winch_fd; + pollfds[ 2 ].fd = signal_fd; pollfds[ 2 ].events = POLLIN; - pollfds[ 3 ].fd = shutdown_signal_fd; - pollfds[ 3 ].events = POLLIN; - while ( 1 ) { try { output_new_frame(); - int active_fds = poll( pollfds, 4, min( network->wait_time(), overlays.wait_time() ) ); - if ( active_fds < 0 ) { + int active_fds = poll( pollfds, 3, min( network->wait_time(), overlays.wait_time() ) ); + if ( active_fds < 0 && errno == EINTR ) { + continue; + } else if ( active_fds < 0 ) { perror( "poll" ); break; } @@ -329,26 +312,20 @@ void STMClient::main( void ) } if ( pollfds[ 2 ].revents & POLLIN ) { - /* resize */ - if ( !process_resize() ) { return; } - } + int signo = selfpipe_read(); - if ( pollfds[ 3 ].revents & POLLIN ) { - /* shutdown signal */ - struct signalfd_siginfo the_siginfo; - ssize_t bytes_read = read( pollfds[ 3 ].fd, &the_siginfo, sizeof( the_siginfo ) ); - if ( bytes_read == 0 ) { - break; - } else if ( bytes_read < 0 ) { - perror( "read" ); - break; - } + if ( signo == SIGWINCH ) { + /* resize */ + if ( !process_resize() ) { return; } + } else if ( signo > 0 ) { + /* shutdown signal */ - if ( !network->has_remote_addr() ) { - break; - } else if ( !network->shutdown_in_progress() ) { - overlays.get_notification_engine().set_notification_string( wstring( L"Signal received, shutting down..." ) ); - network->start_shutdown(); + if ( !network->has_remote_addr() ) { + break; + } else if ( !network->shutdown_in_progress() ) { + overlays.get_notification_engine().set_notification_string( wstring( L"Signal received, shutting down..." ) ); + network->start_shutdown(); + } } } diff --git a/src/frontend/stmclient.h b/src/frontend/stmclient.h index 2256702..9e24265 100644 --- a/src/frontend/stmclient.h +++ b/src/frontend/stmclient.h @@ -36,7 +36,7 @@ private: struct termios saved_termios, raw_termios; - int winch_fd, shutdown_signal_fd; + int signal_fd; struct winsize window_size; Terminal::Framebuffer *local_framebuffer; @@ -56,7 +56,7 @@ public: STMClient( const char *s_ip, int s_port, const char *s_key, const char *predict_mode ) : ip( s_ip ), port( s_port ), key( s_key ), saved_termios(), raw_termios(), - winch_fd(), shutdown_signal_fd(), + signal_fd(), window_size(), local_framebuffer( NULL ), overlays(),