00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <signal.h>
00004 #include <glib.h>
00005 #include "utils/utils.h"
00006 #include "sed_signal.h"
00007
00008 G_GNUC_INTERNAL void _print_choices( int sig_num );
00009
00010 int
00011 sed_signal_set_action( void )
00012 {
00013 gint rtn_val;
00014 struct sigaction new_action, old_action;
00015
00016
00017 new_action.sa_handler = _print_choices;
00018 sigemptyset( &new_action.sa_mask );
00019 new_action.sa_flags = 0;
00020
00021
00022 rtn_val = sigaction( SIGINT , NULL , &old_action );
00023 if ( old_action.sa_handler != SIG_IGN )
00024 rtn_val = sigaction( SIGINT , &new_action , NULL );
00025
00026 return rtn_val;
00027 }
00028
00029 static gboolean __quit_signal = FALSE;
00030 static gboolean __exit_signal = FALSE;
00031 static gboolean __dump_signal = FALSE;
00032 static gboolean __user_signal = FALSE;
00033 static gboolean __next_signal = FALSE;
00034 static gboolean __cpr_signal = FALSE;
00035
00036 gboolean
00037 sed_signal_is_pending( Sed_sig_num sig )
00038 {
00039 gboolean is_pending = FALSE;
00040
00041 if ( sig==SED_SIG_QUIT && __quit_signal ) is_pending = TRUE;
00042 if ( sig==SED_SIG_EXIT && __exit_signal ) is_pending = TRUE;
00043 if ( sig==SED_SIG_DUMP && __dump_signal ) is_pending = TRUE;
00044 if ( sig==SED_SIG_CPR && __cpr_signal ) is_pending = TRUE;
00045 if ( sig==SED_SIG_NEXT && __next_signal ) is_pending = TRUE;
00046 if ( sig==SED_SIG_USER && __user_signal ) is_pending = TRUE;
00047
00048 return is_pending;
00049 }
00050
00051 void
00052 sed_signal_reset( Sed_sig_num sig )
00053 {
00054 if ( sig&SED_SIG_QUIT && __quit_signal ) __quit_signal = FALSE;
00055 if ( sig&SED_SIG_EXIT && __exit_signal ) __exit_signal = FALSE;
00056 if ( sig&SED_SIG_DUMP && __dump_signal ) __dump_signal = FALSE;
00057 if ( sig&SED_SIG_CPR && __cpr_signal ) __cpr_signal = FALSE;
00058 if ( sig&SED_SIG_NEXT && __next_signal ) __next_signal = FALSE;
00059 if ( sig&SED_SIG_USER && __user_signal ) __user_signal = FALSE;
00060
00061 return;
00062 }
00063
00064 void
00065 sed_signal_set( Sed_sig_num sig )
00066 {
00067 if ( sig&SED_SIG_QUIT ) __quit_signal = TRUE;
00068 if ( sig&SED_SIG_EXIT ) __exit_signal = TRUE;
00069 if ( sig&SED_SIG_DUMP ) __dump_signal = TRUE;
00070 if ( sig&SED_SIG_CPR ) __cpr_signal = TRUE;
00071 if ( sig&SED_SIG_NEXT ) __next_signal = TRUE;
00072 if ( sig&SED_SIG_USER ) __user_signal = TRUE;
00073
00074 return;
00075 }
00076
00077 static gchar* head_msg[] =
00078 {
00079 "-----------------------------------------------" ,
00080 NULL
00081 };
00082
00083 static gchar* body_msg[] =
00084 {
00085 " (1) End run after this time step." ,
00086 " (2) Dump results and continue." ,
00087 " (3) Continue (do nothing)." ,
00088 " (4) Jump to next epoch." ,
00089 " (5) Quit immediatly (without saving)." ,
00090 NULL
00091 };
00092
00093 static gchar* tail_msg[] =
00094 {
00095 "-----------------------------------------------" ,
00096 NULL
00097 };
00098
00099 static const gchar* pending_msg[] =
00100 {
00101 [SED_SIG_QUIT] = "Quitting sedflux..." ,
00102 [SED_SIG_DUMP] = "Dump output files at end of current time step..." ,
00103 [SED_SIG_CONT] = "Continuing..." ,
00104 [SED_SIG_NEXT] = "Jumping to next epoch..." ,
00105 [SED_SIG_EXIT] = "Exiting sedflux..." ,
00106 };
00107
00108 G_GNUC_INTERNAL
00109 void
00110 clear_to_eol( FILE* fp)
00111 {
00112 char c = fgetc( fp );
00113 while ( c!='\n' ) c = fgetc( fp );
00114 }
00115
00116 void
00117 _print_choices( int sig_num )
00118 {
00119 gchar** msg;
00120 Sed_sig_num signal;
00121 gchar ch;
00122
00123 for ( msg=head_msg ; *msg ; msg++ ) fprintf( stdout , "%s\n" , *msg );
00124 for ( msg=body_msg ; *msg ; msg++ ) fprintf( stdout , "%s\n" , *msg );
00125 for ( msg=tail_msg ; *msg ; msg++ ) fprintf( stdout , "%s\n" , *msg );
00126
00127 fprintf( stdout , " Your choice [3]? " );
00128
00129 ch = fgetc( stdin );
00130
00131 switch ( ch )
00132 {
00133 case '1': signal = SED_SIG_QUIT; break;
00134 case '2': signal = SED_SIG_DUMP; break;
00135 case '3': signal = SED_SIG_CONT; break;
00136 case '4': signal = SED_SIG_NEXT; break;
00137 case '5': signal = SED_SIG_EXIT; break;
00138 default : signal = SED_SIG_CONT;
00139 }
00140
00141 if ( ch!='\n' ) clear_to_eol( stdin );
00142
00143 sed_signal_set( signal );
00144
00145 fprintf( stdout , " %s\n" , pending_msg[signal] );
00146
00147 if ( sed_signal_is_pending( SED_SIG_EXIT ) ) eh_exit( EXIT_SUCCESS );
00148
00149 return;
00150 }
00151