Example #1
0
/* terminate the currenct proccess into ZOMBIE, and tell its parent.
 * the struct proc is freed by each proc's parent.
 * */
int do_exit(int ret){
    struct file *fp;
    struct proc *p;
    uint fd, nr;

    cu->p_ret = ret;
    // clear all the signal handlers
    for (nr=0; nr<NSIG; nr++) {
        cu->p_sigact[nr].sa_handler = SIG_DFL;
        cu->p_sigact[nr].sa_flags = 0;
    }
    // close all the opened files, and iput the directories.
    for (fd=0; fd<NOFILE; fd++){
        fp = cu->p_ofile[fd];
        if (fp != NULL) {
            do_close(fd);
        }
        cu->p_ofile[fd] = NULL;
    }
    iput(cu->p_iroot);
    iput(cu->p_wdir);
    // tell its parent
    sigsend(cu->p_ppid, SIGCHLD, 1);
    // free the address space
    vm_clear(&cu->p_vm);
    kfree(cu->p_vm.vm_pgd, PAGE);
    // make this process Zombie, give all the children to proc[1] 
    // and tell its parent
    cu->p_chan = 0;
    cu->p_stat = SZOMB;
    for (nr=1; nr<NPROC; nr++) {
        if ((p=proc[nr]) && p!=cu && (p->p_ppid==cu->p_pid)) {
            p->p_ppid = 1;
        }
    }
    // wakeup proc[1] and its parent
    p = proc[cu->p_ppid];
    wakeup(p);
    wakeup(proc[1]);
    return 0;
}
Example #2
0
/* initialize a new struct vm according to an a.out executable 
 * image.
 * returns NULL on fail.
 * the user stack initialized like this:
 *   |--------------- esp
 *   | argc
 *   |---------------
 *   | argv
 *   |---------------
 *   | argv[0] "..."
 *   | argv[1] "..."
 *   | ...
 *   | argv[n] "..."
 *   --------------- VM_STACK
 * note: ignored envp yet.
 * */
int do_exec(char *path, char **argv){
    struct inode *ip;
    struct buf *bp;
    struct sigaction *sa;
    struct ahead *ah;
    struct page *pg;
    struct vm *vm;
    struct vma *vp;
    struct file *fp;
    uint bn, fd, argc, esp, nr;
    char **tmp;

    ip = namei(path, 0);
    if (ip==NULL) {
        return syserr(ENOENT);
    }
    // read the first block of file to get the a.out header.
    bn = bmap(ip, 0, 0);
    if (bn == 0) {
        syserr(EINVAL);
        goto _badf;
    }
    bp = bread(ip->i_dev, bn);
    ah = (struct ahead*)bp->b_data;
    // check this a.out header.
    if (ah->a_magic != NMAGIC) {
        syserr(EINVAL);
        goto _badf;
    }
    // restore the path and argv temporarily
    tmp = store_argv(path, argv);
    // dettach the previous address space, and initialize a new one
    vm = &cu->p_vm;
    vm_clear(vm);
    vm_renew(vm, ah, ip);
    // push arguments to the end of user stack, which always the same address.
    esp = VM_STACK;
    argc = upush_argv(&esp, tmp);
    if (argc<0)
        panic("exec(): bad mem");
    upush(&esp, &argc, sizeof(uint));
    //
    free_argv(tmp);
    // close all the file descriptors with FD_CLOEXEC
    for (fd=0; fd<NOFILE; fd++) {
        fp = cu->p_ofile[fd];
        if ((fp!=NULL) && (fp->f_fdflag & FD_CLOEXEC)) {
            do_close(fd);
        }
    }
    // clear all sigactions
    for (nr=0; nr<NSIG; nr++){
        sa = &cu->p_sigact[nr];
        sa->sa_handler = SIG_DFL;
        sa->sa_mask = 0;
        sa->sa_flags = 0;
        sa->sa_restorer = NULL;
    }
    // never forget this:
    brelse(bp);
    iput(ip);
    // enter user mode
    _retu(vm->vm_entry, esp);
    return 0;

_badf:
    brelse(bp);
    iput(ip);
    return -1;
}
Example #3
0
int colm_delete_program( program_t *prg )
{
	tree_t **sp = prg->stack_root;
	int exit_status = prg->exit_status;

	colm_tree_downref( prg, sp, prg->return_val );
	colm_clear_heap( prg, sp );

	colm_tree_downref( prg, sp, prg->error );

#if DEBUG
	long kid_lost = kid_num_lost( prg );
	long tree_lost = tree_num_lost( prg );
	long parse_tree_lost = parse_tree_num_lost( &prg->parse_tree_pool );
	long head_lost = head_num_lost( prg );
	long location_lost = location_num_lost( prg );

	if ( kid_lost )
		message( "warning: lost kids: %ld\n", kid_lost );

	if ( tree_lost )
		message( "warning: lost trees: %ld\n", tree_lost );

	if ( parse_tree_lost )
		message( "warning: lost parse trees: %ld\n", parse_tree_lost );

	if ( head_lost )
		message( "warning: lost heads: %ld\n", head_lost );

	if ( location_lost )
		message( "warning: lost locations: %ld\n", location_lost );
#endif

	kid_clear( prg );
	tree_clear( prg );
	head_clear( prg );
	parse_tree_clear( &prg->parse_tree_pool );
	location_clear( prg );

	struct run_buf *rb = prg->alloc_run_buf;
	while ( rb != 0 ) {
		struct run_buf *next = rb->next;
		free( rb );
		rb = next;
	}

	vm_clear( prg );

	if ( prg->stream_fns ) {
		char **ptr = prg->stream_fns;
		while ( *ptr != 0 ) {
			free( *ptr );
			ptr += 1;
		}

		free( prg->stream_fns );
	}

	free( prg );

	return exit_status;
}