@@ -80,9 +80,9 @@ struct Settings {
8080/// A timer which triggers on a given interval
8181///
8282/// After being constructed with [`Alarm::with_interval`], [`Alarm::get_trigger`]
83- /// will return [`TRIGGER_TIMER `] once per the given [`Duration`].
83+ /// will return [`ALARM_TRIGGER_TIMER `] once per the given [`Duration`].
8484/// Alarm can be manually triggered with closure returned by [`Alarm::manual_trigger_fn`].
85- /// [`Alarm::get_trigger`] will return [`TRIGGER_SIGNAL `] in this case.
85+ /// [`Alarm::get_trigger`] will return [`ALARM_TRIGGER_SIGNAL `] in this case.
8686///
8787/// Can be cloned, but the trigger status is shared across all instances so only
8888/// the first caller each interval will yield true.
@@ -93,9 +93,9 @@ pub struct Alarm {
9393 trigger : Arc < AtomicU8 > ,
9494}
9595
96- const TRIGGER_NONE : u8 = 0 ;
97- const TRIGGER_TIMER : u8 = 1 ;
98- const TRIGGER_SIGNAL : u8 = 2 ;
96+ pub const ALARM_TRIGGER_NONE : u8 = 0 ;
97+ pub const ALARM_TRIGGER_TIMER : u8 = 1 ;
98+ pub const ALARM_TRIGGER_SIGNAL : u8 = 2 ;
9999
100100impl Alarm {
101101 pub fn with_interval ( interval : Duration ) -> Self {
@@ -105,7 +105,7 @@ impl Alarm {
105105 thread:: spawn ( move || {
106106 while let Some ( trigger) = weak_trigger. upgrade ( ) {
107107 thread:: sleep ( interval) ;
108- trigger. store ( TRIGGER_TIMER , Relaxed ) ;
108+ trigger. store ( ALARM_TRIGGER_TIMER , Relaxed ) ;
109109 }
110110 } ) ;
111111
@@ -116,13 +116,13 @@ impl Alarm {
116116 let weak_trigger = Arc :: downgrade ( & self . trigger ) ;
117117 Box :: new ( move || {
118118 if let Some ( trigger) = weak_trigger. upgrade ( ) {
119- trigger. store ( TRIGGER_SIGNAL , Relaxed ) ;
119+ trigger. store ( ALARM_TRIGGER_SIGNAL , Relaxed ) ;
120120 }
121121 } )
122122 }
123123
124124 pub fn get_trigger ( & self ) -> u8 {
125- self . trigger . swap ( TRIGGER_NONE , Relaxed )
125+ self . trigger . swap ( ALARM_TRIGGER_NONE , Relaxed )
126126 }
127127
128128 pub fn get_interval ( & self ) -> Duration {
@@ -775,6 +775,30 @@ impl<'a> Output<'a> {
775775 }
776776 }
777777
778+ /// writes a block of data. optionally retries when first try didn't complete
779+ ///
780+ /// this is needed by gnu-test: tests/dd/stats.s
781+ /// the write can be interrupted by a system signal.
782+ /// e.g. SIGUSR1 which is send to report status
783+ /// without retry, the data might not be fully written to destination.
784+ fn write_block ( & mut self , chunk : & [ u8 ] ) -> io:: Result < usize > {
785+ let full_len = chunk. len ( ) ;
786+ let mut base_idx = 0 ;
787+ loop {
788+ match self . dst . write ( & chunk[ base_idx..] ) {
789+ Ok ( wlen) => {
790+ base_idx += wlen;
791+ // take iflags.fullblock as oflags shall not have this option
792+ if ( base_idx >= full_len) || !self . settings . iflags . fullblock {
793+ return Ok ( base_idx) ;
794+ }
795+ }
796+ Err ( e) if e. kind ( ) == io:: ErrorKind :: Interrupted => continue ,
797+ Err ( e) => return Err ( e) ,
798+ }
799+ }
800+ }
801+
778802 /// Write the given bytes one block at a time.
779803 ///
780804 /// This may write partial blocks (for example, if the underlying
@@ -788,7 +812,7 @@ impl<'a> Output<'a> {
788812 let mut bytes_total = 0 ;
789813
790814 for chunk in buf. chunks ( self . settings . obs ) {
791- let wlen = self . dst . write ( chunk) ?;
815+ let wlen = self . write_block ( chunk) ?;
792816 if wlen < self . settings . obs {
793817 writes_partial += 1 ;
794818 } else {
@@ -1062,10 +1086,10 @@ fn dd_copy(mut i: Input, o: Output) -> std::io::Result<()> {
10621086 rstat += rstat_update;
10631087 wstat += wstat_update;
10641088 match alarm. get_trigger ( ) {
1065- TRIGGER_NONE => { }
1066- t @ TRIGGER_TIMER | t @ TRIGGER_SIGNAL => {
1089+ ALARM_TRIGGER_NONE => { }
1090+ t @ ALARM_TRIGGER_TIMER | t @ ALARM_TRIGGER_SIGNAL => {
10671091 let tp = match t {
1068- TRIGGER_TIMER => ProgUpdateType :: Periodic ,
1092+ ALARM_TRIGGER_TIMER => ProgUpdateType :: Periodic ,
10691093 _ => ProgUpdateType :: Signal ,
10701094 } ;
10711095 let prog_update = ProgUpdate :: new ( rstat, wstat, start. elapsed ( ) , tp) ;
0 commit comments