diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/build.c | 44 | 
1 files changed, 24 insertions, 20 deletions
diff --git a/src/build.c b/src/build.c index 4342033..c1dd602 100644 --- a/src/build.c +++ b/src/build.c @@ -339,38 +339,42 @@ static char *get_dep_path(const char *target) {  	return dep_path;  } -/* Add the dependency target, with the identifier ident. */ +/* Declare that `parent` depends on `target`. */  void add_dep(const char *target, const char *parent, int ident) {  	char *dep_path = get_dep_path(parent); -	FILE *fp = fopen(dep_path, "rb+"); -	if (!fp) { -		if (errno == ENOENT) { -			fp = fopen(dep_path, "w"); -			if (!fp) -				fatal("redo: failed to open %s", dep_path); -			/* skip the first n bytes that are reserved for the header */ -			fseek(fp, HEADERSIZE, SEEK_SET); -		} else { +	int fd = open(dep_path, O_WRONLY | O_APPEND); +	if (fd < 0) { +		if (errno != ENOENT) +			fatal("redo: failed to open %s", dep_path); + +		/* no dependency record was found, so we create one */ +		mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; +		fd = open(dep_path, O_WRONLY | O_APPEND | O_CREAT, mode); +		if (fd < 0)  			fatal("redo: failed to open %s", dep_path); -		} -	} else { -		fseek(fp, 0L, SEEK_END);  	} -	char *reltarget = get_relpath(target); +	char garbage[HEADERSIZE]; -	putc(ident, fp); -	fputs(reltarget, fp); -	putc('\0', fp); +	/* skip header */ +	if (lseek(fd, 0, SEEK_END) < (off_t) HEADERSIZE) +		pwrite(fd, garbage, HEADERSIZE, 0); -	if (ferror(fp)) +	char *reltarget = get_relpath(target); +	int bufsize = strlen(reltarget) + 2; +	char *buf = xmalloc(bufsize); +	buf[0] = ident; +	strcpy(buf+1, reltarget); +	if (write(fd, buf, bufsize) < bufsize)  		fatal("redo: failed to write to %s", dep_path); -	if (fclose(fp)) +	if (close(fd))  		fatal("redo: failed to close %s", dep_path); -	free(dep_path); + +	free(buf);  	free(reltarget); +	free(dep_path);  }  /* Hash target, storing the result in hash. */  | 
