Beispiel #1
0
static void build_path(const char *dir, int pid, const char *ext, char *path)
{
	assert(path);
	int len = sprintf(path, "%s/diagonal%d.%s", dir, (int)pid, ext);
	if (len < 0) diag_fatal("fail to build path");
	if (PATH_LENGTH <= len) diag_fatal("exceed PATH_LENGTH");
}
Beispiel #2
0
hash_table *
hash_table_new(hash_func hash_f, hash_comp hash_c, hash_free hash_fr)
{
	hash_table *hash_t;

	hash_t = (struct _hash_table *) diag_malloc(sizeof(hash_table));
	if (hash_t == NULL)
		diag_fatal("Unable to allocate memory\n");

	hash_t->size = HASH_TABLE_MIN_SIZE;
	hash_t->nnodes = 0;
	if (hash_f)
		hash_t->hash_func = default_hash_func;
	else
		hash_t->hash_func = hash_f;
	if (hash_c)
		hash_t->hash_comp = default_compare_func;
	else
		hash_t->hash_comp = hash_c;
	hash_t->hash_free = hash_fr;
	hash_t->nodes = (hash_node **) diag_malloc(sizeof(hash_node *) * hash_t->size);
	if (hash_t->nodes == NULL)
	{
		diag_free(hash_t);
		diag_fatal("Unable to allocate memory\n");
	}
	memset(hash_t->nodes, 0, sizeof(hash_node *) * hash_t->size);

	return hash_t;
}
Beispiel #3
0
intptr_t diag_list_ref(const struct diag_pair *list, size_t i)
{
	if (!list) diag_fatal("list is null");
	while (i-- > 0) {
		list = (const struct diag_pair *)list->cdr;
		if (!list) diag_fatal("exceed list length");
	}
	return list->car;
}
Beispiel #4
0
void diag_process_wait(struct diag_process *process)
{
	assert(process);

	int status;
	pid_t pid = waitpid((pid_t)process->pid, &status,
#ifdef WCONTINUED
			    WCONTINUED|
#endif
			    WUNTRACED);
	if (pid == (pid_t)0) {
		assert(0);
	} else if (pid == (pid_t)-1) {
		perror(NULL);
		diag_fatal("failed to wait process: %d", (int)process->pid);
	}
	if (WIFEXITED(status)) {
		process->status = WEXITSTATUS(status);
	} else if (WIFSIGNALED(status)) {
		process->status = -1;
	} else if (WIFSTOPPED(status)) {

#ifdef WIFCONTINUED
	} else if (WIFCONTINUED(status)) {

#endif
	}
}
Beispiel #5
0
long
hash_table_replace(hash_table * hash_t, void *key, void *value)
{
	hash_node **node;
	hash_node *pnode;
	long hash_val;

	node = hash_table_lookup_node(hash_t, key);

	if (node)
		(*node)->value = value;
	else
	{
		*node = (hash_node *) diag_malloc(sizeof(hash_node));
		if (*node == NULL)
			diag_fatal("Unable to allocate memory\n");
		(*node)->key = key;
		(*node)->value = value;
		hash_val = (*hash_t->hash_func) ((*node)->key, hash_t->size);
		(*node)->next = hash_t->nodes[hash_val];
		hash_t->nodes[hash_val] = (*node);
		hash_t->nnodes++;
		pnode = *node;
		hash_table_resize(hash_t);
	}

	return (long) pnode;
}
Beispiel #6
0
/*
 * TODO: n should exceed MAXIMUM_WAIT_OBJECTS
 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx
 */
