Esempio n. 1
0
int main(int argc, char **argv, char **envp)
{
	char *p_argv[] = {0, 0, 0};
	char *p_envp[] = {"LD_LIBRARY_PATH=/lib", 0};
	#define FILENAME "/bin/hello"
	//#define FILENAME "/bin/hello-sym"
	char filename[] = FILENAME;
	#if 0
	/* try some bad combos */
	int pid = sys_proc_create("garbagexxx");
	printf("Garbage pid result: %d\n", pid);

	error_t err = sys_proc_run(2342);
	printf("sys_proc_run(2342) error: %e\n", err);

	err = sys_proc_run(-1);
	cprintf("sys_proc_run(-1) error: %e\n", err);
	#endif

	#define NUM_KIDS 5
	int child_pid[NUM_KIDS];
	#if 0
	printf("U: attempting to create hello(s)\n");
	for (int i = 0; i < NUM_KIDS; i++)
		child_pid[i] = sys_proc_create("roslib_hello");

	for (int i = 0; i < NUM_KIDS; i++) {
		cprintf("U: attempting to run hello (pid: %d)\n", child_pid[i]);
		sys_proc_run(child_pid[i]);
	}
	#endif
	printf("U: attempting to create and run hello\n");
	p_argv[0] = filename;
	printf("SPAWN, I'm pid %d, filename %s\n", getpid(), filename);
	child_pid[0] = sys_proc_create(FILENAME, strlen(FILENAME), p_argv, p_envp);
	if (child_pid[0] <= 0)
		printf("Failed to create the child\n");
	else
		if (sys_proc_run(child_pid[0]) < 0)
			printf("Failed to run the child (pid %d)\n", child_pid[0]);

	#if 0
	printf("U: attempting to create and run another hello\n");
	child_pid[1] = sys_proc_create(FILENAME, strlen(FILENAME), 0, 0);
	if (child_pid[1] <= 0)
		perror("");
	else
		if (sys_proc_run(child_pid[1]) < 0)
			perror("");
	#endif
	return 0;
}
Esempio n. 2
0
static void run_process_and_wait(int argc, const char * const *argv,
								 const struct core_set *cores)
{
	int pid, status;
	size_t max_cores = ros_total_cores();
	struct core_set pvcores;

	pid = sys_proc_create(argv[0], strlen(argv[0]), argv, NULL, 0);
	if (pid < 0) {
		perror(argv[0]);
		exit(1);
	}

	ros_get_low_latency_core_set(&pvcores);
	ros_not_core_set(&pvcores);
	ros_and_core_sets(&pvcores, cores);
	for (size_t i = 0; i < max_cores; i++) {
		if (ros_get_bit(&pvcores, i)) {
			if (sys_provision(pid, RES_CORES, i)) {
				fprintf(stderr,
						"Unable to provision CPU %lu to PID %d: cmd='%s'\n",
						i, pid, argv[0]);
				exit(1);
			}
		}
	}

	sys_proc_run(pid);
	waitpid(pid, &status, 0);
}
Esempio n. 3
0
/* Creates a child process for program @exe, with args and envs.  Will attempt
 * to look in /bin/ if the initial lookup fails, and will invoke sh to handle
 * non-elfs.  Returns the child's PID on success, -1 o/w. */
pid_t create_child(const char *exe, int argc, char *const argv[],
                   char *const envp[])
{
	pid_t kid;
	char *path_exe;
	char **sh_argv;
	const char *sh_path = "/bin/sh";

	kid = sys_proc_create(exe, strlen(exe), argv, envp, 0);
	if (kid > 0)
		return kid;

	/* Here's how we avoid infinite recursion.  We can only have ENOENT the
	 * first time through without bailing out, since all errno paths set exe to
	 * begin with '/'.  That includes calls from ENOEXEC, since sh_path begins
	 * with /.  To avoid repeated calls to ENOEXEC, we just look for sh_path as
	 * the exe, so if we have consecutive ENOEXECs, we'll bail out. */
	switch (errno) {
	case ENOENT:
		if (exe[0] == '/')
			return -1;
		path_exe = malloc(MAX_PATH_LEN);
		if (!path_exe)
			return -1;
		/* Our 'PATH' is only /bin. */
		snprintf(path_exe, MAX_PATH_LEN, "/bin/%s", exe);
		path_exe[MAX_PATH_LEN - 1] = 0;
		kid = create_child(path_exe, argc, argv, envp);
		free(path_exe);
		break;
	case ENOEXEC:
		/* In case someone replaces /bin/sh with a non-elf. */
		if (!strcmp(sh_path, exe))
			return -1;
		/* We want enough space for the original argv, plus one entry at the
		 * front for sh_path.  When we grab the original argv, we also need the
		 * trailing NULL, which is at argv[argc].  That means we really want
		 * argc + 1 entries from argv. */
		sh_argv = malloc(sizeof(char *) * (argc + 2));
		if (!sh_argv)
			return -1;
		memcpy(&sh_argv[1], argv, sizeof(char *) * (argc + 1));
		sh_argv[0] = (char*)sh_path;
		/* Replace the original argv[0] with the path to exe, which might have
		 * been edited to include /bin/ */
		sh_argv[1] = (char*)exe;
		kid = create_child(sh_path, argc + 1, sh_argv, envp);
		free(sh_argv);
		break;
	default:
		return -1;
	}
	return kid;
}
Esempio n. 4
0
int main(int argc, char *argv[]) 
{ 
	struct childfdmap childfdmap[3];
	int ret;
	int flag = 0;
	int kid;
	int talk[2];
	char hi[3] = {0};
	char *child_argv[3];

	/* detect the child by the number of args. */
	if (argc > 1) {
		read(0, hi, 3);
		assert(!strcmp(hi, "HI"));
		/* pass something else back */
		hi[0] = 'Y';
		hi[1] = 'O';
		hi[2] = '\0';
		write(1, hi, 3);
		exit(0);
	}

	if (pipe(talk) < 0) {
		perror("pipe");
		exit(1);
	}
	printd("pipe [%d, %d]\n", talk[0], talk[1]);

	/* parent will read and write on talk[0], and the child does the same
	 * for talk[1].  internally, writing to talk 0 gets read on talk 1.  the
	 * child gets talk1 mapped for both stdin (fd 0) and stdout (fd 1). */
	childfdmap[0].parentfd = talk[1];
	childfdmap[0].childfd = 0;
	childfdmap[1].parentfd = talk[1];
	childfdmap[1].childfd = 1;

	sprintf(filename, "/bin/%s", argv[0]);
	child_argv[0] = filename;
	child_argv[1] = "1"; /* dummy arg, signal so we know they're the child*/
	child_argv[2] = 0;

	kid = sys_proc_create(filename, strlen(filename), child_argv, NULL, 0);
	if (kid < 0) {
		perror("create failed");
		exit(1);
	}

	ret = syscall(SYS_dup_fds_to, kid, childfdmap, 2);
	if (ret != 2) {
		perror("childfdmap faled");
		exit(2);
	}

	/* close the pipe endpoint that we duped in the child.  it doesn't
	 * matter for this test, but after the child exits, the pipe will still
	 * be open unless we close our side of it. */
	close(talk[1]);

	sys_proc_run(kid);

	if (write(talk[0], "HI", 3) < 3) {
		perror("write HI");
		exit(3);
	}

	if (read(talk[0], hi, 3) < 3) {
		perror("read YO");
		exit(4);
	}
	assert(!strcmp(hi, "YO"));

	printf("Passed\n");

	return 0;
}