⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 process.c

📁 大量的汇编程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    int ret_code, error;
    int org_stdin=0, org_stdout=0;

    if (npz->filp[0] && npz->filp[0]->f_doshandle != 0) {
	org_stdin = rm_dup(0);
	rm_dup2(npz->filp[0]->f_doshandle, 0);
    }
    if (npz->filp[1] && npz->filp[1]->f_doshandle != 1) {
	org_stdout = rm_dup(1);
	rm_dup2(npz->filp[1]->f_doshandle, 1);
    }
    error = execute_realmode_prg(filename, argv, env, &ret_code);
    if (org_stdin) {
	rm_dup2(org_stdin, 0);
	rm_close(org_stdin);
    }
    if (org_stdout) {
	rm_dup2(org_stdout, 1);
	rm_close(org_stdout);
    }
    if (error)
	return doserror_to_errno(ret_code);
    else {
	EAX = (long) ret_code & 0xff;	/* return value */
	current_pid++;
	return 0;
    }
}

static void copy_filedescriptors(NEWPROCESS * father, NEWPROCESS * child)
{
    int i;

    for (i = 0; i < N_FILES; i++)
	if (father->filp[i]) {
	    child->filp[i] = father->filp[i];
	    child->filp[i]->f_count ++;
	}
}

struct StubInfo {
    BYTE  magic[16];
    DWORD struct_length;
    char  go32[16];
    BYTE  need_version[4];
    DWORD min_stack;
    DWORD keep_on_spawn;
    BYTE  file_to_run[15];
    BYTE  enable_globbing;
    DWORD free_conv_memory;
} stub_info = {
    "StubInfoMagic!!",
    sizeof(struct StubInfo),
    "RSX",
    { 0,'b',0,4 },
    262144L,
    0L,
    "",
    0,
    0L
};

struct {
  DWORD size_structure;
  DWORD linaddr_primary_screen;
  DWORD linaddr_secondary_screen;
  DWORD linaddr_transfer_buffer;
  DWORD size_transfer_buffer; /* >= 4k */
  DWORD pid;
  BYTE	master_pic;
  BYTE	slave_pic;
  WORD	selector_linear_memory;
  DWORD linaddr_stubinfo;
  DWORD linaddr_org_psp;
  WORD	run_mode;
  WORD	run_mode_info;
} go32_info_block;

static void set_go32_info_block()
{
    go32_info_block.size_structure = sizeof(go32_info_block);
    go32_info_block.linaddr_primary_screen = 0xB0000;
    go32_info_block.linaddr_secondary_screen = 0xB8000;
    go32_info_block.linaddr_transfer_buffer =
	(((DWORD) ds16real << 4) + (DWORD) (UINT) iobuf) + 4096L;
    go32_info_block.size_transfer_buffer = 4096L;
    go32_info_block.pid = 42;
    go32_info_block.master_pic = 8;
    go32_info_block.slave_pic = 70;
    go32_info_block.selector_linear_memory = dosmem_sel;
    go32_info_block.linaddr_stubinfo =
	((DWORD) ds16real << 4) + (DWORD) (UINT) & stub_info;
    go32_info_block.linaddr_org_psp =
	((DWORD) cs16real << 4);
    go32_info_block.run_mode = 3;
    go32_info_block.run_mode_info = 0x090;
}

/*
** load, init and switch to another 32bit program
*/
int exec32(unsigned mode, char *name, int argc, char **argp, int envc, char **envp)
{
    NEWPROCESS *child, *father;
    int i, ret;

#ifdef CONFIG_KDEB
    static kernel_trace = 0;

    ret = strlen(name);
    if (opt_kdeb && ret >= 9 && strcmp(name+(ret-9), "rsx.emx") == 0) {
	if (*kdeb_program) {
	    name = kdeb_program;
	    kernel_trace = 1;
	    printf("KERNEL DEBUG MODE with second prg %s\n", name);
	}
	else {
	    printf("KERNEL DEBUG MODE (but no second prg)\n");
	    return EMX_EINVAL;
	}
    }
#endif

    /* if no wait, free last process */
    if (!opt_schedule)
	sys_wait((unsigned *)&ret);

    /* look for a empty slot */
    child = find_empty_process();
    if (child == NULL)
	return EMX_EAGAIN;

    /* try load a a.out program */
    if ((ret = load_protected_program(name, child)) != 0) {
	child->p_status = PS_EMPTY;
	return ret;
    }

    if (!(child->kstack = alloc_kernel_stack())) {
	puts("no kernel stack");
	child->p_status = PS_EMPTY;
	return EMX_EAGAIN;
    }

    cpy_exename_to_stack(child, name);

    /* copy arguments,environment */
    argvenv(argc, argp, envc, envp, child);

    /* setup new process table */
    child->pid = current_pid++;
    child->pptr = npz;
    if (mode == P_DEBUG)
	child->p_flags |= PF_DEBUG;
    /* start values */
    child->regs.eip = child->entry;
    child->regs.esporg = child->stackp32;
    child->regs.esp = child->stackp32 - 12L;	/* iret frame */
    /* for DJGPP: first MB */
    child->regs.eax = ((DWORD) dosmem_sel << 16) | 0x00007008L;
    child->regs.ebx = 0;
    child->regs.ecx = 0;
    child->regs.edx = ((DWORD) ds16real << 4) + (DWORD) (UINT) &go32_info_block;
    child->regs.esi = 0;
    child->regs.edi = 0;
    child->regs.ebp = 0;
    child->regs.cs = child->code32sel;
    child->regs.ds = child->data32sel;
    child->regs.es = child->data32sel;
    if (opt_stack || (child->p_flags & PF_USEDPMI10))
	child->regs.ss = child->data32sel;
    else
	child->regs.ss = child->data32sel + sel_incr;
    child->regs.fs = child->data32sel;
    child->regs.gs = dosmem_sel;
    child->regs.eflags = 0x3202;
    child->time_tic = time_tic;
    npz->cptr = child;

    if (child->p_flags & PF_DJGPP_FILE)
	set_go32_info_block();

    copy_filedescriptors(npz, child);
    father = npz;
    npz = child;
    for (i=0; i<N_FILES; i++)
	if (FD_ISSET(i, &father->close_on_exec))
	    sys_close(i);
    npz = father;

    /* if current prg extender, switch to first emx-porgram */
    if (npz->p_flags & PF_EXTENDER) {
	djio_init();	/* before first prg, init djio */
	child->p_status = PS_RUN;
	switch_context(child);
	shut_down(0);	/* should never execute */
    }

#ifdef CONFIG_KDEB
    if (opt_kdeb && kernel_trace == 1) {
	EAX = child->pid = 1;
	child->p_status = PS_STOP;
	RSX_PROCESS.cptr = child;
	RSX_PROCESS.regs.eip = 0x10000;
	RSX_PROCESS.regs.esp = (DWORD) & ret;
    }
#endif

    if (mode == P_WAIT) {
	MarkPageDemand(npz->memaddress, npz->membytes);
	npz->p_status = PS_STOP;
	child->p_status = PS_RUN;
	switch_context(child);
	npz->p_status = PS_RUN;
	EFLAGS &= ~1L;
	if (child->wait_return & 0xFF)	/* signal */
	    EAX = 3;
	else
	    EAX = (child->wait_return >> 8) & 0xFF;
    }
    else if (mode == P_NOWAIT) {
	child->p_status = PS_RUN;
	if (!opt_schedule)
	    switch_context(child);
	EFLAGS &= ~1L;
	EAX = (DWORD) child->pid;
    } else if (mode == P_DEBUG) {
	EAX = child->pid;	/* return process no */
	child->p_status = PS_STOP;
    } else if (mode == P_OVERLAY) {
	NEWPROCESS *this = npz;
	npz->p_flags &= ~PF_MATH_USED;	/* don't save mathe state */
	switch_to_process(npz->pptr);	/* switch to parent */
	free_process(this);	/* free process memory */
	clean_processtable(this);	/* free process table */
	npz->cptr = child;	/* new child */
	child->pptr = npz;	/* new parent */
	switch_to_process(child);	/* switch to new child */
	npz->p_status = PS_RUN;
    } else
	return EMX_EINVAL;

    return 0;
}

/*
** fork current process
*/
int sys_fork(void)
{
    NEWPROCESS *child;
    WORD child_stack32sel;
    int pid;

    child = find_empty_process();
    if (child == NULL)
	return -EMX_EAGAIN;

    /* copy process tables */
    memcpy(child, npz, sizeof(NEWPROCESS));

    child->p_status = PS_EMPTY; /* if error, leave empty */

    if (!(child->kstack = alloc_kernel_stack())) {
	puts("no kernel stack");
	return -EMX_EAGAIN;
    }

    /* MEMORY per DPMI besorgen */
    if (child->p_flags & PF_USEDPMI10) {
	if (AllocLinearMemory(npz->membytes, 0L, 0L, &child->memhandle, &child->memaddress))
	    return -EMX_ENOMEM;
    } else {
	if (AllocMem(npz->membytes, &child->memhandle, &child->memaddress))
	    return -EMX_ENOMEM;
    }

    if (AllocLDT(3, &(child->code32sel))) {
	FreeMem(child->memhandle);
	return -EMX_EIO;
    }

    child->data32sel = child->code32sel + sel_incr;
    child_stack32sel = child->data32sel;
    child_stack32sel += sel_incr;

    SetBaseAddress(child->code32sel, child->memaddress);
    SetBaseAddress(child->data32sel, child->memaddress);
    SetBaseAddress(child_stack32sel, child->memaddress);
    SetAccess(child->code32sel, APP_CODE_SEL, DEFAULT_BIT | GRANULAR_BIT);
    SetAccess(child->data32sel, APP_DATA_SEL, DEFAULT_BIT | GRANULAR_BIT);
    SetAccess(child_stack32sel, APP_DATA_SEL | EXPAND_BIT, BIG_BIT | GRANULAR_BIT);
    SetLimit(child->code32sel, lsl32(npz->code32sel));
    SetLimit(child->data32sel, lsl32(npz->data32sel));
    SetLimit(child_stack32sel, lsl32(SS));

    child->regs.cs = child->code32sel;
    child->regs.ds = child->data32sel;
    child->regs.es = child->data32sel;
    if (!opt_stack && !(child->p_flags & PF_USEDPMI10))
	child->regs.ss = child_stack32sel;
    else
	child->regs.ss = child->data32sel;
    child->regs.fs = child->data32sel;
    child->regs.gs = dosmem_sel;/* first Megabyte DOS */
    pid = child->pid = current_pid++;
    child->pptr = npz;
    child->cptr = NULL;
    child->time_alarm = 0;
    child->time_tic = time_tic;
    child->filehandle = 0;		/* for swapper !! */
    child->entry = child->regs.eip;	/* for switch_context !! */
    npz->cptr = child;

    copy_filedescriptors(npz, child);

    /* text segment */
    cpy32_32(npz->data32sel, npz->text_start,
	     child->data32sel, child->text_start,
	     npz->text_end - npz->text_start);

    /* data/bss segment */
    cpy32_32(npz->data32sel, npz->data_start,
	     child->data32sel, child->data_start,
	     npz->data_end - npz->data_start);

    /* heap segment */
    cpy32_32(npz->data32sel, npz->init_brk,
	     child->data32sel, child->init_brk,
	     npz->brk_value - npz->init_brk);

    /* stack segment */
    cpy32_32(npz->data32sel, ESP,
	     child->data32sel, ESP,
	     npz->stack_top - ESP);

    /* child returns null */
    child->regs.ecx = 0;
    child->regs.eax = 0;

    child->p_status = PS_RUN;
    switch_context(child);

    return pid;
}

