io: formalize apk_ostream_write() always writing full data
parent
796d298313
commit
395e92b66e
|
@ -141,7 +141,7 @@ struct apk_istream *apk_istream_tee(struct apk_istream *from, struct apk_ostream
|
||||||
|
|
||||||
struct apk_ostream_ops {
|
struct apk_ostream_ops {
|
||||||
void (*set_meta)(struct apk_ostream *os, struct apk_file_meta *meta);
|
void (*set_meta)(struct apk_ostream *os, struct apk_file_meta *meta);
|
||||||
ssize_t (*write)(struct apk_ostream *os, const void *buf, size_t size);
|
int (*write)(struct apk_ostream *os, const void *buf, size_t size);
|
||||||
int (*close)(struct apk_ostream *os);
|
int (*close)(struct apk_ostream *os);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -153,12 +153,11 @@ struct apk_ostream {
|
||||||
struct apk_ostream *apk_ostream_counter(off_t *);
|
struct apk_ostream *apk_ostream_counter(off_t *);
|
||||||
struct apk_ostream *apk_ostream_to_fd(int fd);
|
struct apk_ostream *apk_ostream_to_fd(int fd);
|
||||||
struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, mode_t mode);
|
struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, mode_t mode);
|
||||||
size_t apk_ostream_write_string(struct apk_ostream *os, const char *string);
|
ssize_t apk_ostream_write_string(struct apk_ostream *os, const char *string);
|
||||||
void apk_ostream_copy_meta(struct apk_ostream *os, struct apk_istream *is);
|
void apk_ostream_copy_meta(struct apk_ostream *os, struct apk_istream *is);
|
||||||
static inline int apk_ostream_error(struct apk_ostream *os) { return os->rc; }
|
static inline int apk_ostream_error(struct apk_ostream *os) { return os->rc; }
|
||||||
static inline int apk_ostream_cancel(struct apk_ostream *os, int rc) { if (!os->rc) os->rc = rc; return rc; }
|
static inline int apk_ostream_cancel(struct apk_ostream *os, int rc) { if (!os->rc) os->rc = rc; return rc; }
|
||||||
static inline ssize_t apk_ostream_write(struct apk_ostream *os, const void *buf, size_t size)
|
static inline int apk_ostream_write(struct apk_ostream *os, const void *buf, size_t size) {
|
||||||
{
|
|
||||||
return os->ops->write(os, buf, size);
|
return os->ops->write(os, buf, size);
|
||||||
}
|
}
|
||||||
static inline int apk_ostream_close(struct apk_ostream *os)
|
static inline int apk_ostream_close(struct apk_ostream *os)
|
||||||
|
|
|
@ -986,15 +986,16 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
||||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
|
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apk_ostream_write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf)
|
r = apk_ostream_write(os, buf, bbuf.ptr - buf);
|
||||||
return -EIO;
|
if (r < 0) return r;
|
||||||
bbuf = APK_BLOB_BUF(buf);
|
bbuf = APK_BLOB_BUF(buf);
|
||||||
}
|
}
|
||||||
if (apk_ostream_write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf)
|
r = apk_ostream_write(os, buf, bbuf.ptr - buf);
|
||||||
return -EIO;
|
if (r < 0) return r;
|
||||||
bbuf = APK_BLOB_BUF(buf);
|
bbuf = APK_BLOB_BUF(buf);
|
||||||
}
|
}
|
||||||
apk_ostream_write(os, "\n", 1);
|
r = apk_ostream_write(os, "\n", 1);
|
||||||
|
if (r < 0) return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1194,11 +1195,10 @@ static int write_index_entry(apk_hash_item item, void *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = apk_pkg_write_index_entry(pkg, iwctx->os);
|
r = apk_pkg_write_index_entry(pkg, iwctx->os);
|
||||||
if (r < 0)
|
if (r < 0) return r;
|
||||||
return r;
|
|
||||||
|
|
||||||
if (apk_ostream_write(iwctx->os, "\n", 1) != 1)
|
r = apk_ostream_write(iwctx->os, "\n", 1);
|
||||||
return apk_ostream_cancel(iwctx->os, -EIO);
|
if (r < 0) return r;
|
||||||
|
|
||||||
iwctx->count++;
|
iwctx->count++;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
45
src/io.c
45
src/io.c
|
@ -314,13 +314,10 @@ static void tee_get_meta(struct apk_istream *is, struct apk_file_meta *meta)
|
||||||
apk_istream_get_meta(tee->inner_is, meta);
|
apk_istream_get_meta(tee->inner_is, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t __tee_write(struct apk_tee_istream *tee, void *ptr, size_t size)
|
static int __tee_write(struct apk_tee_istream *tee, void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
ssize_t w = apk_ostream_write(tee->to, ptr, size);
|
int r = apk_ostream_write(tee->to, ptr, size);
|
||||||
if (size != w) {
|
if (r < 0) return r;
|
||||||
if (w < 0) return w;
|
|
||||||
return -ENOSPC;
|
|
||||||
}
|
|
||||||
tee->size += size;
|
tee->size += size;
|
||||||
if (tee->cb) tee->cb(tee->cb_ctx, tee->size);
|
if (tee->cb) tee->cb(tee->cb_ctx, tee->size);
|
||||||
return size;
|
return size;
|
||||||
|
@ -828,11 +825,8 @@ static ssize_t fdo_flush(struct apk_fd_ostream *fos)
|
||||||
|
|
||||||
if (fos->os.rc < 0) return fos->os.rc;
|
if (fos->os.rc < 0) return fos->os.rc;
|
||||||
if (fos->bytes == 0) return 0;
|
if (fos->bytes == 0) return 0;
|
||||||
|
if ((r = apk_write_fully(fos->fd, fos->buffer, fos->bytes)) != fos->bytes)
|
||||||
if ((r = apk_write_fully(fos->fd, fos->buffer, fos->bytes)) != fos->bytes) {
|
return apk_ostream_cancel(&fos->os, r < 0 ? r : -ENOSPC);
|
||||||
apk_ostream_cancel(&fos->os, r < 0 ? r : -ENOSPC);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
fos->bytes = 0;
|
fos->bytes = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -849,7 +843,7 @@ static void fdo_set_meta(struct apk_ostream *os, struct apk_file_meta *meta)
|
||||||
futimens(fos->fd, times);
|
futimens(fos->fd, times);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t fdo_write(struct apk_ostream *os, const void *ptr, size_t size)
|
static int fdo_write(struct apk_ostream *os, const void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
struct apk_fd_ostream *fos = container_of(os, struct apk_fd_ostream, os);
|
struct apk_fd_ostream *fos = container_of(os, struct apk_fd_ostream, os);
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
|
@ -868,7 +862,7 @@ static ssize_t fdo_write(struct apk_ostream *os, const void *ptr, size_t size)
|
||||||
memcpy(&fos->buffer[fos->bytes], ptr, size);
|
memcpy(&fos->buffer[fos->bytes], ptr, size);
|
||||||
fos->bytes += size;
|
fos->bytes += size;
|
||||||
|
|
||||||
return size;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fdo_close(struct apk_ostream *os)
|
static int fdo_close(struct apk_ostream *os)
|
||||||
|
@ -877,12 +871,10 @@ static int fdo_close(struct apk_ostream *os)
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
fdo_flush(fos);
|
fdo_flush(fos);
|
||||||
|
if (fos->fd > STDERR_FILENO && close(fos->fd) < 0)
|
||||||
|
apk_ostream_cancel(os, -errno);
|
||||||
|
|
||||||
rc = fos->os.rc;
|
rc = fos->os.rc;
|
||||||
|
|
||||||
if (fos->fd > STDERR_FILENO &&
|
|
||||||
close(fos->fd) < 0)
|
|
||||||
rc = -errno;
|
|
||||||
|
|
||||||
if (fos->file) {
|
if (fos->file) {
|
||||||
char tmpname[PATH_MAX];
|
char tmpname[PATH_MAX];
|
||||||
|
|
||||||
|
@ -895,7 +887,6 @@ static int fdo_close(struct apk_ostream *os)
|
||||||
unlinkat(fos->atfd, tmpname, 0);
|
unlinkat(fos->atfd, tmpname, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(fos);
|
free(fos);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -954,20 +945,20 @@ struct apk_counter_ostream {
|
||||||
off_t *counter;
|
off_t *counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t co_write(struct apk_ostream *os, const void *ptr, size_t size)
|
static int co_write(struct apk_ostream *os, const void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
struct apk_counter_ostream *cos = container_of(os, struct apk_counter_ostream, os);
|
struct apk_counter_ostream *cos = container_of(os, struct apk_counter_ostream, os);
|
||||||
|
|
||||||
*cos->counter += size;
|
*cos->counter += size;
|
||||||
return size;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int co_close(struct apk_ostream *os)
|
static int co_close(struct apk_ostream *os)
|
||||||
{
|
{
|
||||||
struct apk_counter_ostream *cos = container_of(os, struct apk_counter_ostream, os);
|
struct apk_counter_ostream *cos = container_of(os, struct apk_counter_ostream, os);
|
||||||
|
int rc = os->rc;
|
||||||
|
|
||||||
free(cos);
|
free(cos);
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct apk_ostream_ops counter_ostream_ops = {
|
static const struct apk_ostream_ops counter_ostream_ops = {
|
||||||
|
@ -991,14 +982,14 @@ struct apk_ostream *apk_ostream_counter(off_t *counter)
|
||||||
return &cos->os;
|
return &cos->os;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t apk_ostream_write_string(struct apk_ostream *os, const char *string)
|
ssize_t apk_ostream_write_string(struct apk_ostream *os, const char *string)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
ssize_t r;
|
||||||
|
|
||||||
len = strlen(string);
|
len = strlen(string);
|
||||||
if (apk_ostream_write(os, string, len) != len)
|
r = apk_ostream_write(os, string, len);
|
||||||
return -1;
|
if (r < 0) return r;
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -302,15 +302,15 @@ int apk_tar_write_entry(struct apk_ostream *os, const struct apk_file_info *ae,
|
||||||
put_octal(buf.chksum, sizeof(buf.chksum)-1, chksum);
|
put_octal(buf.chksum, sizeof(buf.chksum)-1, chksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf))
|
if (apk_ostream_write(os, &buf, sizeof(buf)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (ae == NULL) {
|
if (ae == NULL) {
|
||||||
/* End-of-archive is two empty headers */
|
/* End-of-archive is two empty headers */
|
||||||
if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf))
|
if (apk_ostream_write(os, &buf, sizeof(buf)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
} else if (data != NULL) {
|
} else if (data != NULL) {
|
||||||
if (apk_ostream_write(os, data, ae->size) != ae->size)
|
if (apk_ostream_write(os, data, ae->size) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (apk_tar_write_padding(os, ae) != 0)
|
if (apk_tar_write_padding(os, ae) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -326,7 +326,7 @@ int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae
|
||||||
|
|
||||||
pad = 512 - (ae->size & 511);
|
pad = 512 - (ae->size & 511);
|
||||||
if (pad != 512 &&
|
if (pad != 512 &&
|
||||||
apk_ostream_write(os, padding, pad) != pad)
|
apk_ostream_write(os, padding, pad) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -176,7 +176,7 @@ struct apk_gzip_ostream {
|
||||||
z_stream zs;
|
z_stream zs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t gzo_write(struct apk_ostream *os, const void *ptr, size_t size)
|
static int gzo_write(struct apk_ostream *os, const void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
struct apk_gzip_ostream *gos = container_of(os, struct apk_gzip_ostream, os);
|
struct apk_gzip_ostream *gos = container_of(os, struct apk_gzip_ostream, os);
|
||||||
unsigned char buffer[1024];
|
unsigned char buffer[1024];
|
||||||
|
@ -189,16 +189,15 @@ static ssize_t gzo_write(struct apk_ostream *os, const void *ptr, size_t size)
|
||||||
gos->zs.next_out = buffer;
|
gos->zs.next_out = buffer;
|
||||||
r = deflate(&gos->zs, Z_NO_FLUSH);
|
r = deflate(&gos->zs, Z_NO_FLUSH);
|
||||||
if (r == Z_STREAM_ERROR)
|
if (r == Z_STREAM_ERROR)
|
||||||
return -EIO;
|
return apk_ostream_cancel(gos->output, -EIO);
|
||||||
have = sizeof(buffer) - gos->zs.avail_out;
|
have = sizeof(buffer) - gos->zs.avail_out;
|
||||||
if (have != 0) {
|
if (have != 0) {
|
||||||
r = apk_ostream_write(gos->output, buffer, have);
|
r = apk_ostream_write(gos->output, buffer, have);
|
||||||
if (r != have)
|
if (r < 0) return r;
|
||||||
return -EIO;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gzo_close(struct apk_ostream *os)
|
static int gzo_close(struct apk_ostream *os)
|
||||||
|
@ -206,24 +205,21 @@ static int gzo_close(struct apk_ostream *os)
|
||||||
struct apk_gzip_ostream *gos = container_of(os, struct apk_gzip_ostream, os);
|
struct apk_gzip_ostream *gos = container_of(os, struct apk_gzip_ostream, os);
|
||||||
unsigned char buffer[1024];
|
unsigned char buffer[1024];
|
||||||
size_t have;
|
size_t have;
|
||||||
int r, rc = 0;
|
int r, rc = os->rc;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
gos->zs.avail_out = sizeof(buffer);
|
gos->zs.avail_out = sizeof(buffer);
|
||||||
gos->zs.next_out = buffer;
|
gos->zs.next_out = buffer;
|
||||||
r = deflate(&gos->zs, Z_FINISH);
|
r = deflate(&gos->zs, Z_FINISH);
|
||||||
have = sizeof(buffer) - gos->zs.avail_out;
|
have = sizeof(buffer) - gos->zs.avail_out;
|
||||||
if (apk_ostream_write(gos->output, buffer, have) != have)
|
if (apk_ostream_write(gos->output, buffer, have) < 0)
|
||||||
rc = -EIO;
|
break;
|
||||||
} while (r == Z_OK);
|
} while (r == Z_OK);
|
||||||
r = apk_ostream_close(gos->output);
|
r = apk_ostream_close(gos->output);
|
||||||
if (r != 0)
|
|
||||||
rc = r;
|
|
||||||
|
|
||||||
deflateEnd(&gos->zs);
|
deflateEnd(&gos->zs);
|
||||||
free(gos);
|
free(gos);
|
||||||
|
|
||||||
return rc;
|
return rc ?: r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct apk_ostream_ops gzip_ostream_ops = {
|
static const struct apk_ostream_ops gzip_ostream_ops = {
|
||||||
|
|
|
@ -439,7 +439,7 @@ int apk_deps_write(struct apk_database *db, struct apk_dependency_array *deps, s
|
||||||
|
|
||||||
blob = apk_blob_pushed(APK_BLOB_BUF(tmp), blob);
|
blob = apk_blob_pushed(APK_BLOB_BUF(tmp), blob);
|
||||||
if (APK_BLOB_IS_NULL(blob) ||
|
if (APK_BLOB_IS_NULL(blob) ||
|
||||||
apk_ostream_write(os, blob.ptr, blob.len) != blob.len)
|
apk_ostream_write(os, blob.ptr, blob.len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
n += blob.len;
|
n += blob.len;
|
||||||
|
@ -1086,9 +1086,9 @@ static int write_depends(struct apk_ostream *os, const char *field,
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (deps->num == 0) return 0;
|
if (deps->num == 0) return 0;
|
||||||
if (apk_ostream_write(os, field, 2) != 2) return -1;
|
if (apk_ostream_write(os, field, 2) < 0) return -1;
|
||||||
if ((r = apk_deps_write(NULL, deps, os, APK_BLOB_PTR_LEN(" ", 1))) < 0) return r;
|
if ((r = apk_deps_write(NULL, deps, os, APK_BLOB_PTR_LEN(" ", 1))) < 0) return r;
|
||||||
if (apk_ostream_write(os, "\n", 1) != 1) return -1;
|
if (apk_ostream_write(os, "\n", 1) < 0) return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1144,7 +1144,7 @@ int apk_pkg_write_index_entry(struct apk_package *info,
|
||||||
return apk_ostream_cancel(os, -ENOBUFS);
|
return apk_ostream_cancel(os, -ENOBUFS);
|
||||||
|
|
||||||
bbuf = apk_blob_pushed(APK_BLOB_BUF(buf), bbuf);
|
bbuf = apk_blob_pushed(APK_BLOB_BUF(buf), bbuf);
|
||||||
if (apk_ostream_write(os, bbuf.ptr, bbuf.len) != bbuf.len ||
|
if (apk_ostream_write(os, bbuf.ptr, bbuf.len) ||
|
||||||
write_depends(os, "D:", info->depends) ||
|
write_depends(os, "D:", info->depends) ||
|
||||||
write_depends(os, "p:", info->provides) ||
|
write_depends(os, "p:", info->provides) ||
|
||||||
write_depends(os, "i:", info->install_if))
|
write_depends(os, "i:", info->install_if))
|
||||||
|
|
Loading…
Reference in New Issue