NSM/NSM Proxy: Add two new options. Stop Signal and Config File.

This commit is contained in:
Jonathan Moore Liles 2013-08-13 17:35:08 -07:00
parent 21ab68d3e5
commit 9b8f02fbf3
3 changed files with 138 additions and 19 deletions

View File

@ -7,31 +7,31 @@ class NSM_Proxy_UI {open
Function {make_window()} {open Function {make_window()} {open
} { } {
Fl_Window {} { Fl_Window {} {
label {NSM Proxy} open label {NSM Proxy} open selected
xywh {1011 106 490 665} type Double color 47 labelcolor 55 visible xclass NSM-Proxy xywh {644 190 635 665} type Double color 47 labelcolor 55 xclass {NSM-Proxy} visible
} { } {
Fl_Box {} { Fl_Box {} {
label {Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly. This proxy exists to allow programs which require command-line options to be included in an NSM session. Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. Patching the program to use NSM natively will result in a better experience. label {Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly. This proxy exists to allow programs which require command-line options to be included in an NSM session. Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. Patching the program to use NSM natively will result in a better experience.
The program will be started with its current directory being a uniquely named directory under the current session directory. It is recommended that you only refer to files in the current directory. The program will be started with its current directory being a uniquely named directory under the current session directory. It is recommended that you only refer to files in the current directory.
} selected }
xywh {15 11 460 233} box BORDER_BOX color 41 labelfont 8 labelcolor 55 align 128 xywh {15 11 610 139} box BORDER_BOX color 41 labelfont 8 labelsize 12 labelcolor 55 align 128
} }
Fl_File_Input executable_input { Fl_File_Input executable_input {
label {Executable: } label {Executable: }
xywh {115 262 350 33} xywh {115 162 495 31}
} }
Fl_Input arguments_input { Fl_Input arguments_input {
label {Arguments:} label {Arguments:}
xywh {115 414 350 28} xywh {110 310 350 28}
} }
Fl_Input label_input { Fl_Input label_input {
label {Label:} label {Label:}
xywh {115 452 350 28} xywh {110 340 350 28}
} }
Fl_Return_Button start_button { Fl_Return_Button start_button {
label Start label Start
xywh {380 625 88 25} xywh {535 630 88 25}
} }
Fl_Button kill_button { Fl_Button kill_button {
label Kill label Kill
@ -39,7 +39,7 @@ The program will be started with its current directory being a uniquely named di
} }
Fl_Choice save_signal_choice { Fl_Choice save_signal_choice {
label {Save Signal:} open label {Save Signal:} open
xywh {110 625 170 25} down_box BORDER_BOX xywh {110 468 170 25} down_box BORDER_BOX
} { } {
MenuItem {} { MenuItem {} {
label None label None
@ -59,12 +59,41 @@ The program will be started with its current directory being a uniquely named di
} }
} }
Fl_Box {} { Fl_Box {} {
label {The environment variables $NSM_CLIENT_ID and $NSM_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.} label {The environment variables $NSM_CLIENT_ID and $NSM_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively. The variable $CONFIG_FILE will contain the name of the config file selected above.}
xywh {15 312 460 87} box BORDER_BOX color 41 labelfont 8 labelcolor 55 align 128 xywh {15 235 610 69} box BORDER_BOX color 41 labelfont 8 labelsize 12 labelcolor 55 align 128
} }
Fl_Box {} { Fl_Box {} {
label {Some (very few) programs may respond to a specific Unix signal by somehow saving their state. If 'Save Signal' is set to something other than 'None', then NSM Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event. Most programs will treat these signals just like SIGTERM and die. You have been warned.} label {Some (very few) programs may respond to a specific Unix signal by somehow saving their state. If 'Save Signal' is set to something other than 'None', then NSM Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event. Most programs will treat these signals just like SIGTERM and die. You have been warned.}
xywh {15 497 460 114} box BORDER_BOX color 41 labelfont 8 labelcolor 55 align 128 xywh {15 378 610 79} box BORDER_BOX color 41 labelfont 8 labelsize 12 labelcolor 55 align 128
}
Fl_Choice stop_signal_choice {
label {Stop Signal:} open
xywh {108 592 170 25} down_box BORDER_BOX
} {
MenuItem {} {
label SIGTERM
xywh {10 10 40 24}
}
MenuItem {} {
label SIGINT
xywh {40 40 40 24}
}
MenuItem {} {
label SIGHUP
xywh {50 50 40 24}
}
}
Fl_Box {} {
label {Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal. It's impossible to know which signal a specific program will respond to. A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK). Check the program's documentation or source code to determine which signal to use to stop it gracefully.}
xywh {15 502 610 79} box BORDER_BOX color 41 labelfont 8 labelsize 12 labelcolor 55 align 128
}
Fl_File_Input config_file_input {
label {Config File:}
xywh {114 195 406 31}
}
Fl_Button config_file_browse_button {
label Browse
xywh {530 195 85 25}
} }
} }
} }

View File

@ -25,6 +25,7 @@
#define APP_NAME "NSM Proxy" #define APP_NAME "NSM Proxy"
#define APP_TITLE "NSM Proxy" #define APP_TITLE "NSM Proxy"
#include <FL/Fl_File_Chooser.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>
@ -50,6 +51,8 @@ osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_me
ui->arguments_input->value( &argv[0]->s ); ui->arguments_input->value( &argv[0]->s );
else if (!strcmp( path, "/nsm/proxy/executable" )) else if (!strcmp( path, "/nsm/proxy/executable" ))
ui->executable_input->value( &argv[0]->s ); ui->executable_input->value( &argv[0]->s );
else if (!strcmp( path, "/nsm/proxy/config_file" ))
ui->config_file_input->value( &argv[0]->s );
else if (!strcmp( path, "/nsm/proxy/save_signal" )) else if (!strcmp( path, "/nsm/proxy/save_signal" ))
{ {
if ( argv[0]->i == SIGUSR1 ) if ( argv[0]->i == SIGUSR1 )
@ -61,6 +64,15 @@ osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_me
else else
ui->save_signal_choice->value( 0 ); ui->save_signal_choice->value( 0 );
} }
else if (!strcmp( path, "/nsm/proxy/stop_signal" ))
{
if ( argv[0]->i == SIGTERM )
ui->stop_signal_choice->value( 0 );
else if ( argv[0]->i == SIGINT )
ui->stop_signal_choice->value( 1 );
else if ( argv[0]->i == SIGHUP )
ui->stop_signal_choice->value( 2 );
}
Fl::unlock(); Fl::unlock();
@ -85,8 +97,10 @@ init_osc ( const char *osc_port )
lo_server_thread_add_method( loth, "/nsm/proxy/executable", "s", osc_update, NULL ); lo_server_thread_add_method( loth, "/nsm/proxy/executable", "s", osc_update, NULL );
lo_server_thread_add_method( loth, "/nsm/proxy/arguments", "s", osc_update, NULL ); lo_server_thread_add_method( loth, "/nsm/proxy/arguments", "s", osc_update, NULL );
lo_server_thread_add_method( loth, "/nsm/proxy/config_file", "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/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_start( loth ); lo_server_thread_start( loth );
} }
@ -104,9 +118,10 @@ handle_kill ( Fl_Widget *o, void *v )
void void
handle_start ( Fl_Widget *o, void *v ) handle_start ( Fl_Widget *o, void *v )
{ {
lo_send_from( nsmp_addr, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/start", "ss", lo_send_from( nsmp_addr, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/start", "sss",
ui->executable_input->value(), ui->executable_input->value(),
ui->arguments_input->value() ); ui->arguments_input->value(),
ui->config_file_input->value() );
} }
void void
@ -122,6 +137,20 @@ handle_executable ( Fl_Widget *o, void *v )
ui->label_input->value( ui->executable_input->value() ); ui->label_input->value( ui->executable_input->value() );
} }
void
handle_config_file ( Fl_Widget *o, void *v )
{
}
void
handle_config_file_browse ( Fl_Widget *o, void *v )
{
const char * file = fl_file_chooser( "Pick file", "*", NULL, 1 );
ui->config_file_input->value( file );
}
void void
handle_save_signal ( Fl_Widget *o, void *v ) handle_save_signal ( Fl_Widget *o, void *v )
{ {
@ -140,14 +169,35 @@ handle_save_signal ( Fl_Widget *o, void *v )
sig ); sig );
} }
void
handle_stop_signal ( Fl_Widget *o, void *v )
{
int sig = SIGTERM;
const char* picked = ui->stop_signal_choice->mvalue()->label();
if ( !strcmp( picked, "SIGTERM" ) )
sig = SIGTERM;
else if ( !strcmp( picked, "SIGINT" ) )
sig = SIGINT;
else if ( !strcmp( picked, "SIGHUP" ) )
sig = SIGHUP;
lo_send_from( nsmp_addr, losrv, LO_TT_IMMEDIATE,"/nsm/proxy/stop_signal", "i",
sig );
}
void void
connect_ui ( void ) connect_ui ( void )
{ {
ui->executable_input->callback( handle_executable, NULL ); ui->executable_input->callback( handle_executable, NULL );
ui->config_file_input->callback( handle_config_file, NULL );
ui->kill_button->callback( handle_kill, NULL ); ui->kill_button->callback( handle_kill, NULL );
ui->start_button->callback( handle_start, NULL ); ui->start_button->callback( handle_start, NULL );
ui->save_signal_choice->callback( handle_save_signal, NULL ); ui->save_signal_choice->callback( handle_save_signal, NULL );
ui->stop_signal_choice->callback( handle_stop_signal, NULL );
ui->label_input->callback( handle_label, NULL ); ui->label_input->callback( handle_label, NULL );
ui->config_file_browse_button->callback( handle_config_file_browse, NULL );
} }