int diag_wait_agent(int n, const intptr_t *agents, int *code)
{
	assert(n > 0);
	assert(agents);

	if (n > MAXIMUM_WAIT_OBJECTS) {
		diag_error("number of agents exceeds MAXIMUM_WAIT_OBJECTS");
		return -1;
	}
	DWORD r = WaitForMultipleObjects((DWORD)n,
					 (const HANDLE *)agents,
					 FALSE,
					 INFINITE);
	assert(r != WAIT_TIMEOUT);
	if (r == WAIT_FAILED) {
		diag_error("failed to wait agent: %x",
			   (unsigned int)GetLastError());
		return -1;
	}
	assert(WAIT_OBJECT_0 == 0);
	if (WAIT_OBJECT_0 + (DWORD)n <= r) {
		diag_fatal("failed to wait agent");
	}
	DWORD i = r - WAIT_OBJECT_0;
	intptr_t p = agents[i];
	if (code) {
		DWORD c = 0;
		if (GetExitCodeProcess((HANDLE)p, &c) == 0) {
			diag_fatal("failed to get exit code: %x",
				   (unsigned int)GetLastError());
		}
		*code = (int)c;
	}
	if (CloseHandle((HANDLE)p) == 0) {
		diag_error("failed to close handle");
	}
	return (int)i;
}
Beispiel #7
0
struct diag_command *diag_command_new(char **argv,
				      const char *dir,
				      const char *in,
				      const char *out,
				      const char *err)
{
	struct diag_command *command = diag_malloc(sizeof(*command));
	size_t argc;
	for (argc = 0; argv[argc]; argc++) ;
	command->argv = diag_calloc(argc + 1, sizeof(char *));
	size_t i;
	for (i = 0; i < argc; i++) {
		command->argv[i] = diag_strdup(argv[i]);
	}
	command->argv[argc] = NULL; /* NULL-terminated */
	command->file = argv[0];

	if (dir) {
		command->dir = diag_strdup(dir);
	} else {
		command->dir = diag_malloc(PATH_LENGTH);
		char *p;
#if defined(_WIN32) && defined(__MINGW32__)
		p = _getcwd(command->dir, PATH_LENGTH);
#elif defined(HAVE_UNISTD_H)
		p = getcwd(command->dir, PATH_LENGTH);
#endif
		if (!p) {
			perror(NULL);
			diag_fatal("failed to get current working directory");
		}
	}

	if (in) {
		command->in = diag_strdup(in);
	} else {
		command->in = NULL;
	}
	if (out) {
		command->out = diag_strdup(out);
	} else {
		command->out = NULL;
	}
	if (err) {
		command->err = diag_strdup(err);
	} else {
		command->err = NULL;
	}
	return command;
}
Beispiel #8
0
intptr_t diag_run_agent(char **argv)
{
	SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(sa);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	STARTUPINFO si;
	GetStartupInfo(&si);
	si.dwFlags |= STARTF_USESTDHANDLES;
	si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
	si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

	char *line = diag_get_command_line(argv);

	BOOL b = CreateProcess(NULL,
			       line,
			       NULL,
			       NULL,
			       TRUE,
			       0,
			       NULL,
			       NULL,
			       &si,
			       &pi);
	if (!b) {
		diag_fatal("could not create process: %s: 0x%x",
			   line,
			   (unsigned int)GetLastError());
	}

	/* We do not want WaitForInputIdle() because there is no interaction
	   between the parent process and this child */

	diag_free(line);
	CloseHandle(pi.hThread);
	return (intptr_t)pi.hProcess;
}
Beispiel #9
0
long
hash_table_insert(hash_table * hash_t, void *key, void *value)
{
	hash_node **node;
	hash_node *pnode;

	node = hash_table_lookup_node(hash_t, key);

	if (!*node)
	{

		*node = (hash_node *) diag_malloc(sizeof(hash_node));
		if (*node == NULL)
			diag_fatal("Unable to allocate memory\n");
		(*node)->key = key;
		(*node)->value = value;
		(*node)->next = NULL;
		hash_t->nnodes++;
		pnode = *node;
		hash_table_resize(hash_t);
	}

	return (long) pnode;
}
Beispiel #10
0
int main(int argc, char *argv[])
{
	int c;
	int n = 0;
	int r = EXIT_FAILURE;
	char *in = NULL;

	diag_init();

	while ( (c = getopt(argc, argv, "+Vhi:n:")) >=0) {
		switch (c) {
		case 'V':
			diag_print_version();
			exit(EXIT_SUCCESS);
			break;
		case 'h':
			usage();
			exit(EXIT_SUCCESS);
			break;
		case 'i':
			in = optarg;
			break;
		case 'n':
			n = atoi(optarg);
			if (n < 0) {
				diag_fatal("non-negative integer expected, but %d", n);
			} else if (n == 0) {
				exit(EXIT_SUCCESS);
			}
			break;
		case ':':
		case '?':
			usage();
			exit(EXIT_FAILURE);
			break;
		}
	}
	if (!argv[optind]) {
		usage();
		exit(EXIT_FAILURE);
	}
	if (n == 0) {
		diag_fatal("please specify the number with the -n option");
	}

	char *tfin = NULL;
	if (!in) {
		struct diag_temporary_file *tf = diag_temporary_file_new();
		if (!tf) {
			return EXIT_FAILURE;
		}
		tfin = diag_strdup(tf->path);
		struct diag_port *ip = diag_port_new_stdin();
		assert(ip);
		ssize_t s = diag_port_copy(ip, tf->port);
		diag_port_destroy(ip);
		diag_temporary_file_destroy(tf);
		if (s < 0) {
			assert(tfin);
			diag_remove(tfin);
			diag_free(tfin);
			return EXIT_FAILURE;
		}
	}

	int i = 0;
	char *file = in ? in : tfin;
	struct diag_command *cmd;
 run:
	cmd = diag_command_new(argv + optind, NULL, file, NULL, NULL);
	if (!cmd) {
		goto done;
	}
	struct diag_process *p = diag_run_program(cmd);
	if (!p) {
		goto done;
	}
	diag_process_wait(p);
	int status = p->status;
	diag_process_destroy(p);
	if (status != 0) {
		r = status;
		goto done;
	}

	assert(cmd->err);
	diag_remove(cmd->err);

	if (i) {
		diag_remove(file);
		diag_free(file);
	} else if (tfin) {
		diag_remove(tfin);
		diag_free(tfin);
		tfin = NULL;
	}

	if (++i < n) {
		file = diag_strdup(cmd->out);
		diag_command_destroy(cmd);
		goto run;
	}

	struct diag_port *ip = diag_port_new_path(cmd->out, "rb");
	if (!ip) {
		goto done;
	}
	struct diag_port *op = diag_port_new_stdout();
	assert(op);
	ssize_t s = diag_port_copy(ip, op);
	diag_port_destroy(op);
	diag_port_destroy(ip);
	if (s < 0) {
		goto done;
	}

	diag_remove(cmd->out);
	r = EXIT_SUCCESS;

 done:
	diag_command_destroy(cmd);
	if (tfin) {
		diag_remove(tfin);
		diag_free(tfin);
	}
	return r;
}