@@ -200,17 +200,22 @@ impl BytesWriter {
200200 }
201201 }
202202
203- fn bytes_for_pass ( & mut self , size : usize ) -> & [ u8 ] {
203+ fn bytes_for_pass ( & mut self , size : usize ) -> Result < & [ u8 ] , std :: io :: Error > {
204204 match self {
205205 Self :: Random { rng, buffer } => {
206206 let bytes = & mut buffer[ ..size] ;
207- rng. fill ( bytes) ;
208- bytes
207+ match rng. try_fill ( bytes) {
208+ Ok ( ( ) ) => Ok ( bytes) ,
209+ Err ( err) => Err ( std:: io:: Error :: new (
210+ std:: io:: ErrorKind :: Other ,
211+ err. to_string ( ) ,
212+ ) ) ,
213+ }
209214 }
210215 Self :: Pattern { offset, buffer } => {
211216 let bytes = & buffer[ * offset..size + * offset] ;
212217 * offset = ( * offset + size) % PATTERN_LENGTH ;
213- bytes
218+ Ok ( bytes)
214219 }
215220 }
216221 }
@@ -237,8 +242,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
237242 None => unreachable ! ( ) ,
238243 } ;
239244
240- // TODO: implement --random-source
241-
242245 let remove_method = if matches. get_flag ( options:: WIPESYNC ) {
243246 RemoveMethod :: WipeSync
244247 } else if matches. contains_id ( options:: REMOVE ) {
@@ -504,6 +507,29 @@ fn wipe_file(
504507 None => metadata. len ( ) ,
505508 } ;
506509
510+ // Random source errors
511+ if let Some ( random_source_str) = random_source {
512+ let random_source_path = Path :: new ( random_source_str. as_str ( ) ) ;
513+ if !random_source_path. exists ( ) {
514+ return Err ( USimpleError :: new (
515+ 1 ,
516+ format ! (
517+ "{}: No such file or directory" ,
518+ random_source_path. maybe_quote( )
519+ ) ,
520+ ) ) ;
521+ }
522+ if !random_source_path. is_file ( ) {
523+ return Err ( USimpleError :: new (
524+ 1 ,
525+ format ! (
526+ "{}: read error: Is a directory" ,
527+ random_source_path. maybe_quote( )
528+ ) ,
529+ ) ) ;
530+ }
531+ }
532+
507533 for ( i, pass_type) in pass_sequence. into_iter ( ) . enumerate ( ) {
508534 if verbose {
509535 let pass_name = pass_name ( & pass_type) ;
@@ -517,7 +543,7 @@ fn wipe_file(
517543 }
518544 // size is an optional argument for exactly how many bytes we want to shred
519545 // Ignore failed writes; just keep trying
520- show_if_err ! ( do_pass( & mut file, & pass_type, exact, size)
546+ show_if_err ! ( do_pass( & mut file, & pass_type, exact, size, random_source )
521547 . map_err_context( || format!( "{}: File write pass failed" , path. maybe_quote( ) ) ) ) ;
522548 }
523549
@@ -534,6 +560,7 @@ fn do_pass(
534560 pass_type : & PassType ,
535561 exact : bool ,
536562 file_size : u64 ,
563+ random_source : & Option < String > ,
537564) -> Result < ( ) , io:: Error > {
538565 // We might be at the end of the file due to a previous iteration, so rewind.
539566 file. rewind ( ) ?;
@@ -542,7 +569,15 @@ fn do_pass(
542569
543570 // We start by writing BLOCK_SIZE times as many time as possible.
544571 for _ in 0 ..( file_size / BLOCK_SIZE as u64 ) {
545- let block = writer. bytes_for_pass ( BLOCK_SIZE ) ;
572+ let data = writer. bytes_for_pass ( BLOCK_SIZE ) ;
573+ let Ok ( block) = data else {
574+ let random_source_path = random_source
575+ . clone ( )
576+ . expect ( "random_source should be Some is None" ) ;
577+ let path = Path :: new ( & random_source_path) ;
578+ show_error ! ( "{}: end of file" , path. maybe_quote( ) ) ;
579+ std:: process:: exit ( 1 ) ;
580+ } ;
546581 file. write_all ( block) ?;
547582 }
548583
@@ -551,7 +586,15 @@ fn do_pass(
551586 let bytes_left = ( file_size % BLOCK_SIZE as u64 ) as usize ;
552587 if bytes_left > 0 {
553588 let size = if exact { bytes_left } else { BLOCK_SIZE } ;
554- let block = writer. bytes_for_pass ( size) ;
589+ let data = writer. bytes_for_pass ( size) ;
590+ let Ok ( block) = data else {
591+ let random_source_path = random_source
592+ . clone ( )
593+ . expect ( "random_source should be Some is None" ) ;
594+ let path = Path :: new ( & random_source_path) ;
595+ show_error ! ( "{}: end of file" , path. maybe_quote( ) ) ;
596+ std:: process:: exit ( 1 ) ;
597+ } ;
555598 file. write_all ( block) ?;
556599 }
557600
0 commit comments