From 749f6041a00b218a7d1fe668fa5efd455563e92e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Mon, 7 Apr 2008 00:31:01 -0400 Subject: [PATCH] Create the new repo file O_EXCL to prevent racing with another razor process. And remember to clean it up on exit paths. --- main.c | 38 ++++++++++++++++++++++++++++---------- razor.c | 28 ++++++++++++++++++++-------- razor.h | 1 + 3 files changed, 49 insertions(+), 18 deletions(-) diff --git a/main.c b/main.c index 6bcd996..a2ef1d0 100644 --- a/main.c +++ b/main.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -530,33 +531,50 @@ command_install(int argc, const char *argv[]) struct razor_transaction *trans; char path[PATH_MAX], new_path[PATH_MAX]; CURL *curl; - int errors; + int errors, fd; + + /* Create the new next repo file up front to ensure exclusive + * access. */ + snprintf(new_path, sizeof new_path, + "%s%s/%s", root, razor_root_path, next_repo_filename); + fd = open(new_path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666); + if (fd < 0) { + fprintf(stderr, "failed to get lock file, " + "maybe previous operation crashed?\n"); + + /* FIXME: Use fcntl advisory locking to figure out + * whether previous operation crashed or is still in + * progress. */ + + return -1; + } upstream = razor_set_open(rawhide_repo_filename); snprintf(path, sizeof path, "%s%s/%s", root, razor_root_path, system_repo_filename); system = razor_set_open(path); - if (system == NULL || upstream == NULL) + if (system == NULL || upstream == NULL) { + unlink(new_path); return 1; + } trans = razor_transaction_create(system, upstream, argc, argv, 0, NULL); errors = razor_transaction_describe(trans); - if (errors) + if (errors) { + unlink(new_path); return 1; + } next = razor_transaction_finish(trans); - /* FIXME: Need razor_set_write_to_fd() so we can open it excl - * up front here or fail if it already exists. */ - snprintf(new_path, sizeof new_path, - "%s%s/%s", root, razor_root_path, next_repo_filename); - - razor_set_write(next, new_path); + razor_set_write_to_fd(next, fd); printf("wrote %s\n", new_path); curl = curl_easy_init(); - if (curl == NULL) + if (curl == NULL) { + unlink(new_path); return 1; + } razor_set_diff(system, next, download_package, curl); curl_easy_cleanup(curl); diff --git a/razor.c b/razor.c index 5e77402..722f41b 100644 --- a/razor.c +++ b/razor.c @@ -198,13 +198,13 @@ razor_set_destroy(struct razor_set *set) } int -razor_set_write(struct razor_set *set, const char *filename) +razor_set_write_to_fd(struct razor_set *set, int fd) { char data[4096]; struct razor_set_header *header = (struct razor_set_header *) data; struct array *a; uint32_t offset; - int i, fd; + int i; memset(data, 0, sizeof data); header->magic = RAZOR_MAGIC; @@ -225,10 +225,6 @@ razor_set_write(struct razor_set *set, const char *filename) header->sections[i].offset = 0; header->sections[i].size = 0; - fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); - if (fd < 0) - return -1; - razor_write(fd, data, sizeof data); memset(data, 0, sizeof data); for (i = 0; i < ARRAY_SIZE(razor_sections); i++) { @@ -239,11 +235,27 @@ razor_set_write(struct razor_set *set, const char *filename) razor_write(fd, data, ALIGN(a->size, 4096) - a->size); } - close(fd); - return 0; } +int +razor_set_write(struct razor_set *set, const char *filename) +{ + int fd, status; + + fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); + if (fd < 0) + return -1; + + status = razor_set_write_to_fd(set, fd); + if (status) { + close(fd); + return status; + } + + return close(fd); +} + void razor_build_evr(char *evr_buf, int size, const char *epoch, const char *version, const char *release) diff --git a/razor.h b/razor.h index cc6a869..62e8e5f 100644 --- a/razor.h +++ b/razor.h @@ -26,6 +26,7 @@ extern const char * const razor_version_relations[]; struct razor_set *razor_set_create(void); struct razor_set *razor_set_open(const char *filename); void razor_set_destroy(struct razor_set *set); +int razor_set_write_to_fd(struct razor_set *set, int fd); int razor_set_write(struct razor_set *set, const char *filename); struct razor_package * -- 1.7.1