diff --git a/src/context.h b/src/context.h index a942c66..a6963be 100644 --- a/src/context.h +++ b/src/context.h @@ -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 */ diff --git a/src/gui.c b/src/gui.c index 147113b..78ff7fe 100644 --- a/src/gui.c +++ b/src/gui.c @@ -1829,7 +1829,8 @@ void *nwipe_gui_status( void *ptr ) } /* 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 +2051,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; diff --git a/src/method.c b/src/method.c index cdc1128..1ee3774 100644 --- a/src/method.c +++ b/src/method.c @@ -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 */ diff --git a/src/nwipe.c b/src/nwipe.c index 6141c3d..f766b26 100644 --- a/src/nwipe.c +++ b/src/nwipe.c @@ -254,6 +254,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 +420,44 @@ 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. */ + i = 0; + while( i < nwipe_selected ) + { + 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 */ + } + + /* Now cancel the wipe threads */ 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 ); + + /* 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 ); @@ -450,7 +483,7 @@ int main( int argc, char** argv ) nwipe_gui_free(); } - + nwipe_log( NWIPE_LOG_NOTICE, "Nwipe exited." ); for( i = 0 ; i < nwipe_selected ; i++ ) @@ -495,7 +528,8 @@ void *signal_hand(void *ptr) sigaddset(&sigset, SIGINT); sigaddset(&sigset, SIGUSR1); - int i; + 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; @@ -571,12 +605,17 @@ void *signal_hand(void *ptr) 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." ); + } } } @@ -586,6 +625,13 @@ void *signal_hand(void *ptr) 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; } } diff --git a/src/pass.c b/src/pass.c index caeca34..7526fd2 100644 --- a/src/pass.c +++ b/src/pass.c @@ -703,7 +703,6 @@ int nwipe_static_pass( NWIPE_METHOD_SIGNATURE, nwipe_pattern_t* pattern ) return -1; } - while( z > 0 ) { if( c->device_stat.st_blksize <= z )