summaryrefslogtreecommitdiffstats
path: root/usr.bin/tar/write.c
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2008-07-05 08:03:08 +0000
committercperciva <cperciva@FreeBSD.org>2008-07-05 08:03:08 +0000
commite2615c73e35aeaa1b898221ac63c1837803cdfc4 (patch)
tree0b3bf6f768d6a1bd95d8a42553facf54ceb2521d /usr.bin/tar/write.c
parent62e198e3179a13191226b09152f6e3ee7f6a14e0 (diff)
downloadFreeBSD-src-e2615c73e35aeaa1b898221ac63c1837803cdfc4.zip
FreeBSD-src-e2615c73e35aeaa1b898221ac63c1837803cdfc4.tar.gz
Use malloc in write_archive to allocate a 64kB buffer for holding file data
instead of using 64kB of stack space in copy_file_data and write_file_data.
Diffstat (limited to 'usr.bin/tar/write.c')
-rw-r--r--usr.bin/tar/write.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/usr.bin/tar/write.c b/usr.bin/tar/write.c
index 2d22ff7..d604095 100644
--- a/usr.bin/tar/write.c
+++ b/usr.bin/tar/write.c
@@ -79,6 +79,9 @@ __FBSDID("$FreeBSD$");
#include "bsdtar.h"
#include "tree.h"
+/* Size of buffer for holding file data prior to writing. */
+#define FILEDATABUFLEN 65536
+
/* Fixed size of uname/gname caches. */
#define name_cache_size 101
@@ -434,6 +437,10 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
const char *arg;
struct archive_entry *entry, *sparse_entry;
+ /* Allocate a buffer for file data. */
+ if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL)
+ bsdtar_errc(bsdtar, 1, 0, "cannot allocate memory");
+
if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL)
bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver");
archive_entry_linkresolver_set_strategy(bsdtar->resolver,
@@ -484,6 +491,9 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
bsdtar->return_value = 1;
}
+
+ /* Free file data buffer. */
+ free(bsdtar->buff);
}
/*
@@ -615,22 +625,23 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
static int
copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
{
- char buff[64*1024];
ssize_t bytes_read;
ssize_t bytes_written;
off_t progress = 0;
- bytes_read = archive_read_data(ina, buff, sizeof(buff));
+ bytes_read = archive_read_data(ina, bsdtar->buff, FILEDATABUFLEN);
while (bytes_read > 0) {
siginfo_printinfo(bsdtar, progress);
- bytes_written = archive_write_data(a, buff, bytes_read);
+ bytes_written = archive_write_data(a, bsdtar->buff,
+ bytes_read);
if (bytes_written < bytes_read) {
bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
return (-1);
}
progress += bytes_written;
- bytes_read = archive_read_data(ina, buff, sizeof(buff));
+ bytes_read = archive_read_data(ina, bsdtar->buff,
+ FILEDATABUFLEN);
}
return (0);
@@ -956,24 +967,21 @@ abort:
}
-/* Helper function to copy file to archive, with stack-allocated buffer. */
+/* Helper function to copy file to archive. */
static int
write_file_data(struct bsdtar *bsdtar, struct archive *a,
struct archive_entry *entry, int fd)
{
- char buff[64*1024];
ssize_t bytes_read;
ssize_t bytes_written;
off_t progress = 0;
- /* XXX TODO: Allocate buffer on heap and store pointer to
- * it in bsdtar structure; arrange cleanup as well. XXX */
-
- bytes_read = read(fd, buff, sizeof(buff));
+ bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN);
while (bytes_read > 0) {
siginfo_printinfo(bsdtar, progress);
- bytes_written = archive_write_data(a, buff, bytes_read);
+ bytes_written = archive_write_data(a, bsdtar->buff,
+ FILEDATABUFLEN);
if (bytes_written < 0) {
/* Write failed; this is bad */
bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
@@ -987,7 +995,7 @@ write_file_data(struct bsdtar *bsdtar, struct archive *a,
return (0);
}
progress += bytes_written;
- bytes_read = read(fd, buff, sizeof(buff));
+ bytes_read = read(fd, bsdtar->buff, FILEDATABUFLEN);
}
return 0;
}
OpenPOWER on IntegriCloud