View File

@ -56,16 +56,19 @@ class NSM_Proxy {
char *_label; char *_label;
char *_executable; char *_executable;
char *_config_file;
char *_arguments; char *_arguments;
int _save_signal; int _save_signal;
int _stop_signal;
int _pid; int _pid;
public: public:
NSM_Proxy ( ) NSM_Proxy ( )
{ {
_label = _executable = _arguments = 0; _label = _executable = _arguments = _config_file = 0;
_save_signal = 0; _save_signal = 0;
_stop_signal = SIGTERM;
_pid = 0; _pid = 0;
} }
@ -76,15 +79,17 @@ public:
void kill ( void ) void kill ( void )
{ {
if ( _pid ) if ( _pid )
::kill( _pid, SIGTERM ); ::kill( _pid, _stop_signal );
} }
bool start ( const char *executable, const char *arguments ) bool start ( const char *executable, const char *arguments, const char *config_file )
{ {
if ( _executable ) if ( _executable )
free( _executable ); free( _executable );
if ( _arguments ) if ( _arguments )
free( _arguments ); free( _arguments );
if ( _config_file )
free( _config_file );
_executable = strdup( executable ); _executable = strdup( executable );
@ -93,6 +98,11 @@ public:
else else
_arguments = NULL; _arguments = NULL;
if ( config_file )
_config_file = strdup( config_file );
else
_config_file = NULL;
return start(); return start();
} }
@ -128,6 +138,8 @@ public:
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 );
if ( _config_file )
setenv( "CONFIG_FILE", _config_file, 1 );
unsetenv( "NSM_URL" ); unsetenv( "NSM_URL" );
if ( -1 == execvp( "/bin/sh", args ) ) if ( -1 == execvp( "/bin/sh", args ) )
@ -147,6 +159,11 @@ public:
{ {
_save_signal = s; _save_signal = s;
} }
void stop_signal ( int s )
{
_stop_signal = s;
}
void label ( const char *s ) void label ( const char *s )
{ {
@ -187,7 +204,12 @@ public:
if ( _arguments && strlen(_arguments) ) if ( _arguments && strlen(_arguments) )
fprintf( fp, "arguments\n\t%s\n", _arguments ); fprintf( fp, "arguments\n\t%s\n", _arguments );
if ( _config_file && strlen(_config_file) )
fprintf( fp, "config file\n\t%s\n", _config_file );
fprintf( fp, "save signal\n\t%i\n", _save_signal ); fprintf( fp, "save signal\n\t%i\n", _save_signal );
fprintf( fp, "stop signal\n\t%i\n", _stop_signal );
if ( _label && strlen(_label) ) if ( _label && strlen(_label) )
fprintf( fp, "label\n\t%s\n", _label ); fprintf( fp, "label\n\t%s\n", _label );
@ -221,11 +243,18 @@ public:
_executable = value; _executable = value;
else if (!strcmp( name, "arguments" ) ) else if (!strcmp( name, "arguments" ) )
_arguments = value; _arguments = value;
else if (!strcmp( name, "config file" ) )
_config_file = value;
else if ( !strcmp( name, "save signal" ) ) else if ( !strcmp( name, "save signal" ) )
{ {
_save_signal = atoi( value ); _save_signal = atoi( value );
free( value ); free( value );
} }
else if ( !strcmp( name, "stop signal" ) )
{
_stop_signal = atoi( value );
free( value );
}
else if ( !strcmp( name, "label" ) ) else if ( !strcmp( name, "label" ) )
{ {
label( value ); label( value );
@ -254,6 +283,8 @@ public:
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/label", "s", _label ? _label : "" ); lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/label", "s", _label ? _label : "" );
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/executable", "s", _executable ? _executable : "" ); lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/executable", "s", _executable ? _executable : "" );
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/stop_signal", "i", _stop_signal );
} }
}; };
@ -493,12 +524,20 @@ osc_save_signal ( const char *path, const char *types, lo_arg **argv, int argc,
return 0; return 0;
} }
int
osc_stop_signal ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
{
nsm_proxy->stop_signal( argv[0]->i );
return 0;
}
int int
osc_start ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) osc_start ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
{ {
snapshot( project_file ); snapshot( project_file );
if ( nsm_proxy->start( &argv[0]->s, &argv[1]->s ) ) if ( nsm_proxy->start( &argv[0]->s, &argv[1]->s, &argv[2]->s ) )
{ {
hide_gui(); hide_gui();
} }
@ -567,8 +606,9 @@ init_osc ( const char *osc_port )
/* GUI */ /* GUI */
lo_server_add_method( losrv, "/nsm/proxy/label", "s", osc_label, NULL ); lo_server_add_method( losrv, "/nsm/proxy/label", "s", osc_label, NULL );
lo_server_add_method( losrv, "/nsm/proxy/save_signal", "i", osc_save_signal, NULL ); lo_server_add_method( losrv, "/nsm/proxy/save_signal", "i", osc_save_signal, NULL );
lo_server_add_method( losrv, "/nsm/proxy/stop_signal", "i", osc_stop_signal, NULL );
lo_server_add_method( losrv, "/nsm/proxy/kill", "", osc_kill, NULL ); lo_server_add_method( losrv, "/nsm/proxy/kill", "", osc_kill, NULL );
lo_server_add_method( losrv, "/nsm/proxy/start", "ss", osc_start, NULL ); lo_server_add_method( losrv, "/nsm/proxy/start", "sss", osc_start, NULL );
lo_server_add_method( losrv, "/nsm/proxy/update", "", osc_update, NULL ); lo_server_add_method( losrv, "/nsm/proxy/update", "", osc_update, NULL );
} }