diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2015-02-05 23:56:14 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2015-02-05 23:56:14 +0000 |
commit | 153a646667ff5ae7578a6027938524db91c40821 (patch) | |
tree | 429f092f8254acbb207302d9dd8c790bc596322f /src/libstddjb | |
parent | cea441e894405c6d28e302ae4360e9f848b37797 (diff) | |
download | skalibs-153a646667ff5ae7578a6027938524db91c40821.tar.xz |
- Add siovec_trunc
- Add openwritevnclose
- replace buffer_read/write with fd_readsv/writesv
- add localtmn_from_tain_g
- refactor cdb_make
- rewrite buffer_getvall and buffer_putvall, with a bugfix
Diffstat (limited to 'src/libstddjb')
-rw-r--r-- | src/libstddjb/allreadwritev.c | 2 | ||||
-rw-r--r-- | src/libstddjb/bufalloc_init.c | 2 | ||||
-rw-r--r-- | src/libstddjb/buffer_0.c | 3 | ||||
-rw-r--r-- | src/libstddjb/buffer_0small.c | 3 | ||||
-rw-r--r-- | src/libstddjb/buffer_1.c | 3 | ||||
-rw-r--r-- | src/libstddjb/buffer_1small.c | 3 | ||||
-rw-r--r-- | src/libstddjb/buffer_2.c | 3 | ||||
-rw-r--r-- | src/libstddjb/buffer_flush1read.c | 3 | ||||
-rw-r--r-- | src/libstddjb/buffer_getall.c | 9 | ||||
-rw-r--r-- | src/libstddjb/buffer_getv.c | 11 | ||||
-rw-r--r-- | src/libstddjb/buffer_getvall.c | 24 | ||||
-rw-r--r-- | src/libstddjb/buffer_init.c | 3 | ||||
-rw-r--r-- | src/libstddjb/buffer_putv.c | 6 | ||||
-rw-r--r-- | src/libstddjb/buffer_putvall.c | 23 | ||||
-rw-r--r-- | src/libstddjb/buffer_read.c | 14 | ||||
-rw-r--r-- | src/libstddjb/buffer_write.c | 11 | ||||
-rw-r--r-- | src/libstddjb/cdb_make.c | 73 | ||||
-rw-r--r-- | src/libstddjb/fd_readsv.c | 2 | ||||
-rw-r--r-- | src/libstddjb/fd_writesv.c | 2 | ||||
-rw-r--r-- | src/libstddjb/iobufferu_init.c | 5 | ||||
-rw-r--r-- | src/libstddjb/openwritevnclose_suffix.c | 30 | ||||
-rw-r--r-- | src/libstddjb/openwritevnclose_unsafe.c | 33 | ||||
-rw-r--r-- | src/libstddjb/siovec_trunc.c | 18 |
23 files changed, 174 insertions, 112 deletions
diff --git a/src/libstddjb/allreadwritev.c b/src/libstddjb/allreadwritev.c index a156698..28695a1 100644 --- a/src/libstddjb/allreadwritev.c +++ b/src/libstddjb/allreadwritev.c @@ -10,7 +10,7 @@ unsigned int allreadwritev (iovfunc_t_ref op, int fd, siovec_t const *v, unsigne siovec_t vv[vlen] ; for (; written < vlen ; written++) vv[written] = v[written] ; written = 0 ; - while (siovec_len(v, vlen)) + while (siovec_len(vv, vlen)) { register int w = (*op)(fd, vv, vlen) ; if (w <= 0) break ; diff --git a/src/libstddjb/bufalloc_init.c b/src/libstddjb/bufalloc_init.c index 921dc3d..913dabb 100644 --- a/src/libstddjb/bufalloc_init.c +++ b/src/libstddjb/bufalloc_init.c @@ -5,7 +5,7 @@ void bufalloc_init (bufalloc *ba, int (*op)(int, char const *, unsigned int), int fd) { - ba->x.len = 0 ; + ba->x = stralloc_zero ; ba->op = op ; ba->fd = fd ; ba->p = 0 ; diff --git a/src/libstddjb/buffer_0.c b/src/libstddjb/buffer_0.c index 50dc6dc..5d40465 100644 --- a/src/libstddjb/buffer_0.c +++ b/src/libstddjb/buffer_0.c @@ -2,7 +2,8 @@ /* MT-unsafe */ +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> static char buf[BUFFER_INSIZE] ; -buffer buffer_0_ = BUFFER_INIT(&buffer_read, 0, buf, BUFFER_INSIZE) ; +buffer buffer_0_ = BUFFER_INIT(&fd_readsv, 0, buf, BUFFER_INSIZE) ; diff --git a/src/libstddjb/buffer_0small.c b/src/libstddjb/buffer_0small.c index 849edec..7537dd6 100644 --- a/src/libstddjb/buffer_0small.c +++ b/src/libstddjb/buffer_0small.c @@ -2,7 +2,8 @@ /* MT-unsafe */ +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> static char buf[BUFFER_INSIZE_SMALL] ; -buffer buffer_0small_ = BUFFER_INIT(&buffer_read, 0, buf, BUFFER_INSIZE_SMALL) ; +buffer buffer_0small_ = BUFFER_INIT(&fd_readsv, 0, buf, BUFFER_INSIZE_SMALL) ; diff --git a/src/libstddjb/buffer_1.c b/src/libstddjb/buffer_1.c index 088d421..46d9647 100644 --- a/src/libstddjb/buffer_1.c +++ b/src/libstddjb/buffer_1.c @@ -2,7 +2,8 @@ /* MT-unsafe */ +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> static char buf[BUFFER_OUTSIZE] ; -buffer buffer_1_ = BUFFER_INIT(&buffer_write, 1, buf, BUFFER_OUTSIZE) ; +buffer buffer_1_ = BUFFER_INIT(&fd_writesv, 1, buf, BUFFER_OUTSIZE) ; diff --git a/src/libstddjb/buffer_1small.c b/src/libstddjb/buffer_1small.c index 6e9cfa2..2bf13e6 100644 --- a/src/libstddjb/buffer_1small.c +++ b/src/libstddjb/buffer_1small.c @@ -2,7 +2,8 @@ /* MT-unsafe */ +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> static char buf[BUFFER_OUTSIZE_SMALL] ; -buffer buffer_1small_ = BUFFER_INIT(&buffer_write, 1, buf, BUFFER_OUTSIZE_SMALL) ; +buffer buffer_1small_ = BUFFER_INIT(&fd_writesv, 1, buf, BUFFER_OUTSIZE_SMALL) ; diff --git a/src/libstddjb/buffer_2.c b/src/libstddjb/buffer_2.c index 9bc4e3f..8bf9d63 100644 --- a/src/libstddjb/buffer_2.c +++ b/src/libstddjb/buffer_2.c @@ -2,7 +2,8 @@ /* MT-unsafe */ +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> static char buf[BUFFER_ERRSIZE] ; -buffer buffer_2_ = BUFFER_INIT(&buffer_write, 2, buf, BUFFER_ERRSIZE) ; +buffer buffer_2_ = BUFFER_INIT(&fd_writesv, 2, buf, BUFFER_ERRSIZE) ; diff --git a/src/libstddjb/buffer_flush1read.c b/src/libstddjb/buffer_flush1read.c index 1a771ea..aaa2869 100644 --- a/src/libstddjb/buffer_flush1read.c +++ b/src/libstddjb/buffer_flush1read.c @@ -1,10 +1,11 @@ /* ISC license. */ +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> #include <skalibs/siovec.h> int buffer_flush1read (int fd, siovec_t const *v, unsigned int n) { if (!buffer_flush(buffer_1)) return -1 ; - return buffer_read(fd, v, n) ; + return fd_readsv(fd, v, n) ; } diff --git a/src/libstddjb/buffer_getall.c b/src/libstddjb/buffer_getall.c index 4f1490b..dc0e115 100644 --- a/src/libstddjb/buffer_getall.c +++ b/src/libstddjb/buffer_getall.c @@ -7,12 +7,13 @@ int buffer_getall (buffer *b, char *buf, unsigned int len, unsigned int *w) { if (*w > len) return (errno = EINVAL, -1) ; - *w += buffer_getnofill(b, buf + *w, len - *w) ; - while (*w < len) + for (;;) { - register int r = sanitize_read(buffer_fill(b)) ; - if (r <= 0) return r ; + register int r ; *w += buffer_getnofill(b, buf + *w, len - *w) ; + if (*w >= len) break ; + r = sanitize_read(buffer_fill(b)) ; + if (r <= 0) return r ; } return 1 ; } diff --git a/src/libstddjb/buffer_getv.c b/src/libstddjb/buffer_getv.c index 0f8f848..b3d237e 100644 --- a/src/libstddjb/buffer_getv.c +++ b/src/libstddjb/buffer_getv.c @@ -1,15 +1,12 @@ /* ISC license. */ -#include <errno.h> +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> -#include <skalibs/diuint.h> #include <skalibs/siovec.h> int buffer_getv (buffer *b, siovec_t const *v, unsigned int n) { - diuint w = DIUINT_ZERO ; - register int r = buffer_getvall(b, v, n, &w) ; - return r == -1 ? errno == EPIPE ? (errno = 0, 0) : -1 : - !r ? (errno = EWOULDBLOCK, -1) : - (int)(siovec_len(v, w.left) + w.right) ; + unsigned int w = 0 ; + register int r = unsanitize_read(buffer_getvall(b, v, n, &w)) ; + return r <= 0 ? r : w ; } diff --git a/src/libstddjb/buffer_getvall.c b/src/libstddjb/buffer_getvall.c index b6eeb46..e34c547 100644 --- a/src/libstddjb/buffer_getvall.c +++ b/src/libstddjb/buffer_getvall.c @@ -1,18 +1,30 @@ /* ISC license. */ #include <errno.h> +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> -#include <skalibs/diuint.h> #include <skalibs/siovec.h> -int buffer_getvall (buffer *b, siovec_t const *v, unsigned int n, diuint *w) +int buffer_getvall (buffer *b, siovec_t const *v, unsigned int n, unsigned int *written) { - if (w->left > n || (w->left == n && w->right) || w->right >= v[w->left].len) - return (errno = EINVAL, -1) ; - for (; w->left < n ; w->left++, w->right = 0) + unsigned int len = siovec_len(v, n) ; + siovec_t vv[n] ; + if (*written > len) return (errno = EINVAL, -1) ; { - register int r = buffer_getall(b, v[w->left].s, v[w->left].len, &w->right) ; + register unsigned int i = n ; + while (i--) vv[i] = v[i] ; + } + siovec_seek(vv, n, *written) ; + for (;;) + { + register int r ; + unsigned int w = buffer_getvnofill(b, vv, n) ; + *written += w ; + if (*written >= len) break ; + siovec_seek(vv, n, w) ; + r = sanitize_read(buffer_fill(b)) ; if (r <= 0) return r ; } return 1 ; } + diff --git a/src/libstddjb/buffer_init.c b/src/libstddjb/buffer_init.c index 2831fe1..fac648a 100644 --- a/src/libstddjb/buffer_init.c +++ b/src/libstddjb/buffer_init.c @@ -2,9 +2,10 @@ #include <errno.h> #include <skalibs/cbuffer.h> +#include <skalibs/functypes.h> #include <skalibs/buffer.h> -int buffer_init (buffer *b, buffer_io_func_t *op, int fd, char *s, unsigned int len) +int buffer_init (buffer *b, iovfunc_t_ref op, int fd, char *s, unsigned int len) { if (!cbuffer_init(&b->c, s, len)) return 0 ; b->fd = fd ; diff --git a/src/libstddjb/buffer_putv.c b/src/libstddjb/buffer_putv.c index a1530d2..fc46811 100644 --- a/src/libstddjb/buffer_putv.c +++ b/src/libstddjb/buffer_putv.c @@ -1,12 +1,10 @@ /* ISC license. */ #include <skalibs/buffer.h> -#include <skalibs/diuint.h> #include <skalibs/siovec.h> int buffer_putv (buffer *b, siovec_t const *v, unsigned int n) { - diuint w = DIUINT_ZERO ; - if (!buffer_putvall(b, v, n, &w)) return -1 ; - return (int)(siovec_len(v, w.left) + w.right) ; + unsigned int w = 0 ; + return buffer_putvall(b, v, n, &w) ? w : -1 ; } diff --git a/src/libstddjb/buffer_putvall.c b/src/libstddjb/buffer_putvall.c index d6297c1..22b7ae4 100644 --- a/src/libstddjb/buffer_putvall.c +++ b/src/libstddjb/buffer_putvall.c @@ -2,14 +2,23 @@ #include <errno.h> #include <skalibs/buffer.h> -#include <skalibs/diuint.h> #include <skalibs/siovec.h> -int buffer_putvall (buffer *b, siovec_t const *v, unsigned int n, diuint *w) +int buffer_putvall (buffer *b, siovec_t const *v, unsigned int n, unsigned int *written) { - if (w->left > n || (w->left == n && w->right) || w->right >= v[w->left].len) - return (errno = EINVAL, 0) ; - for (; w->left < n ; w->left++, w->right = 0) - if (!buffer_putall(b, v[w->left].s, v[w->left].len, &w->right)) return 0 ; - return 1 ; + unsigned int len = siovec_len(v, n) ; + unsigned int w = n ; + siovec_t vv[n] ; + if (*written > len) return (errno = EINVAL, 0) ; + while (w--) vv[w] = v[w] ; + w = *written ; + for (;;) + { + siovec_seek(vv, n, w) ; + w = buffer_putvnoflush(b, vv, n) ; + *written += w ; + if (*written >= len) return 1 ; + buffer_flush(b) ; + if (buffer_isfull(b)) return 0 ; + } } diff --git a/src/libstddjb/buffer_read.c b/src/libstddjb/buffer_read.c deleted file mode 100644 index 88003b4..0000000 --- a/src/libstddjb/buffer_read.c +++ /dev/null @@ -1,14 +0,0 @@ -/* ISC license. */ - -#include <sys/types.h> -#include <sys/uio.h> -#include <skalibs/allreadwrite.h> -#include <skalibs/siovec.h> -#include <skalibs/buffer.h> - -int buffer_read (int fd, siovec_t const *v, unsigned int n) -{ - struct iovec iov[n] ; - iovec_from_siovec(iov, v, n) ; - return fd_readv(fd, iov, n) ; -} diff --git a/src/libstddjb/buffer_write.c b/src/libstddjb/buffer_write.c deleted file mode 100644 index b924cbb..0000000 --- a/src/libstddjb/buffer_write.c +++ /dev/null @@ -1,11 +0,0 @@ -/* ISC license. */ - -#include <skalibs/allreadwrite.h> -#include <skalibs/siovec.h> -#include <skalibs/buffer.h> - -int buffer_write (int fd, siovec_t const *v, unsigned int n) -{ - unsigned int w = allreadwritev(&fd_writesv, fd, v, n) ; - return w ? (int)w : -1 ; -} diff --git a/src/libstddjb/cdb_make.c b/src/libstddjb/cdb_make.c index 0ec3423..203d24c 100644 --- a/src/libstddjb/cdb_make.c +++ b/src/libstddjb/cdb_make.c @@ -4,26 +4,19 @@ #include <errno.h> #include <skalibs/uint32.h> #include <skalibs/diuint32.h> -#include <skalibs/genalloc.h> +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> #include <skalibs/djbunix.h> +#include <skalibs/genalloc.h> #include <skalibs/cdb.h> #include <skalibs/cdb_make.h> -static void cdb_make_free (struct cdb_make *c) -{ - struct cdb_make zero = CDB_MAKE_ZERO ; - genalloc_free(diuint32, &c->hplist) ; - *c = zero ; -} - int cdb_make_start (struct cdb_make *c, int fd) { c->hplist = genalloc_zero ; - c->fd = fd ; c->pos = 2048 ; - buffer_init(&c->b, &buffer_write, fd, c->buf, BUFFER_OUTSIZE) ; - return seek_set(fd, c->pos) ; + buffer_init(&c->b, &fd_writesv, fd, c->buf, BUFFER_OUTSIZE) ; + return (int)lseek(fd, c->pos, SEEK_SET) ; } static int posplus (struct cdb_make *c, uint32 len) @@ -34,41 +27,30 @@ static int posplus (struct cdb_make *c, uint32 len) return 1 ; } -static int cdb_make_addend (struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h) +static inline int cdb_make_addend (struct cdb_make *c, unsigned int keylen, unsigned int datalen, uint32 h) { - diuint32 blah = { h, c->pos } ; - if (!genalloc_append(diuint32, &c->hplist, &blah) || !posplus(c, 8) || !posplus(c, keylen) || !posplus(c, datalen)) - { - cdb_make_free(c) ; - return -1 ; - } - return 0 ; + diuint32 blah = { .left = h, .right = c->pos } ; + return genalloc_append(diuint32, &c->hplist, &blah) && posplus(c, 8) && posplus(c, keylen) && posplus(c, datalen) ; } -static int cdb_make_addbegin (struct cdb_make *c, unsigned int keylen, unsigned int datalen) +static inline int cdb_make_addbegin (struct cdb_make *c, unsigned int keylen, unsigned int datalen) { char buf[8] ; - if ((keylen > 0xffffffff) || (datalen > 0xffffffff)) - { - errno = ENOMEM ; - goto err ; - } - uint32_pack(buf, keylen) ; - uint32_pack(buf + 4, datalen) ; - if (buffer_put(&c->b, buf, 8) < 0) goto err ; - return 0 ; -err: - cdb_make_free(c) ; - return -1 ; + uint32_pack(buf, (uint32)keylen) ; + uint32_pack(buf + 4, (uint32)datalen) ; + return buffer_put(&c->b, buf, 8) ; } int cdb_make_add (struct cdb_make *c, char const *key, unsigned int keylen, char const *data, unsigned int datalen) { - if ((cdb_make_addbegin(c, keylen, datalen) < 0) - || (buffer_put(&c->b, key, keylen) < 0) - || (buffer_put(&c->b, data, datalen) < 0) - || (cdb_make_addend(c, keylen, datalen, cdb_hash(key, keylen)) < 0)) + if (cdb_make_addbegin(c, keylen, datalen) < 0 + || buffer_put(&c->b, key, keylen) < 0 + || buffer_put(&c->b, data, datalen) < 0 + || !cdb_make_addend(c, keylen, datalen, cdb_hash(key, keylen))) + { + genalloc_free(diuint32, &c->hplist) ; return -1 ; + } return 0 ; } @@ -82,7 +64,7 @@ int cdb_make_finish (struct cdb_make *c) register unsigned int i = 0 ; register diuint32 *hp = genalloc_s(diuint32, &c->hplist) ; - for ( ; i < 256 ; i++) count[i] = 0 ; + for (; i < 256 ; i++) count[i] = 0 ; for (i = 0 ; i < n ; i++) ++count[hp[i].left & 255] ; { @@ -115,7 +97,7 @@ int cdb_make_finish (struct cdb_make *c) uint32_pack(final + (i << 3), c->pos) ; uint32_pack(final + (i << 3) + 4, len) ; - for ( ; j < len ; j++) hp[j].left = hp[j].right = 0 ; + for (; j < len ; j++) hp[j].left = hp[j].right = 0 ; for (j = 0 ; j < k ; j++) { register uint32 where = (p->left >> 8) % len ; @@ -127,19 +109,14 @@ int cdb_make_finish (struct cdb_make *c) { uint32_pack(buf, hp[j].left) ; uint32_pack(buf + 4, hp[j].right) ; - if (buffer_put(&c->b, buf, 8) < 0) goto err0 ; - if (!posplus(c, 8)) goto err0 ; + if (buffer_put(&c->b, buf, 8) < 0) return -1 ; + if (!posplus(c, 8)) return -1 ; } } } - if (!buffer_flush(&c->b)) goto err0 ; - if (seek_begin(c->fd) == -1) goto err0 ; - if (buffer_putflush(&c->b, final, 2048) < 0) goto err0 ; - cdb_make_free(c) ; + if (!buffer_flush(&c->b)) return -1 ; + if (lseek(buffer_fd(&c->b), 0, SEEK_SET) < 0) return -1 ; + if (buffer_putflush(&c->b, final, 2048) < 0) return -1 ; return 0 ; - -err0: - cdb_make_free(c) ; - return -1 ; } diff --git a/src/libstddjb/fd_readsv.c b/src/libstddjb/fd_readsv.c index 39efe19..e4390df 100644 --- a/src/libstddjb/fd_readsv.c +++ b/src/libstddjb/fd_readsv.c @@ -1,5 +1,7 @@ /* ISC license. */ +#include <sys/types.h> +#include <sys/uio.h> #include <skalibs/allreadwrite.h> #include <skalibs/siovec.h> diff --git a/src/libstddjb/fd_writesv.c b/src/libstddjb/fd_writesv.c index bd3c2c3..d16991b 100644 --- a/src/libstddjb/fd_writesv.c +++ b/src/libstddjb/fd_writesv.c @@ -1,5 +1,7 @@ /* ISC license. */ +#include <sys/types.h> +#include <sys/uio.h> #include <skalibs/allreadwrite.h> #include <skalibs/siovec.h> diff --git a/src/libstddjb/iobufferu_init.c b/src/libstddjb/iobufferu_init.c index d2b86c8..490ac59 100644 --- a/src/libstddjb/iobufferu_init.c +++ b/src/libstddjb/iobufferu_init.c @@ -1,6 +1,7 @@ /* ISC license. */ #include <skalibs/alloc.h> +#include <skalibs/allreadwrite.h> #include <skalibs/buffer.h> #include <skalibs/iobuffer.h> @@ -9,7 +10,7 @@ int iobufferu_init (iobufferu *b, int fdin, int fdout) register char *x = alloc(IOBUFFERU_SIZE) ; if (!x) return 0 ; b->buf = x ; - buffer_init(&b->b[0], &buffer_read, fdin, x, IOBUFFERU_SIZE) ; - buffer_init(&b->b[1], &buffer_write, fdout, x, IOBUFFERU_SIZE) ; + buffer_init(&b->b[0], &fd_readsv, fdin, x, IOBUFFERU_SIZE) ; + buffer_init(&b->b[1], &fd_writesv, fdout, x, IOBUFFERU_SIZE) ; return 1 ; } diff --git a/src/libstddjb/openwritevnclose_suffix.c b/src/libstddjb/openwritevnclose_suffix.c new file mode 100644 index 0000000..0440960 --- /dev/null +++ b/src/libstddjb/openwritevnclose_suffix.c @@ -0,0 +1,30 @@ +/* ISC license. */ + +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <skalibs/uint64.h> +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> +#include <skalibs/djbunix.h> + +int openwritevnclose_suffix_internal (char const *fn, siovec_t const *v, unsigned int n, uint64 *dev, uint64 *ino, int dosync, char const *suffix) +{ + uint64 tmpdev, tmpino ; + unsigned int len = str_len(fn) ; + unsigned int suffixlen = str_len(suffix) ; + char tmp[len + suffixlen + 1] ; + byte_copy(tmp, len, fn) ; + byte_copy(tmp + len, suffixlen + 1, suffix) ; + if (!openwritevnclose_unsafe_internal(tmp, v, n, dev ? &tmpdev : 0, ino ? &tmpino : 0, dosync)) return 0 ; + if (rename(tmp, fn) < 0) + { + register int e = errno ; + unlink(tmp) ; + errno = e ; + return 0 ; + } + if (dev) *dev = tmpdev ; + if (ino) *ino = tmpino ; + return 1 ; +} diff --git a/src/libstddjb/openwritevnclose_unsafe.c b/src/libstddjb/openwritevnclose_unsafe.c new file mode 100644 index 0000000..feb2ae5 --- /dev/null +++ b/src/libstddjb/openwritevnclose_unsafe.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <unistd.h> +#include <skalibs/uint64.h> +#include <skalibs/allreadwrite.h> +#include <skalibs/siovec.h> +#include <skalibs/djbunix.h> + +int openwritevnclose_unsafe_internal (char const *fn, siovec_t const *v, unsigned int vlen, uint64 *dev, uint64 *ino, int dosync) +{ + struct stat st ; + int fd = open_trunc(fn) ; + if (fd < 0) return 0 ; + if (allwritev(fd, v, vlen) < siovec_len(v, vlen)) goto fail ; + if ((dev || ino) && (fstat(fd, &st) < 0)) goto fail ; + if (dosync && (fd_sync(fd) < 0) && (errno != EINVAL)) goto fail ; + fd_close(fd) ; + if (dev) *dev = (uint64)st.st_dev ; + if (ino) *ino = (uint64)st.st_ino ; + return 1 ; + + fail: + { + register int e = errno ; + fd_close(fd) ; + unlink(fn) ; + errno = e ; + } + return 0 ; +} diff --git a/src/libstddjb/siovec_trunc.c b/src/libstddjb/siovec_trunc.c new file mode 100644 index 0000000..c09225a --- /dev/null +++ b/src/libstddjb/siovec_trunc.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include <skalibs/bytestr.h> +#include <skalibs/siovec.h> + +unsigned int siovec_trunc (siovec_t *v, unsigned int n, unsigned int len) +{ + register unsigned int i = siovec_len(v, n) ; + if (i < len) return n ; + len = i - len ; + i = n ; + while (len && i--) + { + register unsigned int w = len > v[i].len ? v[i].len : len ; + v[i].len -= w ; len -= w ; + } + return i ; +} |