コード例 #1
0
ファイル: proc_syscalls.c プロジェクト: guzhuo0624/workonc-
pid_t
sys_waitpid(pid_t pid, int *status, int options, pid_t *retval) 
{
	int result;

	if (options != 0 && options != WNOHANG) {
		return -EINVAL;
	}

	result = pid_is_parent(curthread->t_pid, pid);

	if (result < 0) {
		return result;
	}

	result = pid_join(pid, status, options);
	*retval = result;


	if (result < 0) {
		return result;
	}

	return 0; 
}
コード例 #2
0
ファイル: menu.c プロジェクト: Adam-Koza/A3
static
int
common_prog(int nargs, char **args)
{
	int result;
	char **args_copy;
#if OPT_SYNCHPROBS
	kprintf("Warning: this probably won't work with a "
		"synchronization-problems kernel.\n");
#endif

	/*
	 * Implementation of & option for menu when running programs.
	 * By default, menu will wait for user program to end before running.
	 * If on menu command line has a '&' at the end,
	 * it will not wait for the user program to end
	 * before continuing to run.
	 */

	bool toDetach;
	toDetach = false;
	pid_t childpid;
	if (*args[nargs - 1] == '&'){
		nargs--; // So we don't pass on &
		toDetach = true;
	}


	/* demke: Make a copy of arguments to pass to new thread,
	 * so that we aren't depending on parent's stack!
	 */
	args_copy = copy_args(nargs, args);
	if (!args_copy) {
		return ENOMEM;
	}

	/* demke: and now call thread_fork with the copy */
	
	result = thread_fork(args_copy[0] /* thread name */,
			cmd_progthread /* thread function */,
			args_copy /* thread arg */, nargs /* thread arg */,
			&childpid);
	if (result) {
		kprintf("thread_fork failed: %s\n", strerror(result));
		/* demke: need to free copy of args if fork fails */
		free_args(nargs, args_copy);
		return result;
	}

	// If toDetach, then wont wait for program to end before continuing menu.
	if (toDetach) {
		pid_detach(childpid);
	}
	// Wait for program to end before continuing
	// (unless it's detached, in which case join will do nothing.)
	pid_join(childpid, NULL, (int)NULL);

	return 0;
}
コード例 #3
0
ファイル: thread.c プロジェクト: adi-mishra/CSC369
int thread_join(pid_t pid, int *status) {
	/* We need to check a bunch of things that are internal to
	 * the pid system, like parent/child relationship and 
	 * exit status.  So, just hand off to a pid system
	 * function
	 */
	return pid_join(pid, status);
}
コード例 #4
0
ファイル: menu.c プロジェクト: guzhuo0624/workonc-
static
int
common_prog(int nargs, char **args)
{
	int result;
	int join_result;
	int *status;
	char **args_copy;
	pid_t *ret;

#if OPT_SYNCHPROBS
	kprintf("Warning: this probably won't work with a "
		"synchronization-problems kernel.\n");
#endif

	/* demke: Make a copy of arguments to pass to new thread,
	 * so that we aren't depending on parent's stack!
	 */
	args_copy = copy_args(nargs, args);
	if (!args_copy) {
		return ENOMEM;
	}

	if(strcmp(args[nargs-2], "&") == 0) {
		ret = NULL; //This will cause thread_fork to detach the child
	}

	/* demke: and now call thread_fork with the copy */
	
	result = thread_fork(args_copy[0] /* thread name */,
			cmd_progthread /* thread function */,
			args_copy /* thread arg */, nargs /* thread arg */,
			ret);

	if (result) {

		kprintf("thread_fork failed: %s\n", strerror(result));
		/* demke: need to free copy of args if fork fails */
		free_args(nargs, args_copy);
		return result;

	} else if (result != 0 && ret != NULL) {

		join_result = pid_join(result, status, 0);

		if (status != 0 || join_result < 0) {
			return join_result;
		}

	}

	return 0;
}
コード例 #5
0
static
int
common_prog(int nargs, char **args)
{
	int result;
	char **args_copy;
	pid_t childthread;
        int status;

#if OPT_SYNCHPROBS
	kprintf("Warning: this probably won't work with a "
		"synchronization-problems kernel.\n");
#endif

	/* demke: Make a copy of arguments to pass to new thread,
	 * so that we aren't depending on parent's stack!
	 */
	args_copy = copy_args(nargs, args);
	if (!args_copy) {
		return ENOMEM;
	}
        if(*args_copy[nargs-1]=='&'){
         result = thread_fork(args_copy[0] /* thread name */,
			cmd_progthread /* thread function */,
			args_copy /* thread arg */, nargs /* thread arg */,
			NULL);
        }
        else{
        result = thread_fork(args_copy[0] /* thread name */,
			cmd_progthread /* thread function */,
			args_copy /* thread arg */, nargs /* thread arg */,
			&childthread);
        pid_join(childthread,&status,0);
        }
	/* demke: and now call thread_fork with the copy */
	
	if (result) {
		kprintf("thread_fork failed: %s\n", strerror(result));
		/* demke: need to free copy of args if fork fails */
		free_args(nargs, args_copy);
		return result;
	}
        
        

	return 0;
}
コード例 #6
0
ファイル: pid.c プロジェクト: gapry/os161
/*
 * Handle system call waitpid - the current process waits for the target
 * process targetpid to exit, and stores the exit status in the pointer status.
 * Store a return value of 0 to retval if no error occurs and -1 otherwise.
 * Return the error code if an error occurs and 0 otherwise.
 */
