Merge pull request #132 from PartialVolume/fix_segfault_on_CNTRL-C_at_end_wipe_take3

Fix segfault on control c at end wipe
This commit is contained in:
PartialVolume
2019-11-14 01:27:33 +00:00
committed by GitHub
3 changed files with 202 additions and 114 deletions

179
src/gui.c
View File

@@ -103,6 +103,8 @@
#define NWIPE_GUI_MAIN_Y 8
#define NWIPE_GUI_MAIN_X 0
#define SKIP_DEV_PREFIX 5
/* Window pointers. */
WINDOW* footer_window;
@@ -339,17 +341,50 @@ void nwipe_gui_free( void )
*/
/* Free ncurses resources. */
del_panel( footer_panel );
del_panel( header_panel );
del_panel( main_panel );
del_panel( options_panel );
del_panel( stats_panel );
delwin( footer_window );
delwin( header_window );
delwin( main_window );
delwin( options_window );
delwin( stats_window );
endwin();
if( del_panel( footer_panel ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting footer panel failed!." );
}
if( del_panel( header_panel ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting header panel failed!." );
}
if( del_panel( main_panel ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting main panel failed!." );
}
if( del_panel( options_panel ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting options panel failed!." );
}
if( del_panel( stats_panel ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting stats panel failed!." );
}
if( delwin( footer_window ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting footer window failed!." );
}
if( delwin( header_window ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting header window failed!." );
}
if( delwin( main_window ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting main window failed!." );
}
if( delwin( options_window ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting options window failed!." );
}
if( delwin( stats_window ) != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Deleting stats window failed!." );
}
if( endwin() != OK )
{
nwipe_log( NWIPE_LOG_ERROR, "Curses endwin() failed !" );
}
} /* nwipe_gui_free */
@@ -368,6 +403,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
*
*/
extern int terminate_signal;
/* Widget labels. */
const char* select_title = " Disks and Partitions ";
@@ -449,8 +486,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
{
case NWIPE_SELECT_TRUE:
wprintw( main_window, " [wipe] %i. %s - %s %s (%s)", (i + offset + 1),
c[i+offset]->device_name,
wprintw( main_window, " [wipe] %i. %s - %s, S/N:%s, (%s)", (i + offset + 1),
c[i+offset]->device_name+SKIP_DEV_PREFIX,
c[i+offset]->label,
c[i+offset]->serial_no,
c[i+offset]->device_size_text );
@@ -458,8 +495,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
case NWIPE_SELECT_FALSE:
/* Print an element that is not selected. */
wprintw( main_window, " [ ] %i. %s - %s %s (%s)", (i + offset +1),
c[i+offset]->device_name,
wprintw( main_window, " [ ] %i. %s - %s, S/N:%s, (%s)", (i + offset +1),
c[i+offset]->device_name+SKIP_DEV_PREFIX,
c[i+offset]->label,
c[i+offset]->serial_no,
c[i+offset]->device_size_text );
@@ -468,8 +505,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
case NWIPE_SELECT_TRUE_PARENT:
/* This element will be wiped when its parent is wiped. */
wprintw( main_window, " [****] %i. %s - %s %s (%s)", (i + offset +1),
c[i+offset]->device_name,
wprintw( main_window, " [****] %i. %s - %s, S/N:%s, (%s)", (i + offset +1),
c[i+offset]->device_name+SKIP_DEV_PREFIX,
c[i+offset]->label,
c[i+offset]->serial_no,
c[i+offset]->device_size_text );
@@ -478,8 +515,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
case NWIPE_SELECT_FALSE_CHILD:
/* We can't wipe this element because it has a child that is being wiped. */
wprintw( main_window, " [----] %i. %s - %s %s (%s)", (i + offset +1),
c[i+offset]->device_name,
wprintw( main_window, " [----] %i. %s - %s, S/N:%s, (%s)", (i + offset +1),
c[i+offset]->device_name+SKIP_DEV_PREFIX,
c[i+offset]->label,
c[i+offset]->serial_no,
c[i+offset]->device_size_text );
@@ -521,9 +558,17 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
/* Refresh the window. */
wrefresh( main_window );
/* Get user input. */
keystroke = getch();
/* Wait 250ms for input from getch, if nothing getch will then continue,
* This is necessary so that the while loop can be exited by the
* terminate_signal e.g.. the user pressing control-c to exit.
* Do not change this value, a higher value means the keys become
* sluggish, any slower and more time is spent unnecessarily looping
* which wastes CPU cycles.
*/
timeout(250); /* block getch() for 250ms */
keystroke = getch(); /* Get user input. */
timeout(-1); /* Switch back to blocking mode */
switch( keystroke )
{
@@ -750,10 +795,11 @@ void nwipe_gui_select( int count, nwipe_context_t** c )
/* Run the noblank dialog. */
nwipe_gui_noblank();
break;
} /* keystroke switch */
} while( keystroke != 'S' && keystroke != ERR );
} while( keystroke != 'S' && terminate_signal !=1);
/* Clear the main window. */
werase( main_window );
@@ -857,6 +903,8 @@ void nwipe_gui_rounds( void )
/* Input buffer. */
int keystroke;
extern int terminate_signal;
/* Erase the footer window. */
werase( footer_window );
@@ -904,8 +952,16 @@ void nwipe_gui_rounds( void )
/* Refresh the window. */
wrefresh( main_window );
/* Get a keystroke. */
keystroke = getch();
/* Wait 250ms for input from getch, if nothing getch will then continue,
* This is necessary so that the while loop can be exited by the
* terminate_signal e.g.. the user pressing control-c to exit.
* Do not change this value, a higher value means the keys become
* sluggish, any slower and more time is spent unnecessarily looping
* which wastes CPU cycles.
*/
timeout(250); /* block getch() for 250ms */
keystroke = getch(); /* Get a keystroke. */
timeout(-1); /* Switch back to blocking mode */
switch( keystroke )
{
@@ -945,7 +1001,7 @@ void nwipe_gui_rounds( void )
/* Hide the cursor. */
curs_set( 0 );
} while( keystroke != 10 && keystroke != ERR );
} while( keystroke != 10 && terminate_signal !=1 );
if( focus > 0 )
{
@@ -969,6 +1025,7 @@ void nwipe_gui_prng( void )
extern nwipe_prng_t nwipe_twister;
extern nwipe_prng_t nwipe_isaac;
extern int terminate_signal;
/* The number of implemented PRNGs. */
const int count = 2;
@@ -1053,8 +1110,16 @@ void nwipe_gui_prng( void )
/* Refresh the window. */
wrefresh( main_window );
/* Get a keystroke. */
keystroke = getch();
/* Wait 250ms for input from getch, if nothing getch will then continue,
* This is necessary so that the while loop can be exited by the
* terminate_signal e.g.. the user pressing control-c to exit.
* Do not change this value, a higher value means the keys become
* sluggish, any slower and more time is spent unnecessarily looping
* which wastes CPU cycles.
*/
timeout(250); /* block getch() for 250ms */
keystroke = getch(); /* Get a keystroke. */
timeout(-1); /* Switch back to blocking mode */
switch( keystroke )
{
@@ -1088,7 +1153,7 @@ void nwipe_gui_prng( void )
} /* switch */
}
while( keystroke != ERR );
while( terminate_signal != 1 );
} /* nwipe_gui_prng */
@@ -1104,6 +1169,8 @@ void nwipe_gui_verify( void )
*
*/
extern int terminate_signal;
/* The number of definitions in the nwipe_verify_t enumeration. */
const int count = 3;
@@ -1188,8 +1255,16 @@ void nwipe_gui_verify( void )
/* Refresh the window. */
wrefresh( main_window );
/* Get a keystroke. */
keystroke = getch();
/* Wait 250ms for input from getch, if nothing getch will then continue,
* This is necessary so that the while loop can be exited by the
* terminate_signal e.g.. the user pressing control-c to exit.
* Do not change this value, a higher value means the keys become
* sluggish, any slower and more time is spent unnecessarily looping
* which wastes CPU cycles.
*/
timeout(250); /* block getch() for 250ms */
keystroke = getch(); /* Get a keystroke. */
timeout(-1); /* Switch back to blocking mode */
switch( keystroke )
{
@@ -1223,7 +1298,7 @@ void nwipe_gui_verify( void )
} /* switch */
}
while( keystroke != ERR );
while( terminate_signal != 1 );
} /* nwipe_gui_verify */
@@ -1238,6 +1313,8 @@ void nwipe_gui_noblank( void )
*
*/
extern int terminate_signal;
/* The number of options available. */
const int count = 2;
@@ -1309,8 +1386,16 @@ void nwipe_gui_noblank( void )
/* Refresh the window. */
wrefresh( main_window );
/* Get a keystroke. */
keystroke = getch();
/* Wait 250ms for input from getch, if nothing getch will then continue,
* This is necessary so that the while loop can be exited by the
* terminate_signal e.g.. the user pressing control-c to exit.
* Do not change this value, a higher value means the keys become
* sluggish, any slower and more time is spent unnecessarily looping
* which wastes CPU cycles.
*/
timeout(250); /* block getch() for 250ms */
keystroke = getch(); /* Get a keystroke. */
timeout(-1); /* Switch back to blocking mode */
switch( keystroke )
{
@@ -1345,7 +1430,7 @@ void nwipe_gui_noblank( void )
}
while( keystroke != ERR );
while( terminate_signal != 1 );
} /* nwipe_gui_noblank */
@@ -1359,6 +1444,8 @@ void nwipe_gui_method( void )
*
*/
extern int terminate_signal;
/* The number of implemented methods. */
const int count = 7;
@@ -1505,8 +1592,16 @@ void nwipe_gui_method( void )
/* Refresh the window. */
wrefresh( main_window );
/* Get a keystroke. */
keystroke = getch();
/* Wait 250ms for input from getch, if nothing getch will then continue,
* This is necessary so that the while loop can be exited by the
* terminate_signal e.g.. the user pressing control-c to exit.
* Do not change this value, a higher value means the keys become
* sluggish, any slower and more time is spent unnecessarily looping
* which wastes CPU cycles.
*/
timeout(250); /* block getch() for 250ms */
keystroke = getch(); /* Get a keystroke. */
timeout(-1); /* Switch back to blocking mode */
switch( keystroke )
{
@@ -1531,7 +1626,7 @@ void nwipe_gui_method( void )
} /* switch */
} while( keystroke != KEY_ENTER && keystroke != ' ' && keystroke != 10 && keystroke != ERR );
} while( keystroke != KEY_ENTER && keystroke != ' ' && keystroke != 10 && terminate_signal != 1 );
switch( focus )
@@ -1635,6 +1730,8 @@ void *nwipe_gui_status( void *ptr )
*
*/
extern int terminate_signal;
nwipe_thread_data_ptr_t *nwipe_thread_data_ptr;
nwipe_thread_data_ptr = (nwipe_thread_data_ptr_t *) ptr;
@@ -1721,7 +1818,7 @@ void *nwipe_gui_status( void *ptr )
nwipe_gui_title( footer_window, nwipe_buttons3 );
wrefresh( footer_window );
while ( nwipe_active ) {
while ( nwipe_active && terminate_signal != 1) {
/* Get the current time. */
nwipe_time_now = time( NULL );
@@ -1835,12 +1932,12 @@ void *nwipe_gui_status( void *ptr )
/* Print the context label. */
if ( strlen((const char*)c[i]->serial_no) )
{
mvwprintw( main_window, yy++, 2, "%s - %s (%s)", c[i]->device_name,
mvwprintw( main_window, yy++, 2, "%s - %s (S/N:%s)", c[i]->device_name+SKIP_DEV_PREFIX,
c[i]->label,
c[i]->serial_no);
}
else {
mvwprintw( main_window, yy++, 2, "%s - %s", c[i]->device_name,
mvwprintw( main_window, yy++, 2, "%s - %s", c[i]->device_name+SKIP_DEV_PREFIX,
c[i]->label );
}

View File

@@ -46,6 +46,8 @@
#include <parted/parted.h>
#include <parted/debug.h>
int terminate_signal;
int main( int argc, char** argv )
{
int nwipe_optind; /* The result of nwipe_options(). */
@@ -64,6 +66,9 @@ int main( int argc, char** argv )
/* The generic result buffer. */
int r;
/* Initialise the termintaion signal, 1=terminate nwipe */
terminate_signal = 0;
/* Two arrays are used, containing pointers to the the typedef for each disk */
/* The first array (c1) points to all devices, the second points to only */
@@ -420,9 +425,10 @@ int main( int argc, char** argv )
errno = pthread_create( &nwipe_gui_thread, NULL, nwipe_gui_status, &nwipe_gui_data);
}
/* Wait for all the wiping threads to finish. */
/* Wait for all the wiping threads to finish, but don't wait if we receive the terminate signal */
i = 0;
while( i < nwipe_selected )
while( i < nwipe_selected && terminate_signal == 0 )
{
if( i == nwipe_selected )
{
@@ -440,8 +446,24 @@ int main( int argc, char** argv )
}
sleep( 2 ); /* DO NOT REMOVE ! Stops the routine hogging CPU cycles */
}
/* Now cancel the wipe threads */
if ( terminate_signal == 1 )
{
nwipe_log( NWIPE_LOG_INFO, "Program interrupted" );
}
else
{
if( !nwipe_options.nowait )
{
/* Wait for the user to press enter to exit */
nocbreak();
getch();
}
}
nwipe_log( NWIPE_LOG_INFO, "Exit in progress" );
/* Send a REQUEST for the wipe threads to be cancelled */
for( i = 0 ; i < nwipe_selected ; i++ )
{
@@ -450,7 +472,36 @@ int main( int argc, char** argv )
nwipe_log( NWIPE_LOG_INFO, "main():Cancelling wipe thread for %s", c2[i]->device_name );
nwipe_log( NWIPE_LOG_INFO, "main():Please wait.. disk cache is being flushed" );
pthread_cancel( c2[i]->thread );
}
}
/* Kill the GUI thread */
if ( nwipe_gui_thread )
{
nwipe_log( NWIPE_LOG_INFO, "Cancelling the GUI thread." );
/* We don't want to use pthread_cancel as our GUI thread is aware of the control-c
* signal and will exit itself we just join the GUI thread and wait for confirmation
*/
r = pthread_join( nwipe_gui_thread, NULL );
if( r != 0 )
{
nwipe_log( NWIPE_LOG_WARNING, "main()>pthread_join():Error when waiting for GUI thread to cancel." );
}
}
/* Release the gui. */
if( !nwipe_options.nogui )
{
nwipe_gui_free();
}
/* Now join the wipe threads and wait until they have terminated */
for( i = 0 ; i < nwipe_selected ; i++ )
{
if ( c2[i]->thread )
{
/* Joins the thread and waits for completion before continuing */
r = pthread_join( c2[i]->thread, NULL);
if( r != 0 )
@@ -465,27 +516,6 @@ int main( int argc, char** argv )
}
/* Kill the GUI thread */
/* It may not be running if the program was interrupted */
if ( nwipe_gui_thread )
{
pthread_join( nwipe_gui_thread, NULL );
nocbreak();
// timeout(-1);
/* Wait for enter key to be pressed unless --nowait
was specified. */
if( !nwipe_options.nowait )
getch();
/* Release the gui. */
nwipe_gui_free();
}
nwipe_log( NWIPE_LOG_NOTICE, "Nwipe exited." );
for( i = 0 ; i < nwipe_selected ; i++ )
{
@@ -501,6 +531,8 @@ int main( int argc, char** argv )
if( c2[i]->result > 0 ){ return 1; }
}
nwipe_log( NWIPE_LOG_NOTICE, "Nwipe Successfully Exited." );
/* Flush any remaining logs. */
for (i=0; i < log_current_element; i++)
@@ -529,7 +561,6 @@ void *signal_hand(void *ptr)
sigaddset(&sigset, SIGUSR1);
int i;
int r; /* Generic result buffer */
/* Set up the structs we will use for the data required. */
nwipe_thread_data_ptr_t *nwipe_thread_data_ptr;
@@ -601,55 +632,14 @@ void *signal_hand(void *ptr)
case SIGQUIT :
case SIGTERM :
{
nwipe_log( NWIPE_LOG_INFO, "nwipe_selected = %lu", nwipe_misc_thread_data->nwipe_selected );
/* Set termination flag for main() which will do housekeeping prior to exit */
terminate_signal = 1;
for( i = 0; i < nwipe_misc_thread_data->nwipe_selected; i++ )
{
if ( c[i]->thread )
{
nwipe_log( NWIPE_LOG_INFO, "Cancelling thread for %s", c[i]->device_name );
nwipe_log( NWIPE_LOG_INFO, "Please be patient.. disk cache is being flushed" );
pthread_cancel( c[i]->thread );
r = pthread_join( c[i]->thread, NULL);
if( r != 0 )
{
nwipe_log( NWIPE_LOG_WARNING, "signal_hand()>pthread_join():Error when waiting for wipe thread to cancel." );
}
}
}
// Kill the GUI thread
if( !nwipe_options.nogui )
{
if ( *nwipe_misc_thread_data->gui_thread )
{
pthread_cancel( *nwipe_misc_thread_data->gui_thread );
r = pthread_join( *nwipe_misc_thread_data->gui_thread, NULL);
if( r != 0 )
{
nwipe_log( NWIPE_LOG_WARNING, "signal_hand()>pthread_join():Error when waiting for GUI thread to cancel." );
}
*nwipe_misc_thread_data->gui_thread = 0;
}
}
/* Return control to the main thread, returning the signal received */
return((void *)0);
if( !nwipe_options.nogui )
nwipe_gui_free();
/* Flush any remaining logs. */
for (i=0; i < log_current_element; i++)
{
printf("%s\n", log_lines[i]);
}
printf("Program interrupted (caught signal %d)\n", sig);
cleanup();
exit(0);
break;
} /* end case */
@@ -657,7 +647,7 @@ void *signal_hand(void *ptr)
} /* end of while */
return((void *)0);
return(0);
} /* end of signal_hand */

View File

@@ -21,6 +21,7 @@
*/
#ifndef NWIPE_H_
#define NWIPE_H_