diff lib/swig/swigwin-2.0.11/CCache/execute.c @ 1899:b3009adc0e2f

Adding swig, gitignore, hgignore
author Nomad
date Mon, 21 Oct 2013 10:42:27 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/swig/swigwin-2.0.11/CCache/execute.c	Mon Oct 21 10:42:27 2013 +0200
@@ -0,0 +1,286 @@
+/*
+   Copyright (C) Andrew Tridgell 2002
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "ccache.h"
+
+#ifdef _WIN32
+char *argvtos(char **argv)
+{
+	int i, len;
+	char *ptr, *str;
+
+	for (i = 0, len = 0; argv[i]; i++) {
+		len += strlen(argv[i]) + 3;
+	}
+
+	str = ptr = (char *)malloc(len + 1);
+	if (str == NULL)
+		return NULL;
+
+	for (i = 0; argv[i]; i++) {
+		len = strlen(argv[i]);
+		*ptr++ = '"';
+		memcpy(ptr, argv[i], len);
+		ptr += len;
+		*ptr++ = '"';
+		*ptr++ = ' ';
+	}
+	*ptr = 0;
+
+	return str;
+}
+#endif
+
+/*
+  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
+
+#if 1
+	PROCESS_INFORMATION pinfo; 
+	STARTUPINFO sinfo;
+	BOOL ret; 
+	DWORD exitcode;
+	char *args;
+	HANDLE fd_out, fd_err;
+	SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
+
+	/* TODO: needs moving after possible exit() below, but before stdout is redirected */
+	if (ccache_verbose) {
+		display_execute_args(argv);
+	}
+
+	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 /* possibly slightly faster */
+	/* needs fixing to quote commandline options to handle spaces in CCACHE_DIR etc */
+	int   status = -2;
+	int   fd, std_od = -1, std_ed = -1;
+
+	/* TODO: needs moving after possible exit() below, but before stdout is redirected */
+	if (ccache_verbose) {
+		display_execute_args(argv);
+	}
+
+	unlink(path_stdout);
+	std_od = _dup(1);
+	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);
+	std_ed = _dup(2);
+	if (fd == -1) {
+		exit(STATUS_NOCACHE);
+	}
+	_dup2(fd, 2);
+	_close(fd);
+
+	/* Spawn process (_exec* familly doesn't return) */
+	status = _spawnv(_P_WAIT, argv[0], (const char **)argv);
+
+	/* Restore descriptors */
+	if (std_od != -1) _dup2(std_od, 1);
+	if (std_ed != -1) _dup2(std_ed, 2);
+	_flushall();
+
+	return (status>0);
+
+#endif
+
+#else
+	pid_t pid;
+	int status;
+
+	pid = fork();
+	if (pid == -1) fatal("Failed to fork");
+	
+	if (pid == 0) {
+		int fd;
+
+		/* TODO: needs moving after possible exit() below, but before stdout is redirected */
+		if (ccache_verbose) {
+			display_execute_args(argv);
+		}
+
+		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
+}
+
+
+/*
+  find an executable by name in $PATH. Exclude any that are links to exclude_name 
+*/
+char *find_executable(const char *name, const char *exclude_name)
+{
+#if _WIN32
+	(void)exclude_name;
+	DWORD ret;
+	char namebuf[MAX_PATH];
+
+	ret = SearchPathA(getenv("CCACHE_PATH"), name, ".exe",
+			  sizeof(namebuf), namebuf, NULL);
+	if (ret != 0) {
+		return x_strdup(namebuf);
+	}
+
+	return NULL;
+#else
+	char *path;
+	char *tok;
+	struct stat st1, st2;
+
+	if (*name == '/') {
+		return x_strdup(name);
+	}
+
+	path = getenv("CCACHE_PATH");
+	if (!path) {
+		path = getenv("PATH");
+	}
+	if (!path) {
+		cc_log("no PATH variable!?\n");
+		stats_update(STATS_ENVIRONMMENT);
+		return NULL;
+	}
+
+	path = x_strdup(path);
+	
+	/* search the path looking for the first compiler of the right name
+	   that isn't us */
+	for (tok=strtok(path,":"); tok; tok = strtok(NULL, ":")) {
+		char *fname;
+		x_asprintf(&fname, "%s/%s", tok, name);
+		/* look for a normal executable file */
+		if (access(fname, X_OK) == 0 &&
+		    lstat(fname, &st1) == 0 &&
+		    stat(fname, &st2) == 0 &&
+		    S_ISREG(st2.st_mode)) {
+			/* if its a symlink then ensure it doesn't
+                           point at something called exclude_name */
+			if (S_ISLNK(st1.st_mode)) {
+				char *buf = x_realpath(fname);
+				if (buf) {
+					char *p = str_basename(buf);
+					if (strcmp(p, exclude_name) == 0) {
+						/* its a link to "ccache" ! */
+						free(p);
+						free(buf);
+						continue;
+					}
+					free(buf);
+					free(p);
+				}
+			}
+
+			/* found it! */
+			free(path);
+			return fname;
+		}
+		free(fname);
+	}
+
+	return NULL;
+#endif
+}
+
+void display_execute_args(char **argv)
+{
+	if (argv) {
+		printf("ccache executing: ");
+		while (*argv) {
+			printf("%s ", *argv);
+			++argv;
+		}
+		printf("\n");
+		fflush(stdout);
+	}
+}