diff --git a/include/helper.h b/include/helper.h index 4c34da2f..008964ae 100644 --- a/include/helper.h +++ b/include/helper.h @@ -121,9 +121,14 @@ int execute_generator ( const char * cmd ) __attribute__( ( nonnull ) ); /** * @param pidfile The pidfile to create. * - * Calls exit (1) when failed. + * returns file descriptor (or -1 when failed) */ -void create_pid_file ( const char *pidfile ); +int create_pid_file ( const char *pidfile ); + +/** + * Remove pid file + */ +void remove_pid_file ( int fd ); /** * Do some input validation, especially the first few could break things. diff --git a/include/rofi.h b/include/rofi.h index 8bd02c7f..955ffd9d 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -303,5 +303,5 @@ struct _Switcher -void show_error_message ( const char *msg, int markup ); +int show_error_message ( const char *msg, int markup ); #endif diff --git a/source/helper.c b/source/helper.c index 229d4ac1..87e38d1d 100644 --- a/source/helper.c +++ b/source/helper.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include #include @@ -403,31 +405,32 @@ int execute_generator ( const char * cmd ) } -void create_pid_file ( const char *pidfile ) +int create_pid_file ( const char *pidfile ) { if ( pidfile == NULL ) { - return; + return -1; } - int fd = open ( pidfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR ); + int fd = g_open ( pidfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR ); if ( fd < 0 ) { fprintf ( stderr, "Failed to create pid file." ); - exit ( EXIT_FAILURE ); + return -1; } // Set it to close the File Descriptor on exit. int flags = fcntl ( fd, F_GETFD, NULL ); flags = flags | FD_CLOEXEC; if ( fcntl ( fd, F_SETFD, flags, NULL ) < 0 ) { fprintf ( stderr, "Failed to set CLOEXEC on pidfile." ); - close ( fd ); - exit ( EXIT_FAILURE ); + remove_pid_file ( fd ); + return -1; } // Try to get exclusive write lock on FD int retv = flock ( fd, LOCK_EX | LOCK_NB ); if ( retv != 0 ) { fprintf ( stderr, "Failed to set lock on pidfile: Rofi already running?\n" ); - fprintf ( stderr, "%d %s\n", retv, strerror ( errno ) ); - exit ( EXIT_FAILURE ); + fprintf ( stderr, "Got error: %d %s\n", retv, strerror ( errno ) ); + remove_pid_file ( fd ); + return -1; } if ( ftruncate ( fd, (off_t) 0 ) == 0 ) { // Write pid, not needed, but for completeness sake. @@ -438,6 +441,14 @@ void create_pid_file ( const char *pidfile ) l += write ( fd, &buffer[l], length - l ); } } + return fd; +} + +void remove_pid_file ( int fd ) +{ + if ( fd >= 0 ) { + g_close ( fd, NULL ); + } } /** diff --git a/source/rofi.c b/source/rofi.c index d61ab315..90f89a06 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -1457,25 +1457,25 @@ void error_dialog ( const char *msg, int markup ) release_keyboard ( display ); } - /** - * Start dmenu mode. + * Do needed steps to start showing the gui */ -static int run_dmenu () +static int setup () { // Create pid file - create_pid_file ( pidfile ); - - // Request truecolor visual. - create_visual_and_colormap ( display ); - textbox_setup ( &vinfo, map ); - char *input = NULL; - - // Dmenu modi has a return state. - int ret_state = dmenu_switcher_dialog ( &input ); - - g_free ( input ); - + int pfd = create_pid_file ( pidfile ); + if ( pfd >= 0 ) { + // Request truecolor visual. + create_visual_and_colormap ( display ); + textbox_setup ( &vinfo, map ); + } + return pfd; +} +/** + * Teardown the gui. + */ +static void teardown ( int pfd ) +{ // Cleanup font setup. textbox_cleanup ( ); @@ -1493,19 +1493,35 @@ static int run_dmenu () map = None; } // Cleanup pid file. - if ( pidfile ) { - unlink ( pidfile ); + remove_pid_file ( pfd ); +} + +/** + * Start dmenu mode. + */ +static int run_dmenu () +{ + char *input = NULL; + int ret_state = EXIT_FAILURE; + int pfd = setup (); + if ( pfd < 0 ) { + return ret_state; } + + // Dmenu modi has a return state. + ret_state = dmenu_switcher_dialog ( &input ); + + g_free ( input ); + teardown ( pfd ); return ret_state; } static void run_switcher ( SwitcherMode mode ) { - // Create pid file to avoid multiple instances. - create_pid_file ( pidfile ); - // Create the colormap and the main visual. - create_visual_and_colormap ( display ); - textbox_setup ( &vinfo, map ); + int pfd = setup (); + if ( pfd < 0 ) { + return; + } // Otherwise check if requested mode is enabled. char *input = NULL; for ( unsigned int i = 0; i < num_switchers; i++ ) { @@ -1542,27 +1558,19 @@ static void run_switcher ( SwitcherMode mode ) for ( unsigned int i = 0; i < num_switchers; i++ ) { switchers[i]->destroy ( switchers[i] ); } + // cleanup + teardown ( pfd ); +} - // Cleanup font setup. - textbox_cleanup ( ); - - // Release the window. - release_keyboard ( display ); - if ( main_window != None ) { - XUnmapWindow ( display, main_window ); - XDestroyWindow ( display, main_window ); - main_window = None; - XFreeGC ( display, gc ); - gc = NULL; - } - if ( map != None ) { - XFreeColormap ( display, map ); - map = None; - } - // Cleanup pid file. - if ( pidfile ) { - unlink ( pidfile ); +int show_error_message ( const char *msg, int markup ) +{ + int pfd = setup (); + if ( pfd < 0 ) { + return EXIT_FAILURE; } + error_dialog ( msg, markup ); + teardown ( pfd ); + return EXIT_SUCCESS; } /** @@ -1724,38 +1732,6 @@ static inline void load_configuration_dynamic ( Display *display ) } -void show_error_message ( const char *msg, int markup ) -{ - // Create pid file - create_pid_file ( pidfile ); - - // Request truecolor visual. - create_visual_and_colormap ( display ); - textbox_setup ( &vinfo, map ); - error_dialog ( msg, markup ); - textbox_cleanup ( ); - // - // Cleanup font setup. - textbox_cleanup ( ); - - // Release the window. - release_keyboard ( display ); - if ( main_window != None ) { - XUnmapWindow ( display, main_window ); - XDestroyWindow ( display, main_window ); - main_window = None; - XFreeGC ( display, gc ); - gc = NULL; - } - if ( map != None ) { - XFreeColormap ( display, map ); - map = None; - } - // Cleanup pid file. - if ( pidfile ) { - unlink ( pidfile ); - } -} /** * Separate thread that handles signals being send to rofi. @@ -1995,8 +1971,7 @@ int main ( int argc, char *argv[] ) if ( find_arg ( "-markup" ) >= 0 ) { markup = TRUE; } - show_error_message ( msg, markup ); - exit ( EXIT_SUCCESS ); + return show_error_message ( msg, markup ); } @@ -2128,7 +2103,7 @@ int main ( int argc, char *argv[] ) // Close pipe close ( pfds[0] ); close ( pfds[1] ); - if(!quiet) { + if ( !quiet ) { fprintf ( stdout, "Quit from daemon mode.\n" ); } } diff --git a/test/helper-test.c b/test/helper-test.c index 2a22929f..a80b4485 100644 --- a/test/helper-test.c +++ b/test/helper-test.c @@ -16,9 +16,10 @@ void error_dialog ( const char *msg, G_GNUC_UNUSED int markup ) fputs ( msg, stderr ); } -void show_error_message ( const char *msg, int markup ) +int show_error_message ( const char *msg, int markup ) { error_dialog ( msg, markup ); + return 0; } int main ( int argc, char ** argv ) diff --git a/test/textbox-test.c b/test/textbox-test.c index 9180565a..4774985d 100644 --- a/test/textbox-test.c +++ b/test/textbox-test.c @@ -29,9 +29,10 @@ void error_dialog ( const char *msg, G_GNUC_UNUSED int markup ) fputs ( msg, stderr ); } -void show_error_message ( const char *msg, int markup ) +int show_error_message ( const char *msg, int markup ) { error_dialog ( msg, markup ); + return 0; } static unsigned int color_get ( Display *display, const char *const name )