Exemple #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);
}
Exemple #2
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);
}
Exemple #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;

	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);
}
Exemple #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, int fd_out, int fd_err, pid_t *pid)
{
	int status;

	cc_log_argv("Executing ", argv);

	block_signals();
	*pid = fork();
	unblock_signals();

	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);
		x_exit(execv(argv[0], argv));
	}

	close(fd_out);
	close(fd_err);

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

	block_signals();
	*pid = 0;
	unblock_signals();

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

	return WEXITSTATUS(status);
}
Exemple #5
0
bool
hash_command_output(struct mdfour *hash, const char *command,
                    const char *compiler)
{
#ifdef _WIN32
	SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
	HANDLE pipe_out[2];
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	DWORD exitcode;
	bool cmd = false;
	char *sh = NULL;
	char *win32args;
	char *path;
	BOOL ret;
	bool ok;
	int fd;
#else
	pid_t pid;
	int pipefd[2];
#endif

#ifdef _WIN32
	/* trim leading space */
	while (isspace(*command)) {
		command++;
	}
	/* add "echo" command */
	if (str_startswith(command, "echo")) {
		command = format("cmd.exe /c \"%s\"", command);
		cmd = true;
	} else if (str_startswith(command,
	                          "%compiler%") && str_eq(compiler, "echo")) {
		command = format("cmd.exe /c \"%s%s\"", compiler, command + 10);
		cmd = true;
	} else {
		command = x_strdup(command);
	}
#endif
	struct args *args = args_init_from_string(command);
	int i;
	for (i = 0; i < args->argc; i++) {
		if (str_eq(args->argv[i], "%compiler%")) {
			args_set(args, i, compiler);
		}
	}
	cc_log_argv("Executing compiler check command ", args->argv);

#ifdef _WIN32
	memset(&pi, 0x00, sizeof(pi));
	memset(&si, 0x00, sizeof(si));

	path = find_executable(args->argv[0], NULL);
	if (!path) {
		path = args->argv[0];
	}
	sh = win32getshell(path);
	if (sh) {
		path = sh;
	}

	si.cb = sizeof(STARTUPINFO);
	CreatePipe(&pipe_out[0], &pipe_out[1], &sa, 0);
	SetHandleInformation(pipe_out[0], HANDLE_FLAG_INHERIT, 0);
	si.hStdOutput = pipe_out[1];
	si.hStdError = pipe_out[1];
	si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
	si.dwFlags = STARTF_USESTDHANDLES;
	if (!cmd) {
		win32args = win32argvtos(sh, args->argv);
	} else {
		win32args = (char *) command;  /* quoted */
	}
	ret = CreateProcess(path, win32args, NULL, NULL, 1, 0, NULL, NULL, &si, &pi);
	CloseHandle(pipe_out[1]);
	args_free(args);
	free(win32args);
	if (cmd) {
		free((char *) command);  /* original argument was replaced above */
	}
	if (ret == 0) {
		stats_update(STATS_COMPCHECK);
		return false;
	}
	fd = _open_osfhandle((intptr_t) pipe_out[0], O_BINARY);
	ok = hash_fd(hash, fd);
	if (!ok) {
		cc_log("Error hashing compiler check command output: %s", strerror(errno));
		stats_update(STATS_COMPCHECK);
	}
	WaitForSingleObject(pi.hProcess, INFINITE);
	GetExitCodeProcess(pi.hProcess, &exitcode);
	CloseHandle(pipe_out[0]);
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);
	if (exitcode != 0) {
		cc_log("Compiler check command returned %d", (int) exitcode);
		stats_update(STATS_COMPCHECK);
		return false;
	}
	return ok;
#else
	if (pipe(pipefd) == -1) {
		fatal("pipe failed");
	}
	pid = fork();
	if (pid == -1) {
		fatal("fork failed");
	}

	if (pid == 0) {
		/* Child. */
		close(pipefd[0]);
		close(0);
		dup2(pipefd[1], 1);
		dup2(pipefd[1], 2);
		_exit(execvp(args->argv[0], args->argv));
		return false; /* Never reached. */
	} else {
		/* Parent. */
		int status;
		bool ok;
		args_free(args);
		close(pipefd[1]);
		ok = hash_fd(hash, pipefd[0]);
		if (!ok) {
			cc_log("Error hashing compiler check command output: %s", strerror(errno));
			stats_update(STATS_COMPCHECK);
		}
		close(pipefd[0]);
		if (waitpid(pid, &status, 0) != pid) {
			cc_log("waitpid failed");
			return false;
		}
		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
			cc_log("Compiler check command returned %d", WEXITSTATUS(status));
			stats_update(STATS_COMPCHECK);
			return false;
		}
		return ok;
	}
#endif
}