> Date: Sat, 31 Dec 2022 10:33:26 -0500
> From: Scott Cheloha <[email protected]>
> 
> Here's another one.
> 
> The progress meter in scp(1) and sftp(1) updates periodically, once
> per second.  But using alarm(3) to repeatedly rearm the signal causes
> that update period to drift forward:
> 
> $ kdump -ts -R -f scp-current.ktrace.out
>  25343 scp      1672500224.844047 PSIG  SIGALRM caught handler=0x239bf6ec750 
> mask=0<>
>  25343 scp      1.009691 PSIG  SIGALRM caught handler=0x239bf6ec750 mask=0<>
>  25343 scp      1.000314 PSIG  SIGALRM caught handler=0x239bf6ec750 mask=0<>
>  25343 scp      1.009971 PSIG  SIGALRM caught handler=0x239bf6ec750 mask=0<>
>  25343 scp      1.009872 PSIG  SIGALRM caught handler=0x239bf6ec750 mask=0<>
>  25343 scp      1.009831 PSIG  SIGALRM caught handler=0x239bf6ec750 mask=0<>
>  25343 scp      1.000315 PSIG  SIGALRM caught handler=0x239bf6ec750 mask=0<>
> 
> If we use setitimer(2), the update period does not drift:
> 
> $ kdump -ts -R -f scp-patched.ktrace.out 
>  33053 scp      1672500345.413781 PSIG  SIGALRM caught handler=0x9d45436b7f0 
> mask=0<>
>  33053 scp      1.000014 PSIG  SIGALRM caught handler=0x9d45436b7f0 mask=0<>
>  33053 scp      1.000027 PSIG  SIGALRM caught handler=0x9d45436b7f0 mask=0<>
>  33053 scp      1.000208 PSIG  SIGALRM caught handler=0x9d45436b7f0 mask=0<>
>  33053 scp      0.999742 PSIG  SIGALRM caught handler=0x9d45436b7f0 mask=0<>
>  33053 scp      1.000083 PSIG  SIGALRM caught handler=0x9d45436b7f0 mask=0<>
>  33053 scp      1.000057 PSIG  SIGALRM caught handler=0x9d45436b7f0 mask=0<>
>  33053 scp      1.000091 PSIG  SIGALRM caught handler=0x9d45436b7f0 mask=0<>
>  33053 scp      0.999604 PSIG  SIGALRM caught handler=0x9d45436b7f0 mask=0<>
>  33053 scp      1.000176 PSIG  SIGALRM caught handler=0x9d45436b7f0 mask=0<>
> 
> ok?

Bad idea.  The setitimer(2) interface is marked as "OB XSI" in POSIX,
which means that it is considerent "Obsolescent" and may be removed in
a future version of POSIX.  Since we want ssh to be as portable as
possible we shouldn't use it there.  Especially for something that
really is just a cosmetic "fix".


> Index: progressmeter.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/ssh/progressmeter.c,v
> retrieving revision 1.50
> diff -u -p -r1.50 progressmeter.c
> --- progressmeter.c   23 Jan 2020 07:10:22 -0000      1.50
> +++ progressmeter.c   31 Dec 2022 15:30:50 -0000
> @@ -25,8 +25,10 @@
>  
>  #include <sys/types.h>
>  #include <sys/ioctl.h>
> +#include <sys/time.h>
>  #include <sys/uio.h>
>  
> +#include <err.h>
>  #include <errno.h>
>  #include <signal.h>
>  #include <stdarg.h>
> @@ -232,12 +234,13 @@ static void
>  sig_alarm(int ignore)
>  {
>       alarm_fired = 1;
> -     alarm(UPDATE_INTERVAL);
>  }
>  
>  void
>  start_progress_meter(const char *f, off_t filesize, off_t *ctr)
>  {
> +     struct itimerval itv = {{ UPDATE_INTERVAL, 0 }, { UPDATE_INTERVAL, 0 }};
> +
>       start = last_update = monotime_double();
>       file = f;
>       start_pos = *ctr;
> @@ -252,13 +255,17 @@ start_progress_meter(const char *f, off_
>  
>       ssh_signal(SIGALRM, sig_alarm);
>       ssh_signal(SIGWINCH, sig_winch);
> -     alarm(UPDATE_INTERVAL);
> +     if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
> +             err(1, "setitimer");
>  }
>  
>  void
>  stop_progress_meter(void)
>  {
> -     alarm(0);
> +     struct itimerval zero = { 0 };
> +
> +     if (setitimer(ITIMER_REAL, &zero, NULL) == -1)
> +             err(1, "setitimer");
>  
>       if (!can_output())
>               return;
> 
> 

Reply via email to