> 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;
>
>