Commit 354c772e authored by Rusty Russell's avatar Rusty Russell

Fix Joey's report of rename failing across moint points.

parent f7b3eb1e
......@@ -46,7 +46,7 @@ static void *do_build(struct manifest *m)
if (filename) {
char *realname = talloc_asprintf(m, "%s.o", m->dir);
/* We leave this object file around, all built. */
if (rename(filename, realname) != 0)
if (!move_file(filename, realname))
return talloc_asprintf(m, "Failed to rename %s to %s",
filename, realname);
return NULL;
......
#include <tools/ccanlint/ccanlint.h>
#include <tools/doc_extract.h>
#include <tools/tools.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
......@@ -81,7 +82,7 @@ static void create_info_template_doc(struct manifest *m, void *check_result)
unlink_noerr("_info.new");
err(1, "Closing _info.new");
}
if (rename("_info.new", "_info") != 0) {
if (!move_file("_info.new", "_info")) {
unlink_noerr("_info.new");
err(1, "Renaming _info.new to _info");
}
......
......@@ -406,7 +406,7 @@ static void setup_adjust_files(const char *dir,
static void rename_files(const struct adjusted *adj)
{
while (adj) {
if (rename(adj->tmpfile, adj->file) != 0)
if (!move_file(adj->tmpfile, adj->file))
warn("Could not rename over '%s', we're in trouble",
adj->file);
adj = adj->next;
......
#include <ccan/talloc/talloc.h>
#include <ccan/grab_file/grab_file.h>
#include <ccan/noerr/noerr.h>
#include <ccan/read_write_all/read_write_all.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
......@@ -107,3 +110,39 @@ char *temp_file(const void *ctx, const char *extension)
return talloc_asprintf(ctx, "%s/%u%s", tmpdir, count++, extension);
}
bool move_file(const char *oldname, const char *newname)
{
char *contents;
size_t size;
int fd;
bool ret;
/* Simple case: rename works. */
if (rename(oldname, newname) == 0)
return true;
/* Try copy and delete: not atomic! */
contents = grab_file(NULL, oldname, &size);
if (!contents)
return false;
fd = open(newname, O_WRONLY|O_CREAT|O_TRUNC, 0666);
if (fd < 0) {
ret = false;
goto free;
}
ret = write_all(fd, contents, size);
if (close(fd) != 0)
ret = false;
if (ret)
unlink(oldname);
else
unlink(newname);
free:
talloc_free(contents);
return ret;
}
......@@ -29,6 +29,7 @@ char *talloc_dirname(const void *ctx, const char *dir);
char *talloc_getcwd(const void *ctx);
char *run_command(const void *ctx, const char *fmt, ...);
char *temp_file(const void *ctx, const char *extension);
bool move_file(const char *oldname, const char *newname);
/* From compile.c.
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment