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 <swel...@gmail.com> writes:
Tim Kientzle <kient...@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
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;
}
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"