[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Bug-tar] SA_RESTART, perhaps?
From: |
Kevin Fox |
Subject: |
Re: [Bug-tar] SA_RESTART, perhaps? |
Date: |
Tue, 27 Sep 2011 13:35:25 -0700 |
On Tue, 2011-09-27 at 13:00 -0700, Paul Eggert wrote:
> Would it make sense to install the following patch to GNU tar?
>
> The idea here is that I suspect that GNU tar won't work well
> if random system calls fail with errno == EINTR, and this
> change would help insulate tar from that issue, on platforms
> that support SA_RESTART.
>
I considered that. Actually, it handles the case already of errno ==
EINTR in safe_rw.
The following document helps explain what happens when SA_RESTART is
used:
http://www.gnu.org/s/hello/manual/libc/Interrupted-Primitives.html
It states:
There is one situation where resumption never happens no matter which
choice you make: (ie, SA_RESTART or not) when a data-transfer function
such as read or write is interrupted by a signal after transferring part
of the data. In this case, the function returns the number of bytes
already transferred, indicating partial success.
As far as I can figure, partial read is an integral part of the read
api. You can't disable enough stuff so that it doesn't ever happen. We
can fix it in safe_rw to loop and fill the rest of the buffer in this
case fairly easily, or in another wrapper around safe_rw, or everywhere
in the code that cares. Its a very small patch really, in all but the
latter case.
Thanks,
Kevin
> This change affects tar's behavior only if the
> --totals=SIG option is specified, for some signal SIG.
>
> diff --git a/src/tar.c b/src/tar.c
> index 6d37044..f0d8f5b 100644
> --- a/src/tar.c
> +++ b/src/tar.c
> @@ -956,10 +956,13 @@ static void
> stat_on_signal (int signo)
> {
> #ifdef HAVE_SIGACTION
> +# ifndef SA_RESTART
> +# define SA_RESTART 0
> +# endif
> struct sigaction act;
> act.sa_handler = sigstat;
> sigemptyset (&act.sa_mask);
> - act.sa_flags = 0;
> + act.sa_flags = SA_RESTART;
> sigaction (signo, &act, NULL);
> #else
> signal (signo, sigstat);
>