Welcome to little lamb

Code » limb » master » tree

[master] / src / liblimb / djbunix.h / open_writev_closeat.c

/* This file is part of limb                           https://lila.oss/limb
 * Copyright (C) 2023 Olivier Brunel                          jjk@jjacky.com */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <stdio.h>
#include <limb/allreadwrite.h>
#include <limb/djbunix.h>
#include <limb/siovec.h>

#define SUFFIX ":tmp.limb.XXXXXX"

int
open_writev_closeat(int bfd, const char *file, const struct iovec *v, unsigned n)
{
    size_t flen = strlen(file);
    char tmp[flen + sizeof(SUFFIX)];
    memcpy(tmp, file, flen);
    memcpy(tmp + flen, SUFFIX, sizeof(SUFFIX));
    int fd = open_tmpat(bfd, tmp);
    if (fd < 0) return 0;

    if (allwritev(fd, v, n) < siov_len(v, n) || renameat(bfd, tmp, bfd, file) < 0)
        goto err;

    fd_close(fd);
    return 1;

err:
    fd_close(fd);
    unlinkat_void(bfd, tmp, 0);
    return 0;
}