int
sys_waitpid(pid_t targetpid, int *status, int options, int *retval){
    int err;
    
    /* Check if flag is valid. */
    if (options != 0 && options != WNOHANG) {
        err = -1 * EINVAL;
        goto out;
    }
    
    /* Check if the current thread is waiting on one of its
     * own children. */
    int ischild = check_ppid(targetpid);
    if (ischild == -1) {
        /* targetpid process does not exist. */
        err = -1 * ESRCH;
        goto out;
    } else if (ischild == 0) {
        /* Current thread is not the parent of target thread. */
        err = -1 * ECHILD;
        goto out;
    }    
    
    err = pid_join(targetpid, status, options);

out:
    if (err < 0) {
        /* An error occurred. */
        err = -err;
        *retval = -1;
    } else {
        *retval = err;
        err = 0;
    }

    return err;
}
コード例 #7
0
ファイル: waittest.c プロジェクト: JBKahn/OS161-Assignments
int
waittest(int nargs, char **args)
{
	int i, spl, status, err;
	pid_t kid;

	pid_t kids2[NTHREADS];
	int kids2_head = 0, kids2_tail = 0;

	(void)nargs;
	(void)args;

	init_sem();

	kprintf("Starting wait test...\n");
	
	/*
	 * This first set should (hopefully) still be running when
	 * wait is called (helped by the splhigh).
	 */
	
	kprintf("\n");
	kprintf("Set 1 (wait should generally succeed)\n");
	kprintf("-------------------------------------\n");

	spl = splhigh();
	for (i = 0; i < NTHREADS; i++) {
		err = thread_fork("wait test thread", waitfirstthread, NULL, i,
				  &kid);
		if (err) {
			panic("waittest: thread_fork failed (%d)\n", err);
		}
		kprintf("Spawned pid %d\n", kid);
		kids2[kids2_tail] = kid;
		kids2_tail = (kids2_tail+1) % NTHREADS;
	}
	splx(spl);

	for (i = 0; i < NTHREADS; i++) {
		kid = kids2[kids2_head];
		kids2_head = (kids2_head+1) % NTHREADS;
		kprintf("Waiting on pid %d...\n", kid);
		err = pid_join(kid, &status, 0);
		if (err) {
			kprintf("Pid %d waitpid error %d!\n", kid, err);
		}
		else {
			kprintf("Pid %d exit status: %d\n", kid, status);
		}
	}

	/*
	 * This second set has to V their semaphore before the exit,
	 * so when wait is called, they will have already exited, but
	 * their parent is still alive.
	 */

	kprintf("\n");
	kprintf("Set 2 (wait should always succeed)\n");
	kprintf("----------------------------------\n");

	for (i = 0; i < NTHREADS; i++) {
		err = thread_fork("wait test thread", exitfirstthread, NULL, i,
				  &kid);
		if (err) {
			panic("waittest: thread_fork failed (%d)\n", err);
		}
		kprintf("Spawned pid %d\n", kid);
		kids2[kids2_tail] = kid;
		kids2_tail = (kids2_tail+1) % NTHREADS;
		if (err) {
			panic("waittest: q_addtail failed (%d)\n", err);
		}
	}

	for (i = 0; i < NTHREADS; i++) {
		kid = kids2[kids2_head];
		kids2_head = (kids2_head+1) % NTHREADS;
		kprintf("Waiting for pid %d to V()...\n", kid);
		P(exitsems[i]);
		kprintf("Appears that pid %d P()'d\n", kid);
		kprintf("Waiting on pid %d...\n", kid);
		err = pid_join(kid, &status, 0);
		if (err) {
			kprintf("Pid %d waitpid error %d!\n", kid, err);
		}
		else {
			kprintf("Pid %d exit status: %d\n", kid, status);
		}
	}

	/*
	 * This third set has to V their semaphore before the exit, so
	 * when wait is called, they will have already exited, and
	 * since we've gone through and disowned them all, their exit
	 * statuses should have been disposed of already and our waits
	 * should all fail.
	 */

	kprintf("\n");
	kprintf("Set 3 (wait should never succeed)\n");
	kprintf("---------------------------------\n");

	for (i = 0; i < NTHREADS; i++) {
		err = thread_fork("wait test thread", exitfirstthread, NULL, i,
				  &kid);
		if (err) {
			panic("waittest: thread_fork failed (%d)\n", err);
		}
		kprintf("Spawned pid %d\n", kid);

		pid_detach(kid);
		
		kids2[kids2_tail] = kid;
		kids2_tail = (kids2_tail+1) % NTHREADS;
	}

	for (i = 0; i < NTHREADS; i++) {
		kid = kids2[kids2_head];
		kids2_head = (kids2_head+1) % NTHREADS;
		kprintf("Waiting for pid %d to V()...\n", kid);
		P(exitsems[i]);
		kprintf("Appears that pid %d P()'d\n", kid);
		kprintf("Waiting on pid %d...\n", kid);
		err = pid_join(kid, &status, 0);
		if (err) {
			kprintf("Pid %d waitpid error %d!\n", kid, err);
		}
		else {
			kprintf("Pid %d exit status: %d\n", kid, status);
		}
	}

	kprintf("\nWait test done.\n");

	return 0;
}