NSM Proxy: Detect, log, and display startup errors of proxied process.
This commit is contained in:
parent
6bd899f223
commit
e230929a57
|
@ -26,6 +26,7 @@
|
||||||
#define APP_TITLE "NSM Proxy"
|
#define APP_TITLE "NSM Proxy"
|
||||||
|
|
||||||
#include <FL/Fl_File_Chooser.H>
|
#include <FL/Fl_File_Chooser.H>
|
||||||
|
#include <FL/Fl_Text_Display.H>
|
||||||
#include "NSM_Proxy_UI.H"
|
#include "NSM_Proxy_UI.H"
|
||||||
#include <lo/lo.h>
|
#include <lo/lo.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -38,6 +39,8 @@ lo_address nsmp_addr;
|
||||||
|
|
||||||
static NSM_Proxy_UI *ui;
|
static NSM_Proxy_UI *ui;
|
||||||
|
|
||||||
|
static char *client_error;
|
||||||
|
|
||||||
int
|
int
|
||||||
osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
|
||||||
{
|
{
|
||||||
|
@ -73,6 +76,16 @@ osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_me
|
||||||
else if ( argv[0]->i == SIGHUP )
|
else if ( argv[0]->i == SIGHUP )
|
||||||
ui->stop_signal_choice->value( 2 );
|
ui->stop_signal_choice->value( 2 );
|
||||||
}
|
}
|
||||||
|
if (!strcmp( path, "/nsm/proxy/client_error" ))
|
||||||
|
{
|
||||||
|
if ( client_error != NULL )
|
||||||
|
free(client_error);
|
||||||
|
|
||||||
|
client_error = NULL;
|
||||||
|
|
||||||
|
if ( strlen(&argv[0]->s) > 0 )
|
||||||
|
client_error = strdup(&argv[0]->s);
|
||||||
|
}
|
||||||
|
|
||||||
Fl::unlock();
|
Fl::unlock();
|
||||||
|
|
||||||
|
@ -101,6 +114,7 @@ init_osc ( const char *osc_port )
|
||||||
lo_server_thread_add_method( loth, "/nsm/proxy/label", "s", osc_update, NULL );
|
lo_server_thread_add_method( loth, "/nsm/proxy/label", "s", osc_update, NULL );
|
||||||
lo_server_thread_add_method( loth, "/nsm/proxy/save_signal", "i", osc_update, NULL );
|
lo_server_thread_add_method( loth, "/nsm/proxy/save_signal", "i", osc_update, NULL );
|
||||||
lo_server_thread_add_method( loth, "/nsm/proxy/stop_signal", "i", osc_update, NULL );
|
lo_server_thread_add_method( loth, "/nsm/proxy/stop_signal", "i", osc_update, NULL );
|
||||||
|
lo_server_thread_add_method( loth, "/nsm/proxy/client_error", "s", osc_update, NULL );
|
||||||
|
|
||||||
lo_server_thread_start( loth );
|
lo_server_thread_start( loth );
|
||||||
}
|
}
|
||||||
|
@ -202,6 +216,46 @@ connect_ui ( void )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cb_dismiss_button ( Fl_Widget *w, void *v )
|
||||||
|
{
|
||||||
|
w->window()->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
check_error ( void *v )
|
||||||
|
{
|
||||||
|
if ( client_error )
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Fl_Double_Window *o = new Fl_Double_Window(600,300+15,"Abnormal Termination");
|
||||||
|
{
|
||||||
|
Fl_Box *o = new Fl_Box(0+15,0+15,600-30,50);
|
||||||
|
o->box(FL_BORDER_BOX);
|
||||||
|
o->color(FL_RED);
|
||||||
|
o->labelcolor(FL_WHITE);
|
||||||
|
o->align(FL_ALIGN_CENTER|FL_ALIGN_WRAP);
|
||||||
|
o->copy_label( client_error );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Fl_Text_Display *o = new Fl_Text_Display(0+15,50+15,600-30,300-75-30);
|
||||||
|
o->buffer(new Fl_Text_Buffer());
|
||||||
|
o->buffer()->loadfile( "error.log" );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Fl_Button *o = new Fl_Button(600-75-15,300-25,75,25,"Dismiss");
|
||||||
|
o->callback(cb_dismiss_button,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
o->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
free(client_error);
|
||||||
|
client_error = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fl::repeat_timeout( 0.5f, check_error, v );
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main ( int argc, char **argv )
|
main ( int argc, char **argv )
|
||||||
{
|
{
|
||||||
|
@ -229,6 +283,8 @@ main ( int argc, char **argv )
|
||||||
|
|
||||||
Fl::lock();
|
Fl::lock();
|
||||||
|
|
||||||
|
Fl::add_timeout( 0.5f, check_error, NULL );
|
||||||
|
|
||||||
Fl::run();
|
Fl::run();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -51,6 +51,7 @@ static char *nsm_display_name;
|
||||||
|
|
||||||
#define CONFIG_FILE_NAME "nsm-proxy.config"
|
#define CONFIG_FILE_NAME "nsm-proxy.config"
|
||||||
|
|
||||||
|
void show_gui ( void );
|
||||||
|
|
||||||
class NSM_Proxy {
|
class NSM_Proxy {
|
||||||
|
|
||||||
|
@ -61,25 +62,46 @@ class NSM_Proxy {
|
||||||
int _save_signal;
|
int _save_signal;
|
||||||
int _stop_signal;
|
int _stop_signal;
|
||||||
int _pid;
|
int _pid;
|
||||||
|
char *_client_error;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
int stop_signal ( void ) {return _stop_signal;}
|
||||||
|
|
||||||
NSM_Proxy ( )
|
NSM_Proxy ( )
|
||||||
{
|
{
|
||||||
_label = _executable = _arguments = _config_file = 0;
|
_label = _executable = _arguments = _config_file = 0;
|
||||||
_save_signal = 0;
|
_save_signal = 0;
|
||||||
_stop_signal = SIGTERM;
|
_stop_signal = SIGTERM;
|
||||||
_pid = 0;
|
_pid = 0;
|
||||||
|
_client_error = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
~NSM_Proxy ( )
|
~NSM_Proxy ( )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_client_death ( int status )
|
||||||
|
{
|
||||||
|
printf( "proxied process died unexpectedly... not dying\n" );
|
||||||
|
/* proxied process died unexpectedly */
|
||||||
|
|
||||||
|
if ( _client_error != NULL )
|
||||||
|
free(_client_error);
|
||||||
|
|
||||||
|
asprintf(&_client_error, "The proxied process terminated abnormally during invocation. Exit status: %i.", status );
|
||||||
|
|
||||||
|
show_gui();
|
||||||
|
|
||||||
|
_pid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void kill ( void )
|
void kill ( void )
|
||||||
{
|
{
|
||||||
if ( _pid )
|
if ( _pid )
|
||||||
|
{
|
||||||
::kill( _pid, _stop_signal );
|
::kill( _pid, _stop_signal );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start ( const char *executable, const char *arguments, const char *config_file )
|
bool start ( const char *executable, const char *arguments, const char *config_file )
|
||||||
|
@ -130,11 +152,11 @@ public:
|
||||||
char *cmd;
|
char *cmd;
|
||||||
|
|
||||||
if ( _arguments )
|
if ( _arguments )
|
||||||
asprintf( &cmd, "exec %s %s", _executable, _arguments );
|
asprintf( &cmd, "exec %s %s >error.log 2>&1", _executable, _arguments );
|
||||||
else
|
else
|
||||||
asprintf( &cmd, "exec %s", _executable );
|
asprintf( &cmd, "exec %s >error.log 2>&1", _executable );
|
||||||
|
|
||||||
char *args[] = { _executable, strdup( "-c" ), cmd, NULL };
|
char *args[] = { strdup("/bin/sh"), strdup( "-c" ), cmd, NULL };
|
||||||
|
|
||||||
setenv( "NSM_CLIENT_ID", nsm_client_id, 1 );
|
setenv( "NSM_CLIENT_ID", nsm_client_id, 1 );
|
||||||
setenv( "NSM_SESSION_NAME", nsm_display_name, 1 );
|
setenv( "NSM_SESSION_NAME", nsm_display_name, 1 );
|
||||||
|
@ -145,8 +167,7 @@ public:
|
||||||
if ( -1 == execvp( "/bin/sh", args ) )
|
if ( -1 == execvp( "/bin/sh", args ) )
|
||||||
{
|
{
|
||||||
WARNING( "Error starting process: %s", strerror( errno ) );
|
WARNING( "Error starting process: %s", strerror( errno ) );
|
||||||
|
exit(1);
|
||||||
exit(-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +243,6 @@ public:
|
||||||
bool restore ( const char *path )
|
bool restore ( const char *path )
|
||||||
{
|
{
|
||||||
FILE *fp = fopen( path, "r" );
|
FILE *fp = fopen( path, "r" );
|
||||||
|
|
||||||
if ( ! fp )
|
if ( ! fp )
|
||||||
{
|
{
|
||||||
WARNING( "Error opening file for restore: %s", strerror( errno ) );
|
WARNING( "Error opening file for restore: %s", strerror( errno ) );
|
||||||
|
@ -285,6 +305,9 @@ public:
|
||||||
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/arguments", "s", _arguments ? _arguments : "" );
|
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/arguments", "s", _arguments ? _arguments : "" );
|
||||||
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/config_file", "s", _config_file ? _config_file : "" );
|
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/config_file", "s", _config_file ? _config_file : "" );
|
||||||
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/stop_signal", "i", _stop_signal );
|
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/stop_signal", "i", _stop_signal );
|
||||||
|
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/client_error", "s", _client_error ? _client_error : "" );
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -400,7 +423,7 @@ show_gui ( void )
|
||||||
{
|
{
|
||||||
WARNING( "Error starting process: %s", strerror( errno ) );
|
WARNING( "Error starting process: %s", strerror( errno ) );
|
||||||
|
|
||||||
exit(-1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,10 +672,39 @@ void handle_sigchld ( )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* otherwise, it was our proxied process that died, so we should die too */
|
if ( WIFSIGNALED(status) )
|
||||||
printf( "proxied process died... nsm-proxy dying too\n" );
|
{
|
||||||
|
/* process was killed via signal */
|
||||||
|
if (WTERMSIG(status) == SIGTERM ||
|
||||||
|
WTERMSIG(status) == SIGHUP ||
|
||||||
|
WTERMSIG(status) == SIGINT ||
|
||||||
|
WTERMSIG(status) == SIGKILL )
|
||||||
|
{
|
||||||
|
/* process was killed via an appropriate signal */
|
||||||
|
MESSAGE( "child was killed (maybe by us)\n" );
|
||||||
|
die_now = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( WIFEXITED(status) )
|
||||||
|
{
|
||||||
|
/* child called exit() or returned from main() */
|
||||||
|
|
||||||
die_now = 1;
|
MESSAGE( "child exit status: %i", WEXITSTATUS(status) );
|
||||||
|
|
||||||
|
if ( WEXITSTATUS(status) == 0 )
|
||||||
|
{
|
||||||
|
/* apparently normal termination */
|
||||||
|
MESSAGE( "child exited without error.");
|
||||||
|
die_now = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MESSAGE("child exited abnormally.");
|
||||||
|
nsm_proxy->handle_client_death(WEXITSTATUS(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue