Beispiel #1
0
int main(int argc, char **argv)
{
	int ret, r2;

	runcmd_init();
	t_set_colors(0);
	t_start("exec output comparison");
	{
		int i;
		char *out = calloc(1, BUF_SIZE);
		for (i = 0; cases[i].input != NULL; i++) {
			memset(out, 0, BUF_SIZE);
			int pfd[2] = {-1, -1}, pfderr[2] = {-1, -1};
			int fd;
			char *cmd;
			asprintf(&cmd, "/bin/echo -n %s", cases[i].input);
			fd = runcmd_open(cmd, pfd, pfderr, NULL);
			read(pfd[0], out, BUF_SIZE);
			ok_str(cases[i].output, out, "Echoing a command should give expected output");
			close(pfd[0]);
			close(pfderr[0]);
			close(fd);
		}
	}
	ret = t_end();
	t_reset();
	t_start("anomaly detection");
	{
		int i;
		for (i = 0; anomaly[i].cmd; i++) {
			int out_argc;
			char *out_argv[256];
			int result = runcmd_cmd2strv(anomaly[i].cmd, &out_argc, out_argv);
			ok_int(result, anomaly[i].ret, anomaly[i].cmd);
		}
	}
	r2 = t_end();
	ret = r2 ? r2 : ret;
	t_reset();
	t_start("argument splitting");
	{
		int i;
		for (i = 0; parse_case[i].cmd; i++) {
			int x, out_argc;
			char *out_argv[256];
			int result = runcmd_cmd2strv(parse_case[i].cmd, &out_argc, out_argv);
			out_argv[out_argc] = NULL;
			ok_int(result, 0, parse_case[i].cmd);
			ok_int(out_argc, parse_case[i].argc_exp, parse_case[i].cmd);
			for (x = 0; x < parse_case[x].argc_exp && out_argv[x]; x++) {
				ok_str(parse_case[i].argv_exp[x], out_argv[x], "argv comparison test");
			}
		}
	}

	r2 = t_end();
	return r2 ? r2 : ret;
}
int main(int argc, char **argv)
{
	int ret, r2;

	runcmd_init();
	t_set_colors(0);
	t_start("exec output comparison");
	{
		int i;
		char *out = calloc(1, BUF_SIZE);
		for (i = 0; cases[i].input != NULL; i++) {
			memset(out, 0, BUF_SIZE);
			int pfd[2] = {-1, -1}, pfderr[2] = {-1, -1};
			/* We need a stub iobregarg since runcmd_open()'s prototype
			 * declares it attribute non-null. */
			int stub_iobregarg = 0;
			int fd;
			char *cmd;
			asprintf(&cmd, ECHO_COMMAND " -n %s", cases[i].input);
			fd = runcmd_open(cmd, pfd, pfderr, NULL, stub_iobreg, &stub_iobregarg);
			free(cmd);
			read(pfd[0], out, BUF_SIZE);
			ok_str(cases[i].output, out, "Echoing a command should give expected output");
			close(pfd[0]);
			close(pfderr[0]);
			close(fd);
		}
		free(out);
	}
	ret = t_end();
	t_reset();
	t_start("anomaly detection");
	{
		int i;
		for (i = 0; anomaly[i].cmd; i++) {
			int out_argc;
			char *out_argv[256];
			int result = runcmd_cmd2strv(anomaly[i].cmd, &out_argc, out_argv);
			ok_int(result, anomaly[i].ret, anomaly[i].cmd);
			if (out_argv[0]) free(out_argv[0]);
		}
	}
	r2 = t_end();
	ret = r2 ? r2 : ret;
	t_reset();
	t_start("argument splitting");
	{
		int i;
		for (i = 0; parse_case[i].cmd; i++) {
			int x, out_argc;
			char *out_argv[256];
			int result = runcmd_cmd2strv(parse_case[i].cmd, &out_argc, out_argv);
			/*out_argv[out_argc] = NULL;*//* This must be NULL terminated already. */
			ok_int(result, parse_case[i].ret, parse_case[i].cmd);
			ok_int(out_argc, parse_case[i].argc_exp, parse_case[i].cmd);
			for (x = 0; x < parse_case[x].argc_exp && out_argv[x]; x++) {
				ok_str(parse_case[i].argv_exp[x], out_argv[x], "argv comparison test");
			}
			if (out_argv[0]) free(out_argv[0]);
		}
	}

	r2 = t_end();
	return r2 ? r2 : ret;
}
Beispiel #3
0
/* Start running a command */
int runcmd_open(const char *cmd, int *pfd, int *pfderr, char **env)
{
	char **argv = NULL;
	int cmd2strv_errors, argc = 0;
	size_t cmdlen;
	pid_t pid;

	int i = 0;

	if(!pids)
		runcmd_init();

	/* if no command was passed, return with no error */
	if (!cmd || !*cmd)
		return RUNCMD_EINVAL;

	cmdlen = strlen(cmd);
	argv = calloc((cmdlen / 2) + 5, sizeof(char *));
	if (!argv)
		return RUNCMD_EALLOC;

	cmd2strv_errors = runcmd_cmd2strv(cmd, &argc, argv);
	if (cmd2strv_errors) {
		/*
		 * if there are complications, we fall back to running
		 * the command via the shell
		 */
		free(argv[0]);
		argv[0] = "/bin/sh";
		argv[1] = "-c";
		argv[2] = strdup(cmd);
		if (!argv[2]) {
			free(argv);
			return RUNCMD_EALLOC;
		}
		argv[3] = NULL;
	}

	if (pipe(pfd) < 0) {
		if (!cmd2strv_errors)
			free(argv[0]);
		else
			free(argv[2]);
		free(argv);
		return RUNCMD_ECMD;
	}
	if (pipe(pfderr) < 0) {
		if (!cmd2strv_errors)
			free(argv[0]);
		else
			free(argv[2]);
		free(argv);
		close(pfd[0]);
		close(pfd[1]);
		return RUNCMD_EFD;
	}
	pid = fork();
	if (pid < 0) {
		if (!cmd2strv_errors)
			free(argv[0]);
		else
			free(argv[2]);
		free(argv);
		close(pfd[0]);
		close(pfd[1]);
		close(pfderr[0]);
		close(pfderr[1]);
		return RUNCMD_EFORK; /* errno set by the failing function */
	}

	/* child runs excevp() and _exit. */
	if (pid == 0) {
		close (pfd[0]);
		if (pfd[1] != STDOUT_FILENO) {
			dup2 (pfd[1], STDOUT_FILENO);
			close (pfd[1]);
		}
		close (pfderr[0]);
		if (pfderr[1] != STDERR_FILENO) {
			dup2 (pfderr[1], STDERR_FILENO);
			close (pfderr[1]);
		}

		/* close all descriptors in pids[]
		 * This is executed in a separate address space (pure child),
		 * so we don't have to worry about async safety */
		for (i = 0; i < maxfd; i++)
			if(pids[i] > 0)
				close (i);

		i = execvp(argv[0], argv);
		fprintf(stderr, "execvp(%s, ...) failed. errno is %d: %s\n", argv[0], errno, strerror(errno));
		if (!cmd2strv_errors)
			free(argv[0]);
		else
			free(argv[2]);
		_exit (errno);
	}

	/* parent picks up execution here */
	/*
	 * close childs file descriptors in our address space and
	 * release the memory we used that won't get passed to the
	 * caller.
	 */
	close(pfd[1]);
	close(pfderr[1]);
	if (!cmd2strv_errors)
		free(argv[0]);
	else
		free(argv[2]);
	free(argv);

	/* tag our file's entry in the pid-list and return it */
	pids[pfd[0]] = pid;

	return pfd[0];
}