summaryrefslogtreecommitdiff
path: root/src/libstddjb
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstddjb')
-rw-r--r--src/libstddjb/allreadwritev.c2
-rw-r--r--src/libstddjb/bufalloc_init.c2
-rw-r--r--src/libstddjb/buffer_0.c3
-rw-r--r--src/libstddjb/buffer_0small.c3
-rw-r--r--src/libstddjb/buffer_1.c3
-rw-r--r--src/libstddjb/buffer_1small.c3
-rw-r--r--src/libstddjb/buffer_2.c3
-rw-r--r--src/libstddjb/buffer_flush1read.c3
-rw-r--r--src/libstddjb/buffer_getall.c9
-rw-r--r--src/libstddjb/buffer_getv.c11
-rw-r--r--src/libstddjb/buffer_getvall.c24
-rw-r--r--src/libstddjb/buffer_init.c3
-rw-r--r--src/libstddjb/buffer_putv.c6
-rw-r--r--src/libstddjb/buffer_putvall.c23
-rw-r--r--src/libstddjb/buffer_read.c14
-rw-r--r--src/libstddjb/buffer_write.c11
-rw-r--r--src/libstddjb/cdb_make.c73
-rw-r--r--src/libstddjb/fd_readsv.c2
-rw-r--r--src/libstddjb/fd_writesv.c2
-rw-r--r--src/libstddjb/iobufferu_init.c5
-rw-r--r--src/libstddjb/openwritevnclose_suffix.c30
-rw-r--r--src/libstddjb/openwritevnclose_unsafe.c33
-rw-r--r--src/libstddjb/siovec_trunc.c18
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 ;
+}