Beispiel #1
0
ATF_TC_BODY(symbol_lookup_fail, tc)
{
	char symname[32];
	GElf_Sym sym;
	struct proc_handle *phdl;
	prmap_t *map;
	int error;

	phdl = start_prog(tc, false);

	/* Initialize the rtld_db handle. */
	(void)proc_rdagent(phdl);

	map = proc_name2map(phdl, target_prog_file);
	ATF_REQUIRE_MSG(map != NULL, "failed to look up map for '%s'",
	    target_prog_file);

	/*
	 * We shouldn't be able to find symbols at the beginning of a mapped
	 * file.
	 */
	error = proc_addr2sym(phdl, map->pr_vaddr, symname, sizeof(symname),
	    &sym);
	ATF_REQUIRE_MSG(error != 0, "unexpectedly found a symbol");

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Beispiel #2
0
ATF_TC_BODY(symbol_lookup, tc)
{
	GElf_Sym main_sym, r_debug_state_sym;
	struct proc_handle *phdl;
	u_long saved;
	int error;

	phdl = start_prog(tc, false);

	error = proc_name2sym(phdl, target_prog_file, "main", &main_sym, NULL);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main'");

	error = proc_name2sym(phdl, ldelf_object, "r_debug_state",
	    &r_debug_state_sym, NULL);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'r_debug_state'");

	set_bkpt(phdl, r_debug_state_sym.st_value, &saved);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
	verify_bkpt(phdl, &r_debug_state_sym, "r_debug_state", ldelf_object);
	remove_bkpt(phdl, r_debug_state_sym.st_value, saved);

	set_bkpt(phdl, main_sym.st_value, &saved);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
	verify_bkpt(phdl, &main_sym, "main", target_prog_file);
	remove_bkpt(phdl, main_sym.st_value, saved);

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Beispiel #3
0
int sys_kill(int pid){

	//t=t;
	printf("killing %d.",pid);
    ProcStruct *proc=(procs+pid-1);
	proc_free(proc);
    remove_page(proc->cr3);
    remove_page((uint64_t*)PADDR((uint64_t)proc->mm));

    ProcStruct* parent =((ProcStruct*)procs+proc->parent_id-1);

    if(parent)
        parent->num_child--; 
    if((parent) && (parent->status == WAITING) && (parent->waitingfor == proc->proc_id || parent->waitingfor == 0 || (parent->num_child==0)))
    {
        parent->status=RUNNABLE;
        parent->waitingfor=-1;
    }
                      
    printf("Killed %d ",proc->proc_id);
    
   // kmemset((void*)proc,0,sizeof(ProcStruct));
    proc->status = FREE;
    //proccount--
   return 0; 
}
Beispiel #4
0
unsigned int
proc_pid_cpu(pid_t pid)
{
  unsigned int total_pre, part_pre, total_post, part_post;

  proc_base *test = proc_create();
  proc_pid  *testinit = proc_pid_create(pid);
  
  proc_poll(test);
  proc_pid_poll(testinit);
  
  total_pre = proc_total(test);
  part_pre  = proc_pid_total(testinit);
  
  sleep(1);
  
  proc_poll(test);
  proc_pid_poll(testinit);
  
  total_post = proc_total(test);
  part_post  = proc_pid_total(testinit);
  
  proc_free(test);
  proc_pid_free(testinit);

  dprintf("total_pre = %u\n", total_pre);
  dprintf("part_pre = %u\n", part_pre);
  dprintf("total_post = %u\n", total_post);
  dprintf("part_post = %u\n", part_post);
  
  return ((part_post - part_pre) * 10000) / (total_post - total_pre);
}
Beispiel #5
0
ATF_TC_BODY(symbol_lookup, tc)
{
	GElf_Sym main_sym, r_debug_state_sym;
	struct proc_handle *phdl;
	proc_breakpoint_t saved;
	int error;

	phdl = start_prog(tc, false);

	error = proc_name2sym(phdl, target_prog_file, "main", &main_sym, NULL);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main'");

	error = proc_name2sym(phdl, ldelf_object, r_debug_state,
	    &r_debug_state_sym, NULL);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up '%s'", r_debug_state);

	set_bkpt(phdl, (uintptr_t)r_debug_state_sym.st_value, &saved);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
	verify_bkpt(phdl, &r_debug_state_sym, r_debug_state, ldelf_object);
	remove_bkpt(phdl, (uintptr_t)r_debug_state_sym.st_value, &saved);

	set_bkpt(phdl, (uintptr_t)main_sym.st_value, &saved);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
	verify_bkpt(phdl, &main_sym, "main", target_prog_file);
	remove_bkpt(phdl, (uintptr_t)main_sym.st_value, &saved);

	ATF_CHECK_EQ_MSG(proc_detach(phdl, PRELEASE_HANG), 0, "failed to detach");

	proc_free(phdl);
}
Beispiel #6
0
void sys_exit(uint64_t error_code){
//    printf("Exiting Process%p %d",curproc,curproc->proc_id);
    if(curproc)
    {
    proc_free(curproc);
    remove_page(curproc->cr3);
    remove_page((uint64_t*)PADDR((uint64_t)curproc->mm));

    ProcStruct* parent =((ProcStruct*)procs+curproc->parent_id-1);

    if(parent)
        parent->num_child--; 
    if((parent) && (parent->status == WAITING) && (parent->waitingfor == curproc->proc_id || parent->waitingfor == 0 || (parent->num_child==0)))
    {
        parent->status=RUNNABLE;
        parent->waitingfor=-1;
    }
                      
    printf("Exited%d ",curproc->proc_id);
    
   // kmemset((void*)proc,0,sizeof(ProcStruct));
   
    curproc->status = FREE;
    //proccount--
        }
}
Beispiel #7
0
int syscall_exit(int arg1)
{
	int pid;

	(void) arg1;
	if (current_process == NULL)
		return -1;

	set_translation_table_base((uint32_t) V2P(kernel_vm));
	__asm__ volatile("ldr sp, =kernel_stack_start");

	for (pid = 0; pid < PROCESS_COUNT_MAX; pid++) {
		struct Process *proc = &process_table[pid];

		if (proc->state == SLEEPING &&
		    proc->wait_pid == current_process->pid) {
		    	
			proc->wait_pid = -1;
			proc->state = READY;
		}
	}

	proc_free(current_process);
	current_process = NULL;

	schedule();

	return 0;
}
Beispiel #8
0
ATF_TC_BODY(map_alias_name2sym, tc)
{
	GElf_Sym sym1, sym2;
	prsyminfo_t si1, si2;
	struct proc_handle *phdl;
	int error;

	phdl = start_prog(tc, false);

	/* Initialize the rtld_db handle. */
	(void)proc_rdagent(phdl);

	/*
	 * Make sure that "target_prog:main" and "a.out:main" return the same
	 * symbol.
	 */
	error = proc_name2sym(phdl, target_prog_file, "main", &sym1, &si1);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main' via %s",
	    target_prog_file);
	error = proc_name2sym(phdl, aout_object, "main", &sym2, &si2);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main' via %s",
	    aout_object);

	ATF_CHECK_EQ(memcmp(&sym1, &sym2, sizeof(sym1)), 0);
	ATF_CHECK_EQ(si1.prs_id, si2.prs_id);

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Beispiel #9
0
ATF_TC_BODY(signal_forward, tc)
{
	struct proc_handle *phdl;
	int state, status;

	phdl = start_prog(tc, true);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	/* The process should have been interrupted by a signal. */
	state = proc_wstatus(phdl);
	ATF_REQUIRE_EQ_MSG(state, PS_STOP, "process has unexpected state %d",
	    state);

	/* Continue execution and allow the signal to be delivered. */
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	/*
	 * Make sure the process exited with status 0. If it didn't receive the
	 * SIGUSR1 that it sent to itself, it'll exit with a non-zero exit
	 * status, causing the test to fail.
	 */
	state = proc_wstatus(phdl);
	ATF_REQUIRE_EQ_MSG(state, PS_UNDEAD, "process has unexpected state %d",
	    state);

	status = proc_getwstat(phdl);
	ATF_REQUIRE(status >= 0);
	ATF_REQUIRE(WIFEXITED(status));
	ATF_REQUIRE_EQ(WEXITSTATUS(status), 0);

	proc_free(phdl);
}
Beispiel #10
0
void job_free(struct job *j)
{
	struct proc *p, *next;

	for(p = j->proc; p; p = next){
		next = p->next;
		proc_free(p);
	}
	ufree_argvp(j->argvp);
	free(j->cmd);
	free(j);
}
Beispiel #11
0
/* start a new process */
extern process *
noshell_proc_start(char **av, stream *inp, stream *outp, stream *errp, int newpg, char *who)
{
	process *pp;
	int i, n;

	if ((pp = (process *)malloc(sizeof(process))) == 0) {
		if (inp != 0)
			stream_free(inp);
		if (outp != 0)
			stream_free(outp);
		if (errp != 0)
			stream_free(errp);
		return 0;
	}
	pp->std[0] = inp;
	pp->std[1] = outp;
	pp->std[2] = errp;
	switch (pp->pid = fork()) {
	case -1:
		proc_free(pp);
		return 0;
	case 0:
		if(newpg)
			sysdetach();
		for (i=0; i<3; i++)
			if (pp->std[i] != 0){
				close(Bfildes(pp->std[i]->fp));
				while(pp->std[i]->fd < 3)
					pp->std[i]->fd = dup(pp->std[i]->fd, -1);
			}
		for (i=0; i<3; i++)
			if (pp->std[i] != 0)
				dup(pp->std[i]->fd, i);
		for (n = sysfiles(); i < n; i++)
			close(i);
		if(who)
			become(av, who);
		exec(av[0], av);
		perror("proc_start");
		exits("proc_start");
	default:
		for (i=0; i<3; i++)
			if (pp->std[i] != 0) {
				close(pp->std[i]->fd);
				pp->std[i]->fd = -1;
			}
		return pp;
	}
}
Beispiel #12
0
int
proc_attach(pid_t pid, int flags, struct proc_handle **pphdl)
{
	struct proc_handle *phdl;
	int error = 0;
	int status;

	if (pid == 0 || pid == getpid())
		return (EINVAL);

	/*
	 * Allocate memory for the process handle, a structure containing
	 * all things related to the process.
	 */
	if ((phdl = malloc(sizeof(struct proc_handle))) == NULL)
		return (ENOMEM);

	memset(phdl, 0, sizeof(struct proc_handle));
	phdl->pid = pid;
	phdl->flags = flags;
	phdl->status = PS_RUN;
	elf_version(EV_CURRENT);

	if (ptrace(PT_ATTACH, phdl->pid, 0, 0) != 0) {
		error = errno;
		DPRINTF("ERROR: cannot ptrace child process %d", pid);
		goto out;
	}

	/* Wait for the child process to stop. */
	if (waitpid(pid, &status, WUNTRACED) == -1) {
		error = errno;
		DPRINTF("ERROR: child process %d didn't stop as expected", pid);
		goto out;
	}

	/* Check for an unexpected status. */
	if (WIFSTOPPED(status) == 0)
		DPRINTFX("ERROR: child process %d status 0x%x", pid, status);
	else
		phdl->status = PS_STOP;

out:
	if (error)
		proc_free(phdl);
	else
		*pphdl = phdl;
	return (error);
}
Beispiel #13
0
void scheduler()
{
    for (;;)
    {
        struct process *proc =
            current_proc ? current_proc->next : list_head.next;

        /* Find a runnable process */
        while (proc == &list_head || proc->state != PROC_STATE_RUNNING)
        {
            if (proc != &list_head && proc->state == PROC_STATE_DEAD)
            {
                /* Release the dead process */
                struct process *dead = proc;
                proc = proc->next;
                sched_remove(dead);
                proc_free(dead);
            }
            else
            {
                proc = proc->next;
            }
        }

        close_int();
        current_proc = proc;

        /* Update TSS */
        tss.ss0 = KERNEL_DATA_SELECTOR;
        tss.esp0 = proc->kernel_stack;
        flush_tss();

        /* Change to process virtual address space */
        set_cr3(CAST_VIRTUAL_TO_PHYSICAL(proc->page_dir));

        if (!proc->context)
            init_context(proc);

        switch_kcontext(&sched_context, proc->context);

        /* Call schedule task */
        if (sched_task)
        {
            sched_task(current_proc);
            sched_task = NULL;
        }
    }
}
Beispiel #14
0
int
t1_bkpt_d()
{
	struct proc_handle *phdl;
	char *targv[] = { "t1-bkpt-t", NULL};
	unsigned long saved;

	proc_create("./t1-bkpt", targv, NULL, NULL, &phdl);
	assert(proc_bkptset(phdl, (uintptr_t)t1_bkpt_t, &saved) == 0);
	proc_continue(phdl);
	assert(proc_wstatus(phdl) == PS_STOP);
	proc_bkptexec(phdl, saved);
	proc_continue(phdl);
	proc_wstatus(phdl);
	proc_free(phdl);
}
Beispiel #15
0
Datei: misc.c Projekt: Jimx-/lyos
PUBLIC int do_procctl()
{
    endpoint_t who = mm_msg.PCTL_WHO;
    int param = mm_msg.PCTL_PARAM;
    int retval = 0;

    struct proc * p = proc_table + who;

    switch (param) {
    case PCTL_CLEARPROC:
        if (mm_msg.source != TASK_FS) retval = EPERM;
        else if (!list_empty(&(p->mem_regions))) retval = proc_free(p);
        break;
    default:
        retval = EINVAL;
        break;
    }

    return retval;
}
Beispiel #16
0
void
verify(String *path)
{
	char *p, *q;
	char *av[4];

	if(rejectcheck())
		return;
	if(shellchars(s_to_c(path))){
		reply("503 5.1.3 Bad character in address %s.\r\n", s_to_c(path));
		return;
	}
	av[0] = s_to_c(mailer);
	av[1] = "-x";
	av[2] = s_to_c(path);
	av[3] = 0;

	pp = noshell_proc_start(av, (stream *)0, outstream(),  (stream *)0, 1, 0);
	if (pp == 0) {
		reply("450 4.3.2 We're busy right now, try later\r\n");
		return;
	}

	p = Brdline(pp->std[1]->fp, '\n');
	if(p == 0){
		reply("550 5.1.0 String does not match anything.\r\n");
	} else {
		p[Blinelen(pp->std[1]->fp)-1] = 0;
		if(strchr(p, ':'))
			reply("550 5.1.0  String does not match anything.\r\n");
		else{
			q = strrchr(p, '!');
			if(q)
				p = q+1;
			reply("250 2.0.0 %s <%s@%s>\r\n", s_to_c(path), p, dom);
		}
	}
	proc_wait(pp);
	proc_free(pp);
	pp = 0;
}
Beispiel #17
0
ATF_TC_BODY(map_prefix_name2map, tc)
{
	struct proc_handle *phdl;
	prmap_t *map1, *map2;

	phdl = start_prog(tc, false);

	/* Initialize the rtld_db handle. */
	(void)proc_rdagent(phdl);

	/* Make sure that "ld-elf" and "ld-elf.so" return the same map. */
	map1 = proc_name2map(phdl, "ld-elf");
	ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for 'ld-elf'");
	map2 = proc_name2map(phdl, "ld-elf.so");
	ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for 'ld-elf.so'");
	ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0);

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Beispiel #18
0
/* pipe an address through a command to translate it */
extern dest *
translate(dest *dp)
{
	process *pp;
	String *line;
	dest *rv;
	char *cp;
	int n;

	pp = proc_start(s_to_c(dp->repl1), (stream *)0, outstream(), outstream(), 1, 0);
	if (pp == 0) {
		dp->status = d_resource;
		return 0;
	}
	line = s_new();
	for(;;) {
		cp = Brdline(pp->std[1]->fp, '\n');
		if(cp == 0)
			break;
		if(strncmp(cp, "_nosummary_", 11) == 0){
			nosummary = 1;
			continue;
		}
		n = Blinelen(pp->std[1]->fp);
		cp[n-1] = ' ';
		s_nappend(line, cp, n);
	}
	rv = s_to_dest(s_restart(line), dp);
	s_restart(line);
	while(s_read_line(pp->std[2]->fp, line))
		;
	if ((dp->pstat = proc_wait(pp)) != 0) {
		dp->repl2 = line;
		rv = 0;
	} else
		s_free(line);
	proc_free(pp);
	return rv;
}
Beispiel #19
0
/*
 *  Run a command to authorize or refuse entry.  Return status 0 means
 *  authorize, -1 means refuse.
 */
void
authorize(dest *dp)
{
	process *pp;
	String *errstr;

	dp->authorized = 1;
	pp = proc_start(s_to_c(dp->repl1), (stream *)0, (stream *)0, outstream(), 1, 0);
	if (pp == 0){
		dp->status = d_noforward;
		return;
	}
	errstr = s_new();
	while(s_read_line(pp->std[2]->fp, errstr))
		;
	if ((dp->pstat = proc_wait(pp)) != 0) {
		dp->repl2 = errstr;
		dp->status = d_noforward;
	} else
		s_free(errstr);
	proc_free(pp);
}
Beispiel #20
0
/*
 * Top-level module proc entries
 */
int proc_register (struct klife_status *klife)
{
	struct proc_dir_entry *version, *status, *create, *destroy;

	root = proc_mkdir (KLIFE_PROC_ROOT, NULL);
	if (unlikely (!root))
		goto err;

	version = create_proc_read_entry (KLIFE_PROC_VERSION, 0644, root,
					  &proc_version_read, klife);
	status = create_proc_read_entry (KLIFE_PROC_STATUS, 0644, root,
					 &proc_status_read, klife);

	boards = proc_mkdir (KLIFE_PROC_BOARDS, root);
	if (unlikely (!boards))
		goto err;

	create = create_proc_entry (KLIFE_PROC_CREATE, 0644, boards);
	if (likely (create)) {
		create->write_proc = proc_create_write;
		create->data = klife;
	}
	else
		goto err;

	destroy = create_proc_entry (KLIFE_PROC_DESTROY, 0644, boards);
	if (likely (destroy)) {
		destroy->write_proc = proc_destroy_write;
		destroy->data = klife;
	}
	else
		goto err;

	return 0;
 err:
	proc_free ();
	return 1;
}
Beispiel #21
0
ATF_TC_BODY(map_alias_name2map, tc)
{
	struct proc_handle *phdl;
	prmap_t *map1, *map2;

	phdl = start_prog(tc, false);

	/* Initialize the rtld_db handle. */
	(void)proc_rdagent(phdl);

	/* Ensure that "target_prog" and "a.out" return the same map. */
	map1 = proc_name2map(phdl, target_prog_file);
	ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for '%s'",
	    target_prog_file);
	map2 = proc_name2map(phdl, aout_object);
	ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for '%s'",
	    aout_object);
	ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0);

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Beispiel #22
0
/**
 * Frees simulator resources by invoking the CPU and OS module release routines.
 */
void sim_free(void) {
   mem_free();
   swapfile_free();
   proc_free();
   tlb_free();
}
Beispiel #23
0
void
data(void)
{
	int status, nbytes;
	char *cp, *ep;
	char errx[ERRMAX];
	Link *l;
	String *cmd, *err;

	if(rejectcheck())
		return;
	if(senders.last == 0){
		reply("503 2.5.2 Data without MAIL FROM:\r\n");
		rejectcount++;
		return;
	}
	if(rcvers.last == 0){
		reply("503 2.5.2 Data without RCPT TO:\r\n");
		rejectcount++;
		return;
	}
	if(!trusted && sendermxcheck()){
		rerrstr(errx, sizeof errx);
		if(strncmp(errx, "rejected:", 9) == 0)
			reply("554 5.7.1 %s\r\n", errx);
		else
			reply("450 4.7.0 %s\r\n", errx);
		for(l=rcvers.first; l; l=l->next)
			syslog(0, "smtpd", "[%s/%s] %s -> %s sendercheck: %s",
				him, nci->rsys, s_to_c(senders.first->p),
				s_to_c(l->p), errx);
		rejectcount++;
		return;
	}

	cmd = startcmd();
	if(cmd == 0)
		return;

	reply("354 Input message; end with <CRLF>.<CRLF>\r\n");
	if(debug){
		seek(2, 0, 2);
		stamp();
		fprint(2, "# sent 354; accepting DATA %s\n", thedate());
	}


	/*
	 *  allow 145 more minutes to move the data
	 */
	alarm(145*60*1000);

	status = pipemsg(&nbytes);

	/*
	 *  read any error messages
	 */
	err = s_new();
	if (debug) {
		stamp();
		fprint(2, "waiting for upas/send to close stderr\n");
	}
	while(s_read_line(pp->std[2]->fp, err))
		;

	alarm(0);
	atnotify(catchalarm, 0);

	if (debug) {
		stamp();
		fprint(2, "waiting for upas/send to exit\n");
	}
	status |= proc_wait(pp);
	if(debug){
		seek(2, 0, 2);
		stamp();
		fprint(2, "# %d upas/send status %#ux at %s\n",
			getpid(), status, thedate());
		if(*s_to_c(err))
			fprint(2, "# %d error %s\n", getpid(), s_to_c(err));
	}

	/*
	 *  if process terminated abnormally, send back error message
	 */
	if(status){
		int code;
		char *ecode;

		if(strstr(s_to_c(err), "mail refused")){
			syslog(0, "smtpd", "++[%s/%s] %s %s refused: %s",
				him, nci->rsys, s_to_c(senders.first->p),
				s_to_c(cmd), firstline(s_to_c(err)));
			code = 554;
			ecode = "5.0.0";
		} else {
			syslog(0, "smtpd", "++[%s/%s] %s %s %s%s%sreturned %#q %s",
				him, nci->rsys,
				s_to_c(senders.first->p), s_to_c(cmd),
				piperror? "error during pipemsg: ": "",
				piperror? piperror: "",
				piperror? "; ": "",
				pp->waitmsg->msg, firstline(s_to_c(err)));
			code = 450;
			ecode = "4.0.0";
		}
		for(cp = s_to_c(err); ep = strchr(cp, '\n'); cp = ep){
			*ep++ = 0;
			reply("%d-%s %s\r\n", code, ecode, cp);
		}
		reply("%d %s mail process terminated abnormally\r\n",
			code, ecode);
	} else {
		/*
		 * if a message appeared on stderr, despite good status,
		 * log it.  this can happen if rewrite.in contains a bad
		 * r.e., for example.
		 */
		if(*s_to_c(err))
			syslog(0, "smtpd",
				"%s returned good status, but said: %s",
				s_to_c(mailer), s_to_c(err));

		if(filterstate == BLOCKED)
			reply("554 5.7.1 we believe this is spam.  "
				"we don't accept it.\r\n");
		else if(filterstate == DELAY)
			reply("450 4.3.0 There will be a delay in delivery "
				"of this message.\r\n");
		else {
			reply("250 2.5.0 sent\r\n");
			logcall(nbytes);
			if(debug){
				seek(2, 0, 2);
				stamp();
				fprint(2, "# %d sent 250 reply %s\n",
					getpid(), thedate());
			}
		}
	}
	proc_free(pp);
	pp = 0;
	s_free(cmd);
	s_free(err);

	listfree(&senders);
	listfree(&rcvers);
}
Beispiel #24
0
pid_t proc_fork(void)
{
    /*
     * http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html
     */

    KERROR_DBG("%s(%u)\n", __func__, curproc->pid);

    struct proc_info * const old_proc = curproc;
    struct proc_info * new_proc;
    pid_t retval = 0;

    /* Check that the old process is in valid state. */
    if (!old_proc || old_proc->state == PROC_STATE_INITIAL)
        return -EINVAL;

    new_proc = clone_proc_info(old_proc);
    if (!new_proc)
        return -ENOMEM;

    /* Clear some things required to be zeroed at this point */
    new_proc->state = PROC_STATE_INITIAL;
    new_proc->exit_ksiginfo = NULL;
    new_proc->files = NULL;
    new_proc->pgrp = NULL; /* Must be NULL so we don't free the old ref. */
    memset(&new_proc->tms, 0, sizeof(new_proc->tms));
    /* ..and then start to fix things. */

    /*
     * Process group.
     */
    PROC_LOCK();
    proc_pgrp_insert(old_proc->pgrp, new_proc);
    PROC_UNLOCK();

    /*
     *  Initialize the mm struct.
     */
    retval = vm_mm_init(&new_proc->mm, old_proc->mm.nr_regions);
    if (retval)
        goto out;

    /*
     * Clone the master page table.
     * This is probably something we would like to get rid of but we are
     * stuck with because it's the easiest way to keep some static kernel
     * mappings valid between processes.
     */
    if (mmu_ptcpy(&new_proc->mm.mpt, &old_proc->mm.mpt)) {
        retval = -EAGAIN;
        goto out;
    }

    /*
     * Clone L2 page tables.
     */
    if (vm_ptlist_clone(&new_proc->mm.ptlist_head, &new_proc->mm.mpt,
                        &old_proc->mm.ptlist_head) < 0) {
        retval = -ENOMEM;
        goto out;
    }

    retval = clone_code_region(new_proc, old_proc);
    if (retval)
        goto out;

    /*
     * Clone stack region.
     */
    retval = clone_stack(new_proc, old_proc);
    if (retval) {
        KERROR_DBG("Cloning stack region failed.\n");
        goto out;
    }

    /*
     *  Clone other regions.
     */
    retval = clone_regions_from(new_proc, old_proc, MM_HEAP_REGION);
    if (retval)
        goto out;

    /*
     * Set break values.
     */
    new_proc->brk_start = (void *)(
            (*new_proc->mm.regions)[MM_HEAP_REGION]->b_mmu.vaddr +
            (*new_proc->mm.regions)[MM_HEAP_REGION]->b_bcount);
    new_proc->brk_stop = (void *)(
            (*new_proc->mm.regions)[MM_HEAP_REGION]->b_mmu.vaddr +
            (*new_proc->mm.regions)[MM_HEAP_REGION]->b_bufsize);

    /* fork() signals */
    ksignal_signals_fork_reinit(&new_proc->sigs);

    /*
     * Copy file descriptors.
     */
    KERROR_DBG("Copy file descriptors\n");
    int nofile_max = old_proc->rlim[RLIMIT_NOFILE].rlim_max;
    if (nofile_max < 0) {
#if configRLIMIT_NOFILE < 0
#error configRLIMIT_NOFILE can't be negative.
#endif
        nofile_max = configRLIMIT_NOFILE;
    }
    new_proc->files = fs_alloc_files(nofile_max, nofile_max);
    if (!new_proc->files) {
        KERROR_DBG(
               "\tENOMEM when tried to allocate memory for file descriptors\n");
        retval = -ENOMEM;
        goto out;
    }
    /* Copy and ref old file descriptors */
    for (int i = 0; i < old_proc->files->count; i++) {
        new_proc->files->fd[i] = old_proc->files->fd[i];
        fs_fildes_ref(new_proc->files, i, 1); /* null pointer safe */
    }
    KERROR_DBG("All file descriptors copied\n");

    /*
     * Select PID.
     */
    new_proc->pid = proc_get_next_pid();

    if (new_proc->cwd) {
        KERROR_DBG("Increment refcount for the cwd\n");
        vref(new_proc->cwd); /* Increment refcount for the cwd */
    }

    /* Update inheritance attributes */
    set_proc_inher(old_proc, new_proc);

    /* Insert the new process into the process array */
    procarr_insert(new_proc);

    /*
     * A process shall be created with a single thread. If a multi-threaded
     * process calls fork(), the new process shall contain a replica of the
     * calling thread.
     * We left main_thread null if calling process has no main thread.
     */
    KERROR_DBG("Handle main_thread\n");
    if (old_proc->main_thread) {
        KERROR_DBG("Call thread_fork() to get a new main thread for the fork.\n");
        if (!(new_proc->main_thread = thread_fork(new_proc->pid))) {
            KERROR_DBG("\tthread_fork() failed\n");
            retval = -EAGAIN;
            goto out;
        }

        KERROR_DBG("\tthread_fork() fork OK\n");

        /*
         * We set new proc's mpt as the current mpt because the new main thread
         * is going to return directly to the user space.
         */
        new_proc->main_thread->curr_mpt = &new_proc->mm.mpt;
        new_proc->state = PROC_STATE_READY;

        KERROR_DBG("Set the new main_thread (%d) ready\n",
                   new_proc->main_thread->id);
        thread_ready(new_proc->main_thread->id);
    } else {
        KERROR_DBG("No thread to fork.\n");
        new_proc->main_thread = NULL;
        new_proc->state = PROC_STATE_READY;
    }

    KERROR_DBG("Fork %d -> %d created.\n", old_proc->pid, new_proc->pid);
    retval = new_proc->pid;
out:
    if (unlikely(retval < 0)) {
        proc_free(new_proc);
    }
    return retval;
}
Beispiel #25
0
int
proc_create(const char *file, char * const *argv, proc_child_func *pcf,
    void *child_arg, struct proc_handle **pphdl)
{
	struct proc_handle *phdl;
	int error = 0;
	int status;
	pid_t pid;

	/*
	 * Allocate memory for the process handle, a structure containing
	 * all things related to the process.
	 */
	if ((phdl = malloc(sizeof(struct proc_handle))) == NULL)
		return (ENOMEM);

	elf_version(EV_CURRENT);

	/* Fork a new process. */
	if ((pid = vfork()) == -1)
		error = errno;
	else if (pid == 0) {
		/* The child expects to be traced. */
		if (ptrace(PT_TRACE_ME, 0, 0, 0) != 0)
			_exit(1);

		if (pcf != NULL)
			(*pcf)(child_arg);

		/* Execute the specified file: */
		execvp(file, argv);

		/* Couldn't execute the file. */
		_exit(2);
	} else {
		/* The parent owns the process handle. */
		memset(phdl, 0, sizeof(struct proc_handle));
		phdl->pid = pid;
		phdl->status = PS_IDLE;

		/* Wait for the child process to stop. */
		if (waitpid(pid, &status, WUNTRACED) == -1) {
			error = errno;
			DPRINTF("ERROR: child process %d didn't stop as expected", pid);
			goto bad;
		}

		/* Check for an unexpected status. */
		if (WIFSTOPPED(status) == 0) {
			error = errno;
			DPRINTFX("ERROR: child process %d status 0x%x", pid, status);
			goto bad;
		} else
			phdl->status = PS_STOP;
	}
bad:
	if (error)
		proc_free(phdl);
	else
		*pphdl = phdl;
	return (error);
}