Commit dbb64220 authored by Timo Teräs's avatar Timo Teräs

io: fix splice for copying unknown lengths

parent f79e3946
......@@ -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);
......
......@@ -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) {
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment