📄 exec.c
字号:
} cur_proc->sig = 0; cur_proc->evenfile = 0; cur_proc->pid = cur_proc->pid; /* Same proccess id */ cur_proc->psize.fmagic = 0; cur_proc->psize.entry = (long)coms->c_routine; cur_proc->psize.tsize = 0; cur_proc->psize.dsize = 0; cur_proc->psize.bsize = 0; cur_proc->psize.ebss = (unsigned)memstart(PROCSEG, 0); cur_proc->object.majdev = 0; cur_proc->object.mindev = 0; cur_proc->object.inode = 0; strncpy(cur_proc->name, name, PATHLEN); cur_proc->majseg = PROCSEG; cur_proc->minseg = 0; cur_proc->flag = SLOAD; cur_proc->stat = SRUN; /* Not realy nesecary as they will be ignored */ cur_proc->reg->sr = 0x0200; /* Sets super state */ cur_proc->reg->usp = (long)sp; cur_proc->reg->pc = cur_proc->psize.entry; /* Sets euid, egid on execution */ if(coms->mode & ISUID) cur_proc->euid = 0; if(coms->mode & ISGID) cur_proc->egid = 0; setmempid(PROCSEG, 0, cur_proc->pid); smaskoff(cur_proc, EVOFF); /* Reallow those nasty interupts */ /* Execute internal program with argc, argv and env on user stack */ kexit(((*coms->c_routine)(*sp, sp + 1, sp + 2)) << 8); return;}/* * Infile - Get program size info from the file whoose inode * is given */infile(file, psize)struct file *file;struct Psize *psize;{ struct bhdr filhdr; /* Read header */ if (f_read(file, &filhdr, sizeof(struct bhdr)) != sizeof(struct bhdr)){ /* read error */ return error(ENOEXEC); } psize->fmagic = filhdr.fmagic; psize->tsize = filhdr.tsize; psize->dsize = filhdr.dsize; psize->bsize = filhdr.bsize; psize->entry = filhdr.entry; psize->ustack = 0; psize->stacks = 0; psize->ebss = 0; return 0;}/* * Fromfile - Collect the executable program from the filestore * Into core. */fromfile(file,psize)struct file *file;struct Psize *psize;{ unsigned long datastart; /* Read in text segment */ if (f_read(file, psize->entry, psize->tsize) != psize->tsize){ /* read error */ return -1; } /* Work out start of data segment */ if(psize->fmagic == FMAGIC){ datastart = psize->entry+psize->tsize; } else{ datastart = ((psize->entry+psize->tsize)&MMUMASK)+MMUBOUND; } /* Read in data segment */ if(f_read(file, datastart, psize->dsize) != psize->dsize){ /* read error */ return -1; } return 0;}/****************************************************************************** * Storeargs Saves both arguments and environ's in store area ****************************************************************************** */storeargs(argv, env)char *argv[], *env[];{ int c; areaptr = argarea; /* Sets area pointer to start of save area */ /* saves argvs */ for(c=0; argv[c]; c++){ if((c>=(NARGS-1))||((areaptr-argarea+strlen(argv[c]))>ARGAREA)){ return error(E2BIG); } aargv[c] = areaptr; /* Puts argument pointer into array */ areaptr = putarea(areaptr, argv[c]); /* Saves string */ } aargv[c]=0; /* Last one is a null pointer /* Saves enviroment varibles */ for(c=0; env[c]; c++){ if((c>=(NENVS-1))||((areaptr-argarea+strlen(env[c]))>ARGAREA)){ return error(E2BIG); } aenv[c] = areaptr; /* Puts environ pointer into array */ areaptr = putarea(areaptr,env[c]); /* Saves string */ } aenv[c]=0; /* Last one is a null pointer */ return 0;}/****************************************************************************** * Saveargs Saves both arguments and environ's on user stack ****************************************************************************** * * Arguments * sp Stack pointer * argv Pointer to array of argument pointers * env Pointer to array of enviroment pointers * * Returns * sp New updated value for stack pointer * * Uses * putstack() To push varibles */long *saveargs(sp, argv, env)long *sp;char *argv[], *env[];{ char *spc; long count; char *args[NARGS]; /* argument pos on stack */ short argc; /* Number of arguments */ char *envs[NENVS]; /* enviroment pos on stack */ short envc; /* Number of enviroment varibles */ int sum;#ifdef TEXECEprintf("SAVEARGS\n\r");#endif *(--sp) = 0; /* Puts 00 on stack end of strings */ spc = (char *)sp; /* Finds the number of bytes in the strings if odd make even */ sum = 0; for(count = 0; env[count]; count++){ sum += strlen(env[count]) + 1; } envc = count; for(count = 0; argv[count]; count++){ sum += strlen(argv[count]) + 1; } argc=count; if(sum&1) *(--spc) = 0; /* Make even subtracts one from sp */ #ifdef TEXECEprintf("SAVEARGS saveing strings\n\r");#endif /* Saveing argument strings */ for(count = envc-1; count >= 0; count--){ spc=putstack(spc,env[count]); envs[count] = spc; /* Sets enviroment pointer to string */ } for(count = argc-1; count >= 0; count--){ spc = putstack(spc,argv[count]); args[count] = spc; /* Sets argument pointer to string */ } sp = (long *)spc; /* Save enviroment pointers */ *(--sp) = 0; /* Null pointer */ for(count = envc-1; count >= 0; count--){ *(--sp) = (long)envs[count]; } /* Save argument pointers */ *(--sp) = 0; /* Null pointer */#ifdef TEXECEprintf("SAVEARGS saveing pointers\n\r");#endif for(count=argc-1; count>=0; count--){ *(--sp) = (long)args[count]; } /* Codata exec type just saves argc */ *(--sp) = argc; /* Save argc */#ifdef TEXECE spl=sp;printf("Bottom stack %x\n\r",sp);if('p'==getchar()){for(c=0; c<20; c++){ printf("%x %x\n\r",spl,*spl); spl++;}}#endif return sp;}/****************************************************************************** * Putstack Puts a string onto the stack (ie decrement before push * action) returning the new value of the stack pointer. ****************************************************************************** */char *putstack(sp,str)char *sp;char *str;{ int len; len=strlen(str); /* Finds length of string */ str += len; /* Sets str to point to end of string */ while(len-- >=0){ /* Puts string includeing null to sp */ *(--sp)= *str--; } return sp; /* Returns updated sp */}/****************************************************************************** * Putarea Puts a string into the area (increment after push * action) returning the new value of the srea pointer ****************************************************************************** */char *putarea(area,str)char *area;char *str;{ int len; len=strlen(str); /* Finds length of string */ while((len--)>=0){ /* Puts string includeing null to area*/ *(area++)= *str++; } return area; /* Returns updated */}/****************************************************************************** * Kfork Fork a new proccess, Swaps parent out and leaves child running ****************************************************************************** * * Returns 0 to child proccess (sets d0 of parent to pid of child) * * uses * swapout() Swaps proccess out of core * * Note * Sets Return address to +=2 if parent (Very nasty!) */kfork(){ struct procs *child; short smask;#ifdef TFORKprintf("Fork\n\r");ps();#endif /* Creates a new proccess entry */ if((child = newproc()) != (struct procs *)-1){ smask = smaskon(cur_proc, EVALL); /* Disable process switch */#ifdef TFORKprintf("Stack p %x, c %x, stp %x, stc %x\n",cur_proc,child,cur_proc->reg, child->reg);#endif child->reg->d0 = cur_proc->pid; /* Sets up return pid */ cur_proc->reg->d0 = child->pid; /* Inform parent of children */ /* Sets up last state pointer */ cur_proc->reg->laststate = (long)&cur_proc->sysstack[SYSSTACK]; /* Increments pc for return to Fork if parent * YEUCK! what a horible thing to Have to do */ cur_proc->reg->pc += 2; /* Adds 2 for return to parent fork */#ifdef TFORKprintf("About to return ie execute bye bye!\n\r");#endif#ifdef TFORKps();#endif smaskoff(child, EVOFF); smaskoff(cur_proc, smask); return cur_proc->reg->d0; }#ifdef TFORKprintf("FORK: Didnt make proccess\n\r");#endif /* failed - no slot */ cur_proc->reg->pc += 2; /* Adds 2 for return to parent fork */ printf("FORK: No more proccess room\n\r"); return error(EAGAIN);}/****************************************************************************** * Kill() System kill process call ****************************************************************************** * * Sends the kill signal to the pid given, if process has the same * userid or is root. * If the pid is 0 sends the signal to all processes in the group. * If the pid is -1 and process is root sends the signal to all * processes bar 0, and the curent process (normaly would send to * process 1 as well). */kill(pid, sig)short pid;long sig;{ struct procs *proc; /* If pid is 0 send the signal to all processes in group */ if(!pid){ sendgrp(cur_proc->tty, sig, 0); } /* If pid is -1 and user is super user then send signal to all * processes except this one, and 0 (note signal is sent to pid 1). */ if((pid == -1) && (!cur_proc->euid)){ proc = &proc_table[NPROC-1]; for(pid = NPROC - 1; pid > 0; pid--){ if((proc->stat) && (proc->pid != cur_proc->pid)) sendsig(proc->pid, sig, 0); proc--; } } /* Else send only to given pid */ else{ /* Check if pid is valid and same user id */ proc = &proc_table[pid]; if((pid < 0) || (pid >= NPROC)) return error(ESRCH); /* If not root and not the same user id then error */ if((cur_proc->euid) && (cur_proc->euid != proc->euid)) return error(ESRCH); sendsig(proc->pid, sig, 0); } return 0;}/****************************************************************************** * Sbrk - Reset proccess's break location ****************************************************************************** */caddr_tsbrk(newbrk)caddr_t newbrk;{ caddr_t oldbrk; oldbrk = (caddr_t)cur_proc->psize.ebss; /* Slight checking is performed ie close to User stack pointer * Or Below workspace */ if((newbrk < (caddr_t)memstart(PROCSEG, cur_proc->minseg)) || ((long)newbrk >= (cur_proc->reg->usp - STACKROOM))){ if(state.warning) printf("SBRK: Warning bss area aproached stack\n"); return (caddr_t)error(ENOMEM); } cur_proc->psize.ebss = (long)newbrk; cur_proc->psize.bsize += (newbrk - oldbrk); return oldbrk;}/* Proccess status enquiry */p_status(no,pointer)int no;struct procs *pointer;{ struct procs *proc; /* Checks if proccess table entry exists */ if(no >= NPROC) return -1; /* Get proccess entry and write to given location */ proc = &proc_table[no]; bytecp(proc,pointer,sizeof(struct procs)); return (int)pointer;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -