aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTharre <tharre3@gmail.com>2014-11-24 17:26:48 +0100
committerTharre <tharre3@gmail.com>2014-11-24 17:26:48 +0100
commitf907d26292168cd9ba8900f3deec513c257c4ffc (patch)
tree5dc283c7fb1e390de2947e5060ad2f33b24412d1
parentb62ca1e0c5c7256c26a68a9a2fb132787a469fc1 (diff)
downloadredo-f907d26292168cd9ba8900f3deec513c257c4ffc.tar.gz
redo-f907d26292168cd9ba8900f3deec513c257c4ffc.tar.xz
redo-f907d26292168cd9ba8900f3deec513c257c4ffc.zip
Refactor out handle_c and fix > 8096 reading bug
-rw-r--r--src/build.c158
-rw-r--r--src/build.h2
2 files changed, 87 insertions, 73 deletions
diff --git a/src/build.c b/src/build.c
index 5763613..5ddda64 100644
--- a/src/build.c
+++ b/src/build.c
@@ -37,6 +37,7 @@ static char **parsecmd(char *cmd, size_t *i, size_t keep_free);
static char *get_relpath(const char *target);
static char *get_dep_path(const char *target);
static void write_dep_hash(const char *target);
+static int handle_c(const char *target);
struct do_attr {
char *specific;
@@ -46,7 +47,7 @@ struct do_attr {
/* Build given target, using it's do-file. */
-void build_target(const char *target) {
+int build_target(const char *target) {
/* get the do-file which we are going to execute */
struct do_attr *dofiles = get_dofiles(target);
if (!dofiles->chosen) {
@@ -55,7 +56,7 @@ void build_target(const char *target) {
then we treat it as a source */
write_dep_hash(target);
free_do_attr(dofiles);
- return;
+ return 1;
}
die("%s couldn't be built as no suitable do-file exists\n", target);
@@ -393,95 +394,108 @@ int update_target(const char *target, int ident) {
return 1;
case 'e':
if (fexists(target)) {
- debug("%s is not up-to-date: target exist and e ident was chosen\n", target);
+ debug("%s is not up-to-date: target exist and e ident was chosen\n",
+ target);
build_target(target);
return 1;
}
return 0;
case 'c':
-#define HEADERSIZE HASHSIZE + sizeof(unsigned)
- if (!fexists(target)) {
- /* target does not exist */
- debug("%s is not up-to-date: target doesn't exist\n", target);
+ return handle_c(target);
+ default:
+ die("redo: unknown identifier '%c'\n", ident);
+ }
+}
+
+static int handle_c(const char *target) {
+ if (!fexists(target)) {
+ /* target does not exist */
+ debug("%s is not up-to-date: target doesn't exist\n", target);
+ build_target(target);
+ return 1;
+ }
+
+ char *dep_path = get_dep_path(target);
+
+ FILE *fp = fopen(dep_path, "rb");
+ if (!fp) {
+ if (errno == ENOENT) {
+ /* dependency file does not exist */
+ debug("%s is not up-to-date: dependency file (%s) doesn't exist\n",
+ target, dep_path);
build_target(target);
+ free(dep_path);
return 1;
+ } else {
+ diem("redo: failed to open %s", dep_path);
}
+ }
- char *dep_path = get_dep_path(target);
+ char buf[8096 > FILENAME_MAX+3 ? 8096 : FILENAME_MAX*2];
- FILE *fp = fopen(dep_path, "rb");
- if (!fp) {
- if (errno == ENOENT) {
- /* dependency file does not exist */
- debug("%s is not up-to-date: dependency file (%s) doesn't exist\n",
- target, dep_path);
- build_target(target);
- return 1;
- } else {
- diem("redo: failed to open %s", dep_path);
- }
- }
+ if (fread(buf, 1, HEADERSIZE, fp) < HEADERSIZE)
+ diem("redo: failed to read %zu bytes from %s", HEADERSIZE, dep_path);
- char buf[8096];
- if (fread(buf, 1, HEADERSIZE, fp) < HEADERSIZE)
- diem("redo: failed to read %zu bytes from %s", HEADERSIZE, dep_path);
-
- free(dep_path);
+ free(dep_path);
- if (*(unsigned *) buf == (unsigned) atoi(getenv("REDO_MAGIC")))
- /* magic number matches */
- return 1;
+ if (*(unsigned *) buf == (unsigned) atoi(getenv("REDO_MAGIC")))
+ /* magic number matches */
+ return 1;
- char *root = getenv("REDO_ROOT");
- bool rebuild = false;
- unsigned char hash[HASHSIZE];
- hash_file(target, hash);
- if (memcmp(hash, buf+sizeof(unsigned), HASHSIZE)) {
- debug("%s is not-up-to-date: hashes don't match\n", target);
- build_target(target);
- return 1;
- }
+ char *root = getenv("REDO_ROOT");
+ bool rebuild = false;
+ unsigned char hash[HASHSIZE];
+ hash_file(target, hash);
+ if (memcmp(hash, buf+sizeof(unsigned), HASHSIZE)) {
+ debug("%s is not-up-to-date: hashes don't match\n", target);
+ build_target(target);
+ return 1;
+ }
- /* FIXME: this doesn't work properly if we actually read beyond 8096 bytes */
- while (!feof(fp)) {
- size_t read = fread(buf, 1, sizeof buf, fp);
-
- if (ferror(fp))
- diem("redo: failed to read %zu bytes from file descriptor", sizeof buf);
-
- char *ptr = buf;
- for (size_t i = 0; i < read; ++i) {
- if (buf[i])
- continue;
- if (!is_absolute(&ptr[1])) {
- /* if our path is relative we need to prefix it with the
- root project directory or the path will be invalid */
- char *abs = concat(3, root, "/", &ptr[1]);
- if (update_target(abs, ptr[0])) {
- debug("%s is not up-to-date: subdependency %s is out-of-date\n",
- target, abs);
- rebuild = true;
- }
- free(abs);
- } else {
- if (update_target(&ptr[1], ptr[0])) {
- debug("%s is not up-to-date: subdependency %s is out-of-date\n",
- target, &ptr[1]);
- rebuild = true;
- }
+ char *ptr;
+
+ while (!feof(fp)) {
+ ptr = buf;
+
+ size_t read = fread(buf, 1, sizeof buf, fp);
+ if (ferror(fp))
+ diem("redo: failed to read %zu bytes from descriptor", sizeof buf);
+
+ for (size_t i = 0; i < read; ++i) {
+ if (buf[i])
+ continue;
+ if (!is_absolute(&ptr[1])) {
+ /* if our path is relative we need to prefix it with the
+ root project directory or the path will be invalid */
+ char *abs = concat(3, root, "/", &ptr[1]);
+ if (update_target(abs, ptr[0])) {
+ debug("%s is not up-to-date: subdependency %s is out-of-date\n",
+ target, abs);
+ rebuild = true;
+ }
+ free(abs);
+ } else {
+ if (update_target(&ptr[1], ptr[0])) {
+ debug("%s is not up-to-date: subdependency %s is out-of-date\n",
+ target, &ptr[1]);
+ rebuild = true;
}
- ptr = &buf[i+1];
}
+ ptr = &buf[i+1];
}
- fclose(fp);
- if (rebuild) {
- build_target(target);
- return 1;
+ if (read && buf[read-1]) {
+ if (buf != ptr)
+ memmove(buf, ptr, buf-ptr + sizeof buf);
+ else
+ die("redo: dependency file contains insanely long paths\n");
}
- return 0;
+ }
- default:
- die("redo: unknown identiier '%c'\n", ident);
+ fclose(fp);
+ if (rebuild) {
+ build_target(target);
+ return 1;
}
+ return 0;
}
diff --git a/src/build.h b/src/build.h
index 2111b82..4961faa 100644
--- a/src/build.h
+++ b/src/build.h
@@ -13,6 +13,6 @@
extern void add_dep(const char *target, const char *parent, int ident);
extern int update_target(const char *target, int ident);
-extern void build_target(const char *target);
+extern int build_target(const char *target);
#endif