mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-03-25 13:29:03 +02:00
util/nvmutil: use renameat for atomic write
not rename(). use renameat() this re-uses the logic added for mkhtemp. this will later enable more stringent integrity checks, though we already verify the integrity of a file after writing it back, and renameat is always tied to the descriptor, so it's fine. Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
@@ -287,6 +287,11 @@ struct xfile {
|
||||
unsigned char bufcmp[GBE_BUF_SIZE]; /* compare gbe/tmp/reads */
|
||||
|
||||
unsigned char pad[GBE_WORK_SIZE]; /* the file that wouldn't die */
|
||||
|
||||
/* we later rename in-place, using old fd. renameat() */
|
||||
int dirfd;
|
||||
char *base;
|
||||
char *tmpbase;
|
||||
};
|
||||
|
||||
/* Command table, MAC address, files
|
||||
|
||||
@@ -432,32 +432,12 @@ gbe_mv(void)
|
||||
|
||||
saved_errno = errno;
|
||||
|
||||
/* TODO: remove this path-based rename,
|
||||
use fd */
|
||||
rval = rename(f->tname, f->fname);
|
||||
|
||||
if (rval > -1) {
|
||||
|
||||
/* rename on same filesystem
|
||||
*/
|
||||
rval = fs_rename_at(f->dirfd, f->tmpbase,
|
||||
f->dirfd, f->base);
|
||||
|
||||
if (rval > -1)
|
||||
tmp_gbe_bin_exists = 0;
|
||||
|
||||
/*
|
||||
if (fsync(dest_fd) < 0) {
|
||||
f->io_err_gbe_bin = 1;
|
||||
rval = -1;
|
||||
}
|
||||
*/
|
||||
|
||||
goto ret_gbe_mv;
|
||||
}
|
||||
|
||||
if (errno != EXDEV)
|
||||
goto ret_gbe_mv;
|
||||
|
||||
err(errno, "BUG: cross-filesystem move (this shouldn't happen)");
|
||||
|
||||
ret_gbe_mv:
|
||||
|
||||
/* TODO: this whole section is bloat.
|
||||
|
||||
@@ -29,6 +29,8 @@ xstart(int argc, char *argv[])
|
||||
static char *dir = NULL;
|
||||
static char *base = NULL;
|
||||
char *realdir = NULL;
|
||||
char *tmpdir = NULL;
|
||||
char *tmpbase_local = NULL;
|
||||
|
||||
static struct xstate us = {
|
||||
{
|
||||
@@ -118,9 +120,27 @@ xstart(int argc, char *argv[])
|
||||
err_no_cleanup(errno, "xstart: don't know CWD of %s",
|
||||
us.f.fname);
|
||||
|
||||
if ((us.f.base = strdup(base)) == NULL)
|
||||
err_no_cleanup(errno, "strdup base");
|
||||
|
||||
us.f.dirfd = fs_open(dir,
|
||||
O_RDONLY | O_DIRECTORY);
|
||||
if (us.f.dirfd < 0)
|
||||
err_no_cleanup(errno, "%s: open dir", dir);
|
||||
|
||||
if (new_tmpfile(&us.f.tmp_fd, &us.f.tname, dir) < 0)
|
||||
err_no_cleanup(errno, "%s", us.f.tname);
|
||||
|
||||
if (fs_dirname_basename(us.f.tname,
|
||||
&tmpdir, &tmpbase_local, 0) < 0)
|
||||
err_no_cleanup(errno, "tmp basename");
|
||||
|
||||
us.f.tmpbase = strdup(tmpbase_local);
|
||||
if (us.f.tmpbase == NULL)
|
||||
err_no_cleanup(errno, "strdup tmpbase");
|
||||
|
||||
free_if_null(&tmpdir);
|
||||
|
||||
if (us.f.tname == NULL)
|
||||
err_no_cleanup(errno, "x->f.tname null");
|
||||
if (*us.f.tname == '\0')
|
||||
@@ -197,6 +217,10 @@ exit_cleanup(void)
|
||||
if (f->tname != NULL)
|
||||
if (unlink(f->tname) == -1)
|
||||
close_err = 1;
|
||||
|
||||
close_no_err(&f->dirfd);
|
||||
free_if_null(&f->base);
|
||||
free_if_null(&f->tmpbase);
|
||||
}
|
||||
|
||||
if (saved_errno)
|
||||
|
||||
Reference in New Issue
Block a user