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) ...@@ -46,7 +46,7 @@ static void *do_build(struct manifest *m)
if (filename) { if (filename) {
char *realname = talloc_asprintf(m, "%s.o", m->dir); char *realname = talloc_asprintf(m, "%s.o", m->dir);
/* We leave this object file around, all built. */ /* 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", return talloc_asprintf(m, "Failed to rename %s to %s",
filename, realname); filename, realname);
return NULL; return NULL;
......
#include <tools/ccanlint/ccanlint.h> #include <tools/ccanlint/ccanlint.h>
#include <tools/doc_extract.h> #include <tools/doc_extract.h>
#include <tools/tools.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -81,7 +82,7 @@ static void create_info_template_doc(struct manifest *m, void *check_result) ...@@ -81,7 +82,7 @@ static void create_info_template_doc(struct manifest *m, void *check_result)
unlink_noerr("_info.new"); unlink_noerr("_info.new");
err(1, "Closing _info.new"); err(1, "Closing _info.new");
} }
if (rename("_info.new", "_info") != 0) { if (!move_file("_info.new", "_info")) {
unlink_noerr("_info.new"); unlink_noerr("_info.new");
err(1, "Renaming _info.new to _info"); err(1, "Renaming _info.new to _info");
} }
......
...@@ -406,7 +406,7 @@ static void setup_adjust_files(const char *dir, ...@@ -406,7 +406,7 @@ static void setup_adjust_files(const char *dir,
static void rename_files(const struct adjusted *adj) static void rename_files(const struct adjusted *adj)
{ {
while (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", warn("Could not rename over '%s', we're in trouble",
adj->file); adj->file);
adj = adj->next; adj = adj->next;
......
#include <ccan/talloc/talloc.h> #include <ccan/talloc/talloc.h>
#include <ccan/grab_file/grab_file.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/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <stdarg.h> #include <stdarg.h>
...@@ -107,3 +110,39 @@ char *temp_file(const void *ctx, const char *extension) ...@@ -107,3 +110,39 @@ char *temp_file(const void *ctx, const char *extension)
return talloc_asprintf(ctx, "%s/%u%s", tmpdir, count++, 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); ...@@ -29,6 +29,7 @@ char *talloc_dirname(const void *ctx, const char *dir);
char *talloc_getcwd(const void *ctx); char *talloc_getcwd(const void *ctx);
char *run_command(const void *ctx, const char *fmt, ...); char *run_command(const void *ctx, const char *fmt, ...);
char *temp_file(const void *ctx, const char *extension); char *temp_file(const void *ctx, const char *extension);
bool move_file(const char *oldname, const char *newname);
/* From compile.c. /* 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