Example #1
0
/*
  execute a compiler backend, capturing all output to the given paths
  the full path to the compiler to run is in argv[0]
*/
int
execute(char **argv, const char *path_stdout, const char *path_stderr)
{
	pid_t pid;
	int status;

	cc_log_argv("Executing ", argv);

	pid = fork();
	if (pid == -1) fatal("Failed to fork: %s", strerror(errno));

	if (pid == 0) {
		int fd;

		tmp_unlink(path_stdout);
		fd = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
		if (fd == -1) {
			cc_log("Error creating %s: %s", path_stdout, strerror(errno));
			exit(FAILED_TO_CREATE_STDOUT);
		}
		dup2(fd, 1);
		close(fd);

		tmp_unlink(path_stderr);
		fd = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
		if (fd == -1) {
			cc_log("Error creating %s: %s", path_stderr, strerror(errno));
			exit(FAILED_TO_CREATE_STDERR);
		}
		dup2(fd, 2);
		close(fd);

		exit(execv(argv[0], argv));
	}

	if (waitpid(pid, &status, 0) != pid) {
		fatal("waitpid failed: %s", strerror(errno));
	}

	if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) {
		return -1;
	}

	if (status == FAILED_TO_CREATE_STDOUT) {
		fatal("Could not create %s (permission denied?)", path_stdout);
	} else if (status == FAILED_TO_CREATE_STDERR) {
		fatal("Could not create %s (permission denied?)", path_stderr);
	}

	return WEXITSTATUS(status);
}
Example #2
0
/*
 * Release the lockfile for the given path. Assumes that we are the legitimate
 * owner.
 */
void
lockfile_release(const char *path)
{
	char *lockfile = format("%s.lock", path);
	cc_log("Releasing lock %s", lockfile);
	tmp_unlink(lockfile);
	free(lockfile);
}
Example #3
0
/*
  execute a compiler backend, capturing all output to the given paths
  the full path to the compiler to run is in argv[0]
*/
int
execute(char **argv, const char *path_stdout, const char *path_stderr)
{
	pid_t pid;
	int status, fd_out, fd_err;

	cc_log_argv("Executing ", argv);

	tmp_unlink(path_stdout);
	fd_out = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
	if (fd_out == -1) {
		fatal("Error creating %s: %s", path_stdout, strerror(errno));
	}

	tmp_unlink(path_stderr);
	fd_err = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
	if (fd_err == -1) {
		fatal("Error creating %s: %s", path_stderr, strerror(errno));
	}

	pid = fork();
	if (pid == -1) fatal("Failed to fork: %s", strerror(errno));

	if (pid == 0) {
		/* Child. */
		dup2(fd_out, 1);
		close(fd_out);
		dup2(fd_err, 2);
		close(fd_err);
		exit(execv(argv[0], argv));
	}

	close(fd_out);
	close(fd_err);

	if (waitpid(pid, &status, 0) != pid) {
		fatal("waitpid failed: %s", strerror(errno));
	}

	if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) {
		return -1;
	}

	return WEXITSTATUS(status);
}
Example #4
0
/*
  execute a compiler backend, capturing all output to the given paths
  the full path to the compiler to run is in argv[0]
*/
int
execute(char **argv, const char *path_stdout, const char *path_stderr)
{
	pid_t pid;
	int status;

	cc_log_argv("Executing ", argv);

	pid = fork();
	if (pid == -1) fatal("Failed to fork");

	if (pid == 0) {
		int fd;

		tmp_unlink(path_stdout);
		fd = open(path_stdout, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
		if (fd == -1) {
			exit(1);
		}
		dup2(fd, 1);
		close(fd);

		tmp_unlink(path_stderr);
		fd = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
		if (fd == -1) {
			exit(1);
		}
		dup2(fd, 2);
		close(fd);

		exit(execv(argv[0], argv));
	}

	if (waitpid(pid, &status, 0) != pid) {
		fatal("waitpid failed");
	}

	if (WEXITSTATUS(status) == 0 && WIFSIGNALED(status)) {
		return -1;
	}

	return WEXITSTATUS(status);
}