Exemplo n.º 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)
{
#ifdef _WIN32
	PROCESS_INFORMATION pinfo; 
	STARTUPINFO sinfo;
	BOOL ret; 
	DWORD exitcode;
	char *args;
	HANDLE fd_out, fd_err;
	SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};

	fd_out = CreateFile(path_stdout, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
                            FILE_ATTRIBUTE_NORMAL, NULL);
	if (fd_out == INVALID_HANDLE_VALUE) {
		return STATUS_NOCACHE;
	}

	fd_err = CreateFile(path_stderr, GENERIC_WRITE, 0, &sa, CREATE_ALWAYS,
                            FILE_ATTRIBUTE_NORMAL, NULL);
	if (fd_err == INVALID_HANDLE_VALUE) {
		return STATUS_NOCACHE;
	}
   
	ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION));
	ZeroMemory(&sinfo, sizeof(STARTUPINFO));

	sinfo.cb = sizeof(STARTUPINFO); 
	sinfo.hStdError = fd_err;
	sinfo.hStdOutput = fd_out;
	sinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
	sinfo.dwFlags |= STARTF_USESTDHANDLES;
 
	args = argvtos(argv);

	ret = CreateProcessA(argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL,
	                     &sinfo, &pinfo);

	free(args);
	CloseHandle(fd_out);
	CloseHandle(fd_err);

	if (ret == 0)
		return -1;

	WaitForSingleObject(pinfo.hProcess, INFINITE);
	GetExitCodeProcess(pinfo.hProcess, &exitcode);
	CloseHandle(pinfo.hProcess);
	CloseHandle(pinfo.hThread);

	return exitcode;
#else
	pid_t pid;
	int status;

	pid = fork();
	if (pid == -1) fatal("Failed to fork");
	
	if (pid == 0) {
		int fd;

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

		unlink(path_stderr);
		fd = open(path_stderr, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL|O_BINARY, 0666);
		if (fd == -1) {
			exit(STATUS_NOCACHE);
		}
		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);
#endif
}
Exemplo n.º 2
0
/*
  something went badly wrong - just execute the real compiler
*/
static void failed(void)
{
	char *e;

	/* delete intermediate pre-processor file if needed */
	if (i_tmpfile) {
		if (!direct_i_file) {
			unlink(i_tmpfile);
		}
		free(i_tmpfile);
		i_tmpfile = NULL;
	}

	/* delete the cpp stderr file if necessary */
	if (cpp_stderr) {
		unlink(cpp_stderr);
		free(cpp_stderr);
		cpp_stderr = NULL;
	}

	/* strip any local args */
	args_strip(orig_args, "--ccache-");

	if ((e=getenv("CCACHE_PREFIX"))) {
		char *p = find_executable(e, MYNAME);
		if (!p) {
			cc_log("could not find executable (%s)\n", e);
			perror(e);
			exit(1);
		}
		args_add_prefix(orig_args, p);
	}

	if (ccache_verbose) {
		display_execute_args(orig_args->argv);
	}

	if (swig) {
		putenv("CCACHE_OUTFILES");
	}

#ifndef _WIN32
	execv(orig_args->argv[0], orig_args->argv);
	cc_log("execv returned (%s)!\n", strerror(errno));
	perror(orig_args->argv[0]);
	exit(1);
#else
	/* execv on Windows causes the 'non-regular' testcase to fail, so use Win32 API instead */
	{
		PROCESS_INFORMATION pinfo; 
		STARTUPINFO sinfo;
		BOOL ret; 
		DWORD exitcode;
		char *args;

		ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION));
		ZeroMemory(&sinfo, sizeof(STARTUPINFO));
		sinfo.cb = sizeof(STARTUPINFO); 
		args = argvtos(orig_args->argv);
		ret = CreateProcessA(orig_args->argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL,
				     &sinfo, &pinfo);
		if (!ret) {
			exitcode = 1;
			cc_log("CreateProcessA failed starting %s\n", orig_args->argv[0]);
			perror_win32(orig_args->argv[0]);
		} else {
			WaitForSingleObject(pinfo.hProcess, INFINITE);
			GetExitCodeProcess(pinfo.hProcess, &exitcode);
			CloseHandle(pinfo.hProcess);
			CloseHandle(pinfo.hThread);
		}
		free(args);
		exit(exitcode);
	}
#endif
}