Fix segfault on Control-C, after a successful wipe

Symptoms: If you control-C to exit nwipe at the end of a successful
wipe you would get a segmentation fault. If nwipe log data was being
sent to stdout rather than to a log file, then you would not see the
log in the terminal windows after nwipe had exited. This patch fixes
those problems by creating a tri-state wipe flag for each wipe
thread. The main thread after having launched the wipe threads
will wait for ALL wipe flags to report that the wipe routine has
completed and the thread has exited. Only at that time does the
main() routine then proceed with joining the threads and waiting
for the join to confirm the thread has indeed exited. This join
is important as the thread will not actually exit until the OS
has flushed the disk buffers. Currently nwipe does not use O_SYNC
where data is sent straight to disk. Therefore it's important
to wait for data to be flushed before exiting nwipe. Part of this
patch is introducing a "please wait .. disks are being flushed"
prior to exiting nwipe otherwise it might look like nwipe had
hung. A disk flush in terms of how long it takes, can be from
instantly to 30 seconds or more, depending on how much system
memory you have, when the last sync occurred and if you have
changed the sync option from it's default. Something else to
note is that when all wipes have finished nwipe displays "Enter
To Exit" on the status line at the bottom of the screen. I
believe typing 'enter' rather than control-c did not produce a
segmentation fault. Irrespective, both methods of exiting nwipe
have been tested and confirmed to now work correctly. Tested
overnight with two drives using multiple wipe methods,
verification and blanking.
This commit is contained in:
PartialVolume
2019-11-11 12:34:28 +00:00
parent dd3828008d
commit 4241485e6a
6 changed files with 268 additions and 120 deletions

View File

@@ -114,6 +114,7 @@ typedef struct nwipe_context_t_
pthread_t thread; /* The ID of the thread. */
u64 throughput; /* Average throughput in bytes per second. */
u64 verify_errors; /* The number of verification errors across all passes. */
int wipe_status; /* Wipe finished = 0, wipe in progress = 1, wipe yet to start = -1*/
char serial_no[21]; /* Serial number(processed), 20 characters, plus null termination */
struct hd_driveid identity; /* Identity contains the raw serial number of the drive */
/* (where applicable), however, for use within nwipe use the */

