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

📄 exec.c

📁 用于motorala 68K系列处理器的小实时多任务操作系统 The OMU Kernel was written to provide a cut-down Unix-like O/S for a
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** *	Exec.c		Exec fork and sbrk etc *			T.Barnaby, Made 20/5/85 ****************************************************************************** */# include	"../include/param.h"# include	<a.out.h># include	"../include/inode.h"# include	"../include/signal.h"# include	"../include/procs.h"# include	"../include/memory.h"# include	"../include/swap.h"# include	<errno.h># include	"../include/stat.h"# include	<sys/dir.h># include	"../include/state.h"# include	"../include/inbin.h"# include	"../include/dev.h"# include	"../include/file.h"extern	int proc_index;		/* Proccess index (number of proccesse */extern	struct Comm kercom[];	/* Internal kernal commands */long *saveargs();		/* Internal function declarations */char *putstack(), *putarea();struct procs *newproc();# define	OPEN	SEARCH# define	ARGAREA 2048		/* Max area for argument strings */# define	NARGS   60		/* Max number of arguments */# define	NENVS	30		/* Number of enviroment varibles */char	argarea[ARGAREA];	/* Area on system stack to save arguments */char	*areaptr;		/* Pointer to the area */char	*aargv[NARGS];		/* Pointers to args in area */char	*aenv[NENVS];		/* Pointers to environs in area *//****************************************************************************** *	Xeq	- Attempt to load and execute a command ****************************************************************************** * * This is used to execute a program from within the kernal (eg internal shell) *	A new proccess number is found, but the old proccess is not swaped *	out of core. *	It effectivly forks a new process and then execls over the top *	the program required. *	Returns pid to parent on success (0 to child), or -1 on fail *	with error no in errno. *	Do not call this routine without using the syscall interface. */xeq(name, argv, env)char *name, *argv[], *env[];{	struct procs *child, *parent;	short smask;	struct	inode	*iptr;#ifdef TXEQprintf("XEQ: %s, %x, %x\n",name,argv,environ);ps();#endif	/* Checks if internal kernal program, if not checks if program is	 * on disk and accessable	 */	if(!inbin(name)){		/* Try and get the file inode and get the object name */		if(!(iptr = namlock(name, EOPEN, NULLIPTR))) return error(ENOENT);		/* Check file access permissions */		if(!i_access(iptr, IAEXEC)){			freeiptr(iptr);			return error(EACCES);		}		/* Checks if regular file else retuens error */		if((iptr->i_mode & S_IFMT) != S_IFREG){			freeiptr(iptr);			return error(EACCES);		}		freeiptr(iptr);	}	smask = smaskon(cur_proc, EVALL);	/* Disables process switching */#ifdef TXEQprintf("Forking new process\n");#endif	/* attempt to make process slot for new process */	if((child = newproc()) != (struct procs *)-1){		/* Gets area of memory for the process */		getmem(PROCSEG, 0);		/* Sets parent to return childs pid */		parent = cur_proc;		/* Process is now child */		cur_proc = child;#ifdef TXEQprintf("Execling new process\n");#endif		/* Try and execl a process */		if(kexece(name, argv, env) == -1){#ifdef TXEQprintf("Exiting new process\n");#endif			endmem(PROCSEG, 0);			clrproc();			cur_proc->pid = 0;			cur_proc->ppid = 0;			cur_proc->sig = 0;			cur_proc->flag = 0;			cur_proc->majseg = 0;			cur_proc->minseg = 0;			cur_proc->wchan = 0;			cur_proc->stat = 0;			cur_proc->exitstatus = 0;			proc_index--;			cur_proc = parent;			smaskoff(cur_proc, smask);			return error(-1);		}		else {			cur_proc = parent;			smaskoff(child, EVOFF);			smaskoff(cur_proc, smask);			return child->pid;		}	}	/* failed - no slot */	smaskoff(cur_proc, smask);	return error(EAGAIN);}/****************************************************************************** * kexece - attempt to load and execute a command. ****************************************************************************** * * This is the standard system execl. It will check to see if the *	program name is an internal kernal program, if so it will execute *	this else will search the disk for the given program. *	returns 0 on success, -1 on fail. *	Do not call this routine without using the syscall interface. */kexece(name, argv, env)char *name, *argv[], *env[];{	unsigned long datastart;	/* Start of data in process space */	short sticky;		/* Sticky file indicator */	char swap;		/* Program from swap space flag */	short mseg, smask, smask1;	int c;	long *sp;	struct	inode	*iptr;	/* Inode or the program */	struct	Object	object;	struct	Psize	psize;	struct	file	file;#ifdef TEXECprintf("EXEC: %s, %x, %x\n",name, argv, env);ps();#endif	sticky = swap = 0;	/* Checks if internal program if so executes it */	if(inbin(name)) return exinbin(name, argv, env);	/* Try and get the file inode and get the object name */	if(!(iptr = namlock(name, EOPEN, NULLIPTR))) return error(ENOENT);	object.majdev = iptr->i_mdev;	object.mindev = iptr->i_minor;	object.inode = iptr->i_ino;	/* Check file access permissions */	if(!i_access(iptr, IAEXEC)){		freeiptr(iptr);		return error(EACCES);	}	/* Checks if regular file else returns error */	if((iptr->i_mode & S_IFMT) != S_IFREG){		freeiptr(iptr);		return error(EACCES);	}	smask = smaskon(cur_proc, EVALL);	/* Mask process switch */	/* Store all arguments in argarea */ 	if(storeargs(argv, env) == -1){		freeiptr(iptr);		smaskoff(cur_proc, smask);		return -1;	}#ifdef TEXECprintf("EXEC: checking swap\n");#endif	/* Check if in swap space */	if(inswap(&object, &psize) != -1){		swap = 1;	}	/* If not check if in file */	else{#ifdef TEXECprintf("EXEC: Opening file\n");#endif		if(f_open(&file, relock(iptr), READABLE) == -1){			freeiptr(iptr);			smaskoff(cur_proc,smask);			return error(ENOENT);		}#ifdef TEXECprintf("EXEC: checking file\n");#endif		infile(&file, &psize);	}#ifdef TEXECprintf("EXEC: in %d filetype %x\n",swap, psize.fmagic);#endif	/* Check file type */	if ((psize.fmagic != FMAGIC) && (psize.fmagic != NMAGIC)){		/* format wrong */		if(!swap) f_close(&file);		freeiptr(iptr);		return error(ENOEXEC);	}	/* Check if there is room for this program */	if((mseg = extmem(PROCSEG, cur_proc->minseg,		psize.tsize + psize.dsize + psize.bsize)) == -1){		if(!swap) f_close(&file);		freeiptr(iptr);		smaskoff(cur_proc, smask);		return error(ENOMEM);	}	/* Check if within process workspace */	if((psize.entry < (long)memstart(PROCSEG, mseg)) ||		(psize.entry >= (long)memend(PROCSEG, mseg))){		if(!swap) f_close(&file);		freeiptr(iptr);		smaskoff(cur_proc,smask);		return error(ENOMEM);	}	/* Clears signals to default if they are not ignored ones */	for(c=0; c<NSIG; c++){		if(cur_proc->signals[c].func != SIG_IGN){			cur_proc->signals[c].func = SIG_DFL;		}	}	cur_proc->sigmode = SIGMODEUNIX;	/* Normal signal mode */	cur_proc->sigmask = ENALLSIG;		/* Unmask all signals */	cur_proc->evcom = 0;			/* All events off */	cur_proc->evenfile = 0;	cur_proc->evfile = 0;	cur_proc->alarm = 0;		/* Event alarm clock ! */					/* Ps I only found this one 1 day */					/* before my Phd viva ! */	cur_proc->wchan = 0;			/* Wakeup off */	cur_proc->pwakechan = 0;		/* Pre-wake off */	cur_proc->pwakeevent = 0;	/* Set program sizes */	if(psize.fmagic == FMAGIC){		datastart = psize.entry+psize.tsize;	}	else{		datastart = ((psize.entry+psize.tsize)&MMUMASK)+MMUBOUND;	}	/* Sets up stack pointer to end of stack */	sp = (long *)memend(PROCSEG, mseg);	cur_proc->psize.ustack = (long)sp;	/* Top of user stack */#ifdef TEXECprintf("EXEC: saveing args \n");#endif 	/* Saves arguments here either for codata exec */	sp = saveargs(sp, aargv, aenv);	setusp(sp);				/* Sets the user sp to here */	/* Modify process table entry for this new process */	cur_proc->pid = cur_proc->pid;		/* Same proccess id */	cur_proc->reg->sr = 0x0000;		/* Sets user state */	cur_proc->reg->usp = (long)sp;	cur_proc->reg->pc = psize.entry;	cur_proc->psize.fmagic = psize.fmagic;	cur_proc->psize.entry = psize.entry;	cur_proc->psize.tsize = psize.tsize;	cur_proc->psize.dsize = psize.dsize;	cur_proc->psize.bsize = psize.bsize;	cur_proc->psize.ebss = (unsigned)(datastart+psize.dsize+psize.bsize);	cur_proc->object.majdev = object.majdev;	cur_proc->object.mindev = object.mindev;	cur_proc->object.inode = object.inode;	strncpy(cur_proc->name, name, PATHLEN);	cur_proc->majseg = PROCSEG;	cur_proc->minseg = mseg;#ifdef TEXECprintf("EXEC: GETING program\n");#endif	/* If inswap space recover program from here */	if(swap){		if(stickin(&object)){			freeiptr(iptr);			endmem(PROCSEG, mseg);			smaskoff(cur_proc,smask);			kexit(1 << 8);		}	}	/* Else get program from opened file */	else {		if(fromfile(&file, &psize)){			f_close(&file);			freeiptr(iptr);			endmem(PROCSEG, mseg);			smaskoff(cur_proc,smask);			kexit(1 << 8);		}		if(iptr->i_mode & ISVTX) sticky = 1;	} 	if(!swap) f_close(&file);	/* set BSS to zeroes */	byteclr((datastart+psize.dsize),psize.bsize);	/* Sets euid, egid on execution */	if(iptr->i_mode & ISUID) cur_proc->euid = iptr->i_uid;	if(iptr->i_mode & ISGID) cur_proc->egid = iptr->i_gid;	/* If sticky process save in swap area */	if(sticky) stickout(cur_proc);#ifdef TEXECps();#endif	cur_proc->flag = SLOAD;	cur_proc->stat = SRUN;	setmempid(PROCSEG, mseg, cur_proc->pid);	freeiptr(iptr);	smaskoff(cur_proc,smask);	/* Reallow those nasty interupts */	return 0;}/* *	Inbin()		Determins whether the program is internal or not */inbin(name)char	*name;{	if(strncmp(name, INBIN, strlen(INBIN))) return 0;	return 1;}/* *	Exinbin()	Executes internal program *			Checks if program exists, if so resets the process *			table entry for 0 text, data and bss size, places *			All arguments on user stack, and executes the *			Internal process in super state with arguments pointing *			to argc, argv, and env on the user stack. */exinbin(name, argv, env)char	*name;char	*argv[], *env[];{	int	c;	short	smask;	long	*sp;	struct	Comm *coms;	/* Finds comand name entry in internal kernal command jump table */	coms = kercom;	while(coms->c_name && strcmp(coms->c_name, (name + strlen(INBIN)))) coms++;	if(!coms->c_name) return error(ENOENT);	smask = smaskon(cur_proc, EVALL);	/* Mask process switch */	/* Store all arguments in argarea */ 	if(storeargs(argv, env) == -1){		smaskoff(cur_proc, smask);		return -1;	}	/* Sets up stack pointer to end of stack (user stack) */	sp = (long *)memend(PROCSEG, 0);	cur_proc->psize.ustack = (long)sp;	/* Top of user stack */ 	/* Saves arguments here either for codata exec */	sp = saveargs(sp, aargv, aenv);	/* Modify process table entry for this new process */	/* Clears signals to default if they are not ignored ones */	for(c=0; c<NSIG; c++){		if(cur_proc->signals[c].func != SIG_IGN){			cur_proc->signals[c].func = SIG_DFL;		}

⌨️ 快捷键说明

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