/*
** global clean-up for extender
*/
void shut_down(int exit_code)
{
    NEWPROCESS *p;

    /* free memory,selectors */
    for (p = &FIRST_PROCESS; p != NULL && p <= &LAST_PROCESS; p++)
	free_process(p);

    if (opt_printall)
	printf("clock: %lu ticks = %lu sec\n", time_tic, time_tic * 10 / 182);

#ifdef CONFIG_KDEB
    if (opt_kdeb)
	KDEB_disable_breakpoints();
#endif

    /* clean_up ints,exceptions,... */
    clean_up();

    /* leave protected mode */
    protected_to_real(exit_code);
}

/*
** get more memory from DPMI-Server
*/
DWORD getmem(DWORD bytes, NEWPROCESS * p)
{				/* ret: old break value */
    DWORD retv, pagealign;
    DWORD newaddress, newhandle;

    if (bytes <= p->pagefree) {
	retv = p->brk_value;
	p->brk_value += bytes;
	p->pagefree -= bytes;
    } else {
	if (p->p_flags & PF_DJGPP_FILE)
	    pagealign = (bytes + 0xFFFF) & 0xFFFF0000L;
	else
	    pagealign = (bytes + 0xFFF) & 0xFFFFF000L;
	if (ResizeMem(p->membytes + pagealign, p->memhandle,
		      &newhandle, &newaddress))
	    return -1L;
	p->membytes += pagealign;
	retv = p->brk_value;
	p->brk_value += bytes;
	p->pagefree += (pagealign - bytes);
	if (!opt_memaccess && !(p->options & OPT_MEMACCESS))
	    SetLimit(p->data32sel, p->membytes - 1);
	if (p->memhandle != newhandle) {
	    p->memhandle = newhandle;
	}
	if (p->memaddress != newaddress) {
	    p->memaddress = newaddress;
	    SetBaseAddress(p->code32sel, p->memaddress);
	    SetBaseAddress(p->data32sel, p->memaddress);
	    SetBaseAddress(p->data32sel + sel_incr, p->memaddress);
	    if (opt_memaccess && opt_printall)
		puts("warning: memaccess pointer is not valid");
	}
	/* dammed! djgpp (gcc.exe) cause gp-fault, if not */
	if ((p->p_flags & PF_DJGPP_FILE) || opt_zero)
	    bzero32(p->data32sel, retv, pagealign);
    }
    return retv;
}

/*
** exit process and switch to father
*/
int do_exit4c(int bysig)
{
    NEWPROCESS *father;
    int i;
    unsigned retval;

    retval = AX & 0xFF;

    /* close all files */
    for (i = 0; i <= N_FILES; i++)
	if (npz->filp[i])
	    sys_close(i);

    /* get parent */
    father = npz->pptr;

    npz->wait_return = (bysig) ? bysig : retval << 8;
    npz->p_status = PS_ZOMBIE;
    npz->p_flags |= PF_WAIT_WAIT;	/* allow wait() for father */
    npz->p_flags &= ~PF_MATH_USED;	/* don't save mathe state */
    free_process(npz);
    free_kernel_stack(npz->kstack);

    /* if father process is Extender */
    if (father->p_flags & PF_EXTENDER)
	shut_down(retval);

    if (father->p_status == PS_WAIT)
	father->p_status = PS_RUN;

    send_signal(father, SIGCLD);
    switch_context(father);

    puts("RSX: end of do_exit4c() should never reached");
    shut_down(0);
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -