Date: Sat, 22 May 2010 10:17:54 -0700 From: Tim Kientzle <kientzle@freebsd.org> To: Anonymous <swell.k@gmail.com> Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r207790 - head/usr.bin/tar Message-ID: <4BF811C2.4050901@freebsd.org> In-Reply-To: <86mxvsxtjh.fsf@gmail.com> References: <201005081628.o48GSM9s067363__30886.3841965378$1273336146$gmane$org@svn.freebsd.org> <86aas3oc8b.fsf@gmail.com> <4BF059FF.8050002__30617.9139217877$1274042897$gmane$org@freebsd.org> <861vdaakkf.fsf@gmail.com> <86mxvsxtjh.fsf@gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Ah, yes. I did forget to add an EINTR check to the write side.
Attached patch should fix "tar cf"
Thanks for your careful testing...
Anonymous wrote:
> Anonymous <swell.k@gmail.com> writes:
>
>> Tim Kientzle <kientzle@freebsd.org> writes:
>>
>>> Please try the attached patch and let me know if it fixes it for you...
>>>
>>> Cheers,
>>>
>>> Tim
>> [...]
>>
>> It fixes the issue. Thanks.
>
> I'm afraid not. Similar issue affects `tar cf - blah | tar xf -'.
> It's a little bit harder to reproduce. Caught after using pkg_add(1).
>
> # pkg_add gtk-2.20.1_1.tbz
> load: 0.21 cmd: bsdtar 3351 [running] 0.06r 0.02u 0.00s 1% 6348k
> In: 307200 bytes, compression 76%; Out: 161 files, 1316787 bytes
> Current: include/gtk-2.0/gtk/gtklabel.h (8627 bytes)
> load: 0.16 cmd: bsdtar 3354 [tx->tx_quiesce_done_cv)] 4.08r 0.00u 0.14s 1% 2712k
> In: 544 files, 36359168 bytes; Out: 36352000 bytes, compression 0%
> Current: share/locale/hi/LC_MESSAGES/gtk20-properties.mo (131072/234342 bytes)
> load: 0.16 cmd: bsdtar 3354 [tx->tx_quiesce_done_cv)] 4.86r 0.00u 0.14s 1% 2712k
> tar: Write error
> In: 36341760 bytes, compression 0%; Out: 544 files, 36341760 bytes
> Current: share/locale/hi/LC_MESSAGES/gtk20-properties.mo (234342 bytes)
> share/locale/hi/LC_MESSAGES/gtk20-properties.mo: Truncated tar archive
> tar: Error exit delayed from previous errors.
> pkg_add: leave_playpen: can't chdir back to ''
> zsh: exit 2 sudo -E pkg_add gtk-x11-2.20.1_1.tbz
>
> Workaround is the same - svn diff -c207790 | patch -R
>
> --
> I don't remember svn revision (newvers.sh doesn't work here). But it was
> after you committed that patch.
>
> $ uname -vm
> FreeBSD 9.0-CURRENT #0: Fri May 21 15:32:05 UTC 2010 ...:.../PHOENIX amd64
>
>
[-- Attachment #2 --]
Index: archive_write_open_fd.c
===================================================================
--- archive_write_open_fd.c (revision 2413)
+++ archive_write_open_fd.c (working copy)
@@ -51,7 +51,6 @@
#include "archive.h"
struct write_fd_data {
- off_t offset;
int fd;
};
@@ -122,12 +121,16 @@
ssize_t bytesWritten;
mine = (struct write_fd_data *)client_data;
- bytesWritten = write(mine->fd, buff, length);
- if (bytesWritten <= 0) {
- archive_set_error(a, errno, "Write error");
- return (-1);
+ for (;;) {
+ bytesWritten = write(mine->fd, buff, length);
+ if (bytesWritten <= 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Write error");
+ return (-1);
+ }
+ return (bytesWritten);
}
- return (bytesWritten);
}
static int
Index: archive_write_open_file.c
===================================================================
--- archive_write_open_file.c (revision 2413)
+++ archive_write_open_file.c (working copy)
@@ -86,12 +86,16 @@
size_t bytesWritten;
mine = client_data;
- bytesWritten = fwrite(buff, 1, length, mine->f);
- if (bytesWritten < length) {
- archive_set_error(a, errno, "Write error");
- return (-1);
+ for (;;) {
+ bytesWritten = fwrite(buff, 1, length, mine->f);
+ if (bytesWritten <= 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Write error");
+ return (-1);
+ }
+ return (bytesWritten);
}
- return (bytesWritten);
}
static int
Index: archive_write_open_filename.c
===================================================================
--- archive_write_open_filename.c (revision 2413)
+++ archive_write_open_filename.c (working copy)
@@ -142,12 +142,16 @@
ssize_t bytesWritten;
mine = (struct write_file_data *)client_data;
- bytesWritten = write(mine->fd, buff, length);
- if (bytesWritten <= 0) {
- archive_set_error(a, errno, "Write error");
- return (-1);
+ for (;;) {
+ bytesWritten = write(mine->fd, buff, length);
+ if (bytesWritten <= 0) {
+ if (errno == EINTR)
+ continue;
+ archive_set_error(a, errno, "Write error");
+ return (-1);
+ }
+ return (bytesWritten);
}
- return (bytesWritten);
}
static int
Index: archive_write.c
===================================================================
--- archive_write.c (revision 2413)
+++ archive_write.c (working copy)
@@ -361,11 +361,20 @@
remaining -= to_copy;
/* ... if it's full, write it out. */
if (state->avail == 0) {
- bytes_written = (a->client_writer)(&a->archive,
- a->client_data, state->buffer, state->buffer_size);
- if (bytes_written <= 0)
- return (ARCHIVE_FATAL);
- /* XXX TODO: if bytes_written < state->buffer_size */
+ char *p = state->buffer;
+ size_t remaining = state->buffer_size;
+ while (remaining > 0) {
+ bytes_written = (a->client_writer)(&a->archive,
+ a->client_data, p, remaining);
+ if (bytes_written <= 0)
+ return (ARCHIVE_FATAL);
+ if (bytes_remaining > remaining) {
+ archive_set_error(a, -1, "write overrun");
+ return (ARCHIVE_FATAL);
+ }
+ p += bytes_written;
+ remaining -= bytes_written;
+ }
state->next = state->buffer;
state->avail = state->buffer_size;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4BF811C2.4050901>
