From dbb642206d2ef73c5428a04cb10bb27e7cdd3b29 Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Mon, 17 Jun 2013 13:51:49 +0300 Subject: io: fix splice for copying unknown lengths --- src/apk_io.h | 15 +++++++++++++-- src/io.c | 4 +++- src/url.c | 12 ++++++------ 3 files changed, 22 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/apk_io.h b/src/apk_io.h index 4790d80..2a6db5a 100644 --- a/src/apk_io.h +++ b/src/apk_io.h @@ -77,9 +77,11 @@ struct apk_ostream *apk_ostream_counter(off_t *); struct apk_istream *apk_istream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int)); struct apk_istream *apk_istream_from_file(int atfd, const char *file); struct apk_istream *apk_istream_from_file_gz(int atfd, const char *file); -struct apk_istream *apk_istream_from_url(const char *url); +struct apk_istream *apk_istream_from_fd_url(int atfd, const char *url); struct apk_istream *apk_istream_from_url_gz(const char *url); size_t apk_istream_skip(struct apk_istream *istream, size_t size); + +#define APK_SPLICE_ALL 0xffffffff size_t apk_istream_splice(void *stream, int fd, size_t size, apk_progress_cb cb, void *cb_ctx); @@ -87,11 +89,15 @@ static inline struct apk_istream *apk_istream_from_fd(int fd) { return apk_istream_from_fd_pid(fd, 0, NULL); } +static inline struct apk_istream *apk_istream_from_url(const char *url) +{ + return apk_istream_from_fd_url(-1, url); +} struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream); struct apk_bstream *apk_bstream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int)); struct apk_bstream *apk_bstream_from_file(int atfd, const char *file); -struct apk_bstream *apk_bstream_from_url(const char *url); +struct apk_bstream *apk_bstream_from_fd_url(int atfd, const char *url); struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to); static inline struct apk_bstream *apk_bstream_from_fd(int fd) @@ -99,6 +105,11 @@ static inline struct apk_bstream *apk_bstream_from_fd(int fd) return apk_bstream_from_fd_pid(fd, 0, NULL); } +static inline struct apk_bstream *apk_bstream_from_url(const char *url) +{ + return apk_bstream_from_fd_url(-1, url); +} + struct apk_ostream *apk_ostream_to_fd(int fd); struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, const char *tmpfile, mode_t mode); struct apk_ostream *apk_ostream_to_file_gz(int atfd, const char *file, const char *tmpfile, mode_t mode); diff --git a/src/io.c b/src/io.c index c14cc23..667d9aa 100644 --- a/src/io.c +++ b/src/io.c @@ -138,7 +138,7 @@ size_t apk_istream_splice(void *stream, int fd, size_t size, bufsz = size; if (size > 128 * 1024) { - if (ftruncate(fd, size) == 0) + if (size != APK_SPLICE_ALL && ftruncate(fd, size) == 0) mmapbase = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (bufsz > 2*1024*1024) @@ -165,6 +165,8 @@ size_t apk_istream_splice(void *stream, int fd, size_t size, r = is->read(is, buf, togo); if (r < 0) goto err; + if (r == 0) + break; if (mmapbase == MAP_FAILED) { if (write(fd, buf, r) != r) { diff --git a/src/url.c b/src/url.c index 2484a7f..c96e0a1 100644 --- a/src/url.c +++ b/src/url.c @@ -86,13 +86,13 @@ static int fork_wget(const char *url, pid_t *ppid) return fds[0]; } -struct apk_istream *apk_istream_from_url(const char *url) +struct apk_istream *apk_istream_from_fd_url(int atfd, const char *url) { pid_t pid; int fd; - if (apk_url_local_file(url) != NULL) - return apk_istream_from_file(AT_FDCWD, apk_url_local_file(url)); + if (atfd >= 0 && apk_url_local_file(url) != NULL) + return apk_istream_from_file(atfd, apk_url_local_file(url)); fd = fork_wget(url, &pid); return apk_istream_from_fd_pid(fd, pid, translate_wget); @@ -103,13 +103,13 @@ struct apk_istream *apk_istream_from_url_gz(const char *file) return apk_bstream_gunzip(apk_bstream_from_url(file)); } -struct apk_bstream *apk_bstream_from_url(const char *url) +struct apk_bstream *apk_bstream_from_fd_url(int atfd, const char *url) { pid_t pid; int fd; - if (apk_url_local_file(url)) - return apk_bstream_from_file(AT_FDCWD, url); + if (atfd >= 0 && apk_url_local_file(url)) + return apk_bstream_from_file(atfd, url); fd = fork_wget(url, &pid); return apk_bstream_from_fd_pid(fd, pid, translate_wget); -- cgit v1.2.3-70-g09d2