185
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 = 6;
@@ -1493,8 +1580,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 )
{
@@ -1519,7 +1614,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 )
@@ -1619,6 +1714,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;
@@ -1705,7 +1802,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 );
@@ -1819,17 +1916,18 @@ 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 );
}
/* Check whether the child process is still running the wipe. */
if( c[i]->thread > 0 )
//if( c[i]->thread > 0 )
if( c[i]->wipe_status == 1 )
{
/* Print percentage and pass information. */
mvwprintw( main_window, yy++, 4, "[%05.2f%%, round %i of %i, pass %i of %i] ", \
@@ -2050,7 +2148,8 @@ int compute_stats(void *ptr)
for( i = 0 ; i < count ; i++ )
{
/* Check whether the child process is still running the wipe. */
if( c[i]->thread > 0 )
// if( c[i]->thread > 0 )
if( c[i]->wipe_status == 1 )
{
/* Increment the child counter. */
nwipe_active += 1;

View File

@@ -97,6 +97,9 @@ void *nwipe_zero( void *ptr )
nwipe_context_t *c;
c = (nwipe_context_t *) ptr;
/* set wipe in progress flag for GUI */
c->wipe_status = 1;
/* Do nothing because nwipe_runmethod appends a zero-fill. */
nwipe_pattern_t patterns [] =
@@ -107,8 +110,8 @@ void *nwipe_zero( void *ptr )
/* Run the method. */
c->result = nwipe_runmethod( c, patterns );
/* Finished. Set the thread ID to 0 so that the GUI knows */
c->thread = 0;
/* Finished. Set the wipe_status flag so that the GUI knows */
c->wipe_status = 0;
return NULL;
} /* nwipe_zero */
@@ -124,6 +127,9 @@ void *nwipe_dod522022m( void *ptr )
nwipe_context_t *c;
c = (nwipe_context_t *) ptr;
/* set wipe in progress flag for GUI */
c->wipe_status = 1;
/* A result holder. */
int r;
@@ -170,8 +176,8 @@ void *nwipe_dod522022m( void *ptr )
/* Run the DoD 5220.22-M method. */
c->result = nwipe_runmethod( c, patterns );
/* Finished. Set the thread ID to 0 so that the GUI knows */
c->thread = 0;
/* Finished. Set the wipe_status flag so that the GUI knows */
c->wipe_status = 0;
return NULL;
} /* nwipe_dod522022m */
@@ -188,6 +194,9 @@ void *nwipe_dodshort( void *ptr )
nwipe_context_t *c;
c = (nwipe_context_t *) ptr;
/* set wipe in progress flag for GUI */
c->wipe_status = 1;
/* A result holder. */
int r;
@@ -227,8 +236,8 @@ void *nwipe_dodshort( void *ptr )
/* Run the DoD 5220.022-M short method. */
c->result = nwipe_runmethod( c, patterns );
/* Finished. Set the thread ID to 0 so that the GUI knows */
c->thread = 0;
/* Finished. Set the wipe_status flag so that the GUI knows */
c->wipe_status = 0;
return NULL;
} /* nwipe_dodshort */
@@ -244,6 +253,9 @@ void *nwipe_gutmann( void *ptr )
nwipe_context_t *c;
c = (nwipe_context_t *) ptr;
/* set wipe in progress flag for GUI */
c->wipe_status = 1;
/* A result buffer. */
int r;
@@ -353,9 +365,8 @@ void *nwipe_gutmann( void *ptr )
/* Run the Gutmann method. */
c->result = nwipe_runmethod( c, patterns );
/* Finished. Set the thread ID to 0 so that the GUI knows */
c->thread = 0;
/* Finished. Set the wipe_status flag so that the GUI knows */
c->wipe_status = 0;
return NULL;
} /* nwipe_gutmann */
@@ -375,6 +386,9 @@ void *nwipe_ops2( void *ptr )
nwipe_context_t *c;
c = (nwipe_context_t *) ptr;
/* set wipe in progress flag for GUI */
c->wipe_status = 1;
/* A generic array index. */
int i;
@@ -522,9 +536,8 @@ void *nwipe_ops2( void *ptr )
/* We're done. */
c->result = nwipe_runmethod( c, patterns );
/* Finished. Set the thread ID to 0 so that the GUI knows */
c->thread = 0;
/* Finished. Set the wipe_status flag so that the GUI knows */
c->wipe_status = 0;
return NULL;
} /* nwipe_ops2 */
@@ -540,6 +553,9 @@ void *nwipe_random( void *ptr )
nwipe_context_t *c;
c = (nwipe_context_t *) ptr;
/* set wipe in progress flag for GUI */
c->wipe_status = 1;
/* Define the random method. */
nwipe_pattern_t patterns [] =
@@ -551,9 +567,8 @@ void *nwipe_random( void *ptr )
/* Run the method. */
c->result = nwipe_runmethod( c, patterns );
/* Finished. Set the thread ID to 0 so that the GUI knows */
c->thread = 0;
/* Finished. Set the wipe_status flag so that the GUI knows */
c->wipe_status = 0;
return NULL;
} /* nwipe_random */

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 */
@@ -254,6 +259,9 @@ int main( int argc, char** argv )
/* A result buffer for the BLKGETSIZE64 ioctl. */
u64 size64;
/* Initialise the wipe_status flag, -1 = wipe not yet started */
c2[i]->wipe_status = -1;
/* Open the file for reads and writes. */
c2[i]->device_fd = open( c2[i]->device_name, O_RDWR );
@@ -417,14 +425,88 @@ 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, but don't wait if we receive the terminate signal */
i = 0;
while( i < nwipe_selected && terminate_signal == 0 )
{
if( i == nwipe_selected )
{
break;
}
/* Wait for all the wiping threads to finish. */
if ( c2[i]->wipe_status != 0 )
{
i = 0;
}
else
{
i++;
continue;
}
sleep( 2 ); /* DO NOT REMOVE ! Stops the routine hogging CPU cycles */
}
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++ )
{
if ( c2[i]->thread )
{
pthread_join( c2[i]->thread, NULL);
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 )
{
nwipe_log( NWIPE_LOG_WARNING, "main()>pthread_join():Error when waiting for wipe thread to cancel." );
}
c2[i]->thread = 0; /* Zero the thread so we know it's been cancelled */
/* Close the device file descriptor. */
close( c2[i]->device_fd );
@@ -432,27 +514,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++ )
{
@@ -468,6 +529,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++)
@@ -495,7 +558,7 @@ void *signal_hand(void *ptr)
sigaddset(&sigset, SIGINT);
sigaddset(&sigset, SIGUSR1);
int i;
int i;
/* Set up the structs we will use for the data required. */
nwipe_thread_data_ptr_t *nwipe_thread_data_ptr;
@@ -567,43 +630,13 @@ 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++ )
{
/* Return control to the main thread, returning the signal received */
return((void *)0);
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 );
}
}
// Kill the GUI thread
if( !nwipe_options.nogui )
{
if ( *nwipe_misc_thread_data->gui_thread )
{
pthread_cancel( *nwipe_misc_thread_data->gui_thread );
*nwipe_misc_thread_data->gui_thread = 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 */
@@ -611,7 +644,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_

View File

@@ -702,8 +702,7 @@ int nwipe_static_pass( NWIPE_METHOD_SIGNATURE, nwipe_pattern_t* pattern )
nwipe_log( NWIPE_LOG_SANITY, "__FUNCTION__: lseek() returned a bogus offset on '%s'.", c->device_name );
return -1;
}
//z = 512000000; //FIXME NOTICE This is temporary for debugging - REMOVE
while( z > 0 )
{
if( c->device_stat.st_blksize <= z )