📄 task.c
字号:
{ COUNT rc; UBYTE UMBstate = uppermem_link; UBYTE orig_mem_access = mem_access_mode; if (mode & 0x80) { mem_access_mode |= 0x80; DosUmbLink(1); /* link in UMB's */ } rc = ChildEnv(exp, &env, namep); /* COMFILES will always be loaded in largest area. is that true TE */ /* yes, see RBIL, int21/ah=48 -- Bart */ if (rc == SUCCESS) rc = ExecMemLargest(&asize, com_size); if (rc == SUCCESS) /* Allocate our memory and pass back any errors */ rc = ExecMemAlloc(asize, &mem, &asize); if (rc != SUCCESS) DosMemFree(env); if (mode & 0x80) { DosUmbLink(UMBstate); /* restore link state */ mem_access_mode = orig_mem_access; mode &= 0x7f; } if (rc != SUCCESS) return rc; ++mem; } else mem = exp->load.load_seg; }#ifdef DEBUG printf("DosComLoader. Loading '%S' at %04x\n", namep, mem);#endif /* Now load the executable */ { BYTE FAR *sp; if (mode == OVERLAY) /* memory already allocated */ sp = MK_FP(mem, 0); else /* test the filesize against the allocated memory */ sp = MK_FP(mem, sizeof(psp)); /* MS DOS always only loads the very first 64KB - sizeof(psp) bytes. -- 1999/04/21 ska */ /* rewind to start */ SftSeek(fd, 0, 0); /* read everything, but at most 64K - sizeof(PSP) */ DosRWSft(fd, 0xff00, sp, XFR_READ); DosCloseSft(fd, FALSE); } if (mode == OVERLAY) return SUCCESS; { UWORD fcbcode; psp FAR *p; /* point to the PSP so we can build it */ setvec(0x22, (intvec)MK_FP(user_r->CS, user_r->IP)); child_psp(mem, cu_psp, mem + asize); fcbcode = patchPSP(mem - 1, env, exp, namep); /* set asize to end of segment */ if (asize > 0x1000) asize = 0x1000; if (asize < 0x11) return DE_NOMEM; asize -= 0x11; /* CP/M compatibility--size of first segment for .COM files while preserving the far call to 0:00c0 + copy in HMA at ffff:00d0 */ p = MK_FP(mem, 0); p->ps_reentry = MK_FP(0xc - asize, asize << 4); asize <<= 4; asize += 0x10e; exp->exec.stack = MK_FP(mem, asize); exp->exec.start_addr = MK_FP(mem, 0x100); *((UWORD FAR *) MK_FP(mem, asize)) = (UWORD) 0; load_transfer(mem, exp, fcbcode, mode); } return SUCCESS;}VOID return_user(void){ psp FAR *p, FAR * q; REG COUNT i; iregs FAR *irp;/* long j;*/ /* restore parent */ p = MK_FP(cu_psp, 0); /* When process returns - restore the isv */ setvec(0x22, p->ps_isv22); setvec(0x23, p->ps_isv23); setvec(0x24, p->ps_isv24); /* And free all process memory if not a TSR return */ network_redirector(REM_PROCESS_END); /* might be a good idea to do that after closing but doesn't help NET either TE */ if (!tsr) { network_redirector(REM_CLOSEALL); for (i = 0; i < p->ps_maxfiles; i++) { DosClose(i); } FcbCloseAll(); FreeProcessMem(cu_psp); } cu_psp = p->ps_parent; q = MK_FP(cu_psp, 0); irp = (iregs FAR *) q->ps_stack; irp->CS = FP_SEG(p->ps_isv22); irp->IP = FP_OFF(p->ps_isv22); if (InDOS) --InDOS; exec_user((iregs FAR *) q->ps_stack, 0);}COUNT DosExeLoader(BYTE FAR * namep, exec_blk * exp, COUNT mode, COUNT fd){ UWORD mem, env, start_seg, asize = 0; UWORD exe_size; { UWORD image_size; /* compute image size by removing the offset from the */ /* number pages scaled to bytes plus the remainder and */ /* the psp */ /* First scale the size and remove the offset */ if (ExeHeader.exPages >= 2048) return DE_INVLDDATA; /* we're not able to get >=1MB in dos memory */ image_size = ExeHeader.exPages * 32 - ExeHeader.exHeaderSize; /* We should not attempt to allocate memory if we are overlaying the current process, because the new process will simply re-use the block we already have allocated. Jun 11, 2000 - rbc */ if ((mode & 0x7f) != OVERLAY) { UBYTE UMBstate = uppermem_link; UBYTE orig_mem_access = mem_access_mode; COUNT rc; /* and finally add in the psp size */ image_size += sizeof(psp) / 16; /*TE 03/20/01 */ exe_size = image_size + ExeHeader.exMinAlloc; /* Clone the environement and create a memory arena */ if (mode & 0x80) { DosUmbLink(1); /* link in UMB's */ mem_access_mode |= 0x80; } rc = ChildEnv(exp, &env, namep); if (rc == SUCCESS) /* Now find out how many paragraphs are available */ rc = ExecMemLargest(&asize, exe_size); exe_size = image_size + ExeHeader.exMaxAlloc; /* second test is for overflow (avoiding longs) -- exMaxAlloc can be high */ if (exe_size > asize || exe_size < image_size) exe_size = asize; /* TE if ExeHeader.exMinAlloc == ExeHeader.exMaxAlloc == 0, DOS will allocate the largest possible memory area and load the image as high as possible into it. discovered (and after that found in RBIL), when testing NET */ if ((ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0) exe_size = asize; /* Allocate our memory and pass back any errors */ if (rc == SUCCESS) rc = ExecMemAlloc(exe_size, &mem, &asize); if (rc != SUCCESS) DosMemFree(env); if (mode & 0x80) { mem_access_mode = orig_mem_access; /* restore old situation */ DosUmbLink(UMBstate); /* restore link state */ } if (rc != SUCCESS) return rc; mode &= 0x7f; /* forget about high loading from now on */ #ifdef DEBUG printf("DosExeLoader. Loading '%S' at %04x\n", namep, mem);#endif /* memory found large enough - continue processing */ ++mem; /* /// Added open curly brace and "else" clause. We should not attempt to allocate memory if we are overlaying the current process, because the new process will simply re-use the block we already have allocated. This was causing execl() to fail in applications which use it to overlay (replace) the current exe file with a new one. Jun 11, 2000 - rbc */ } else /* !!OVERLAY */ { mem = exp->load.load_seg; } /* Now load the executable */ /* offset to start of image */ if (SftSeek(fd, ExeHeader.exHeaderSize * 16UL, 0) != SUCCESS) { if (mode != OVERLAY) { DosMemFree(--mem); DosMemFree(env); } return DE_INVLDDATA; } /* create the start seg for later computations */ start_seg = mem; exe_size = image_size; if (mode != OVERLAY) { exe_size -= sizeof(psp) / 16; start_seg += sizeof(psp) / 16; if (exe_size > 0 && (ExeHeader.exMinAlloc | ExeHeader.exMaxAlloc) == 0) { mcb FAR *mp = MK_FP(mem - 1, 0); /* then the image should be placed as high as possible */ start_seg += mp->m_size - image_size; } } } /* read in the image in 32256 chunks */ { int nBytesRead, toRead = CHUNK; seg sp = start_seg; while (1) { if (exe_size < CHUNK/16) toRead = exe_size*16; nBytesRead = (int)DosRWSft(fd, toRead, MK_FP(sp, 0), XFR_READ); if (nBytesRead < toRead || exe_size <= CHUNK/16) break; sp += CHUNK/16; exe_size -= CHUNK/16; } } { /* relocate the image for new segment */ COUNT i; UWORD reloc[2]; seg FAR *spot; SftSeek(fd, ExeHeader.exRelocTable, 0); for (i = 0; i < ExeHeader.exRelocItems; i++) { if (DosRWSft (fd, sizeof(reloc), (VOID FAR *) & reloc[0], XFR_READ) != sizeof(reloc)) { if (mode != OVERLAY) { DosMemFree(--mem); DosMemFree(env); } return DE_INVLDDATA; } if (mode == OVERLAY) { spot = MK_FP(reloc[1] + mem, reloc[0]); *spot += exp->load.reloc; } else { /* spot = MK_FP(reloc[1] + mem + 0x10, reloc[0]); */ spot = MK_FP(reloc[1] + start_seg, reloc[0]); *spot += start_seg; } } } /* and finally close the file */ DosCloseSft(fd, FALSE); /* exit here for overlay */ if (mode == OVERLAY) return SUCCESS; { UWORD fcbcode; /* point to the PSP so we can build it */ setvec(0x22, (intvec)MK_FP(user_r->CS, user_r->IP)); child_psp(mem, cu_psp, mem + asize); fcbcode = patchPSP(mem - 1, env, exp, namep); exp->exec.stack = MK_FP(ExeHeader.exInitSS + start_seg, ExeHeader.exInitSP); exp->exec.start_addr = MK_FP(ExeHeader.exInitCS + start_seg, ExeHeader.exInitIP); /* Transfer control to the executable */ load_transfer(mem, exp, fcbcode, mode); } return SUCCESS;}/* mode = LOAD or EXECUTE ep = EXE block lp = filename to load (string) leb = local copy of exe block */COUNT DosExec(COUNT mode, exec_blk FAR * ep, BYTE FAR * lp){ COUNT rc; COUNT fd; if ((mode & 0x7f) > 3 || (mode & 0x7f) == 2) return DE_INVLDFMT; fmemcpy(&TempExeBlock, ep, sizeof(exec_blk)); /* If file not found - free ram and return error */ if (IsDevice(lp) || /* we don't want to execute C:>NUL */ (fd = (short)DosOpenSft(lp, O_LEGACY | O_OPEN | O_RDONLY, 0)) < 0) { return DE_FILENOTFND; } rc = (int)DosRWSft(fd, sizeof(exe_header), (BYTE FAR *)&ExeHeader, XFR_READ); if (rc == sizeof(exe_header) && (ExeHeader.exSignature == MAGIC || ExeHeader.exSignature == OLD_MAGIC)) { rc = DosExeLoader(lp, &TempExeBlock, mode, fd); } else if (rc != 0) { rc = DosComLoader(lp, &TempExeBlock, mode, fd); } DosCloseSft(fd, FALSE); if (mode == LOAD && rc == SUCCESS) fmemcpy(ep, &TempExeBlock, sizeof(exec_blk)); return rc;}#include "config.h" /* config structure definition *//* start process 0 (the shell) */VOID ASMCFUNC P_0(struct config FAR *Config){ BYTE *tailp, *endp; exec_blk exb; UBYTE mode = Config->cfgP_0_startmode; /* build exec block and save all parameters here as init part will vanish! */ exb.exec.fcb_1 = exb.exec.fcb_2 = (fcb FAR *)-1L; exb.exec.env_seg = DOS_PSP + 8; fstrcpy(Shell, MK_FP(FP_SEG(Config), Config->cfgInit)); /* join name and tail */ fstrcpy(Shell + strlen(Shell), MK_FP(FP_SEG(Config), Config->cfgInitTail)); endp = Shell + strlen(Shell); for ( ; ; ) /* endless shell load loop - reboot or shut down to exit it! */ { BYTE *p; /* if there are no parameters, point to end without "\r\n" */ if((tailp = strchr(Shell,'\t')) == NULL && (tailp = strchr(Shell, ' ')) == NULL) tailp = endp - 2; /* shift tail to right by 2 to make room for '\0', ctCount */ for (p = endp - 1; p >= tailp; p--) *(p + 2) = *p; /* terminate name and tail */ *tailp = *(endp + 2) = '\0'; /* ctCount: just past '\0' do not count the "\r\n" */ exb.exec.cmd_line = (CommandTail *)(tailp + 1); exb.exec.cmd_line->ctCount = endp - tailp - 2;#ifdef DEBUG printf("Process 0 starting: %s%s\n\n", Shell, tailp + 2);#endif res_DosExec(mode, &exb, Shell); put_string("Bad or missing Command Interpreter: "); /* failure _or_ exit */ put_string(Shell); put_string(tailp + 2); put_string(" Enter the full shell command line: "); endp = Shell + res_read(STDIN, Shell, NAMEMAX); *endp = '\0'; /* terminate string for strchr */ }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -