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

📄 exec.cc

📁 南京航空航天大学开发的一个类Unix和Linux的操作系统,好不好看看就知道了,
💻 CC
字号:
#include <lib/root.h>#include <lib/errno.h>#include <lib/string.h>#include <lib/gcc.h>#include <mm/mm.h>#include <fs/inode.h>#include <fs/buf.h>#include <boot/elf.h> #include <asm/frame.h>#include <mm/allocpage.h>static void flush(){		if (lastusedmath == curr)		lastusedmath = NULL;	curr->mm->unmapuspace();	curr->sigset.clear();	curr->sigvec->clearonexec();	curr->fdvec->closeonexec();	if (lastusedmath == curr)		lastusedmath = NULL;	curr->flags &= ~TFUSEDMATH;}#define MAXPH 6static int loadelf(inode_t * exe, buf_t * head, vaddr_t * entry){	elfphdr_t ph[MAXPH], *p;	int e;	elfhdr_t * eh = (elfhdr_t*) head->data;	*entry = 0;	if (eh->phnum > 6) 		return ENOEXEC;	if ((e = exe->read(eh->phoff, ph, sizeof(elfphdr_t)*eh->phnum)) < 0)		return e;#if 0	for (p = ph; p < ph + eh->phnum; p++) {		if (p->type != PTLOAD)			continue;		printf("%d:%x--%x ", p->type, p->vaddr, p->offset);	}	printf("\n");#endif	for (p = ph; p < ph + eh->phnum; p++) {		if (p->type != PTLOAD)			continue;		int prot = 0;		if (p->flags & PFR)			prot |= PROTR;		if (p->flags & PFW)			prot |= PROTW;		if (p->flags & PFX)			prot |= PROTX;		if (e = curr->mm->mmap(p->vaddr, p->vaddr + p->filesz,			prot, MAPFIXED|MAPPRIVATE, exe, p->offset))			return e;		if (p->flags & PFX)			continue;		vaddr_t bss = p->vaddr + p->filesz;		vaddr_t ebss = p->vaddr + p->memsz;		curr->mm->clearfrag(bss, pageup(bss));		/* an empty bss will be created if (bss == ebss) */		if (e = curr->mm->anonmap(pageup(bss), pageup(ebss),			prot, MAPFIXED|MAPPRIVATE))			return e;	}	*entry = eh->entry;	return 0;}static int matchelf(buf_t * head){	elfhdr_t * e = (elfhdr_t *) head->data;	return  (e->ident[EIMAG0] == ELFMAG0) && 		(e->ident[EIMAG1] == ELFMAG1) && 		(e->ident[EIMAG2] == ELFMAG2) && 		(e->ident[EIMAG3] == ELFMAG3) && 		(e->ident[EICLASS]== ELFCLASS32) && 		(e->ident[EIDATA] == ELFDATA2LSB) && 		(e->type == ETEXEC) && 		(e->machine == EM386 || e->machine == EM486) && 		(e->phnum <= 3) && 		(e->phentsize == sizeof(elfphdr_t));}static int matchscript(buf_t * head){	return head->data[0] == '#' && head->data[1] == '!';}/* interpbasename interpargument pathname argv[1] ... */static int parsescript(buf_t * head, ustack_t * ustack, inode_t ** interp){	char buf[256];	char * tmp, * tok;	int e;	*interp = NULL;	memcpy(buf, head->data + 2, 256);	buf[255] = 0;	if  (!(tmp = strchr(buf, '\n')))		return ENOEXEC;	*tmp = 0;	scanstrprev_t scan(buf, " \t");	if (!scan.nlefttok())		return ENOEXEC;	for (; scan.more(); scan.prev()) {		tok = scan.curtok();		if (scan.nlefttok() == 1) {			if (e = namei(ISTAT, tok, interp))				return e;			if (tmp = strrchr(tok, '/'))				tok = tmp + 1;		}		if (e = ustack->pushkstr(tok))			return e;		ustack->argc++;	}	return 0;}static int count(char ** vec){	int sum = 0;	while (*vec++) sum++;	return sum;}static int check(inode_t * inode, buf_t ** head, uid_t * euid, gid_t * egid){	*head = NULL;	if (!inode->isreg() || inode->deny(IX))		return EACCES;	*euid = (inode->mode & SISUID) ? inode->uid : curr->euid;	*egid = (inode->mode & SISGID) ? inode->gid : curr->egid;	bno_t phys;	int e;	if (e = inode->readmap(0, &phys))		return e;	if (phys == BNOTALLOC)		return ENOEXEC;	if (e = readb(inode->dev, phys, head))		return e;	return 0;}asmlinkage int sysexecve(char * pathname, char * argv[], char * envp[]){	regs_t * regs = (regs_t*)&pathname;	int e = 0;	ustack_t ustack;	inode_t * inode = NULL;	buf_t * head = NULL;	uid_t euid;	gid_t egid;#if 0	printf("exec %s ", pathname);	for (int i = 0; argv[i]; i++)		printf("%s ", argv[i]);	printf("\n");#endif	if (lowfreepage(8))		return ENOMEM;	ustack.init();	if (e = namei(ISTAT, pathname, &inode))		goto error;	if (e = check(inode, &head, &euid, &egid))		goto error;	/* exepath arg0 arg1 ...	   interppath interpbase interparg exepath arg1 ... */	if (matchscript(head)) {		if (e = ustack.pushuvec(envp))			goto error;		ustack.envc = count(envp);		if (e = ustack.pushuvec(argv+1))			goto error;		ustack.argc = count(argv+1);		if (e = ustack.pushustr(pathname))			goto error;		ustack.argc++;		inode_t * interp;		if (e = parsescript(head, &ustack, &interp))			goto error;		head->lose();		head = NULL;		inode->lose();		inode = interp;		if (e = check(inode, &head, &euid, &egid))			goto error;	} else {		if (e = ustack.pushuvec(envp))			goto error;		ustack.envc = count(envp);		if (e = ustack.pushuvec(argv))			goto error;		ustack.argc = count(argv);	}	if (!matchelf(head)) {		e = ENOEXEC;		goto error;	}	curr->execname.set(pathname); /* must be donw prior to flush */	curr->euid = euid;	curr->egid = egid;	flush();	vaddr_t entry, initsp;	if (e = loadelf(inode, head, &entry)) {		printf("execve error occured after flush old exec\n");		goto error;	}	if (e = curr->mm->initustack(&ustack, &initsp)) {		printf("execve error occured after flush old exec\n");		goto error;	}	regs->eip = entry;	regs->esp = initsp;	inode->lose();	head->lose();	return 0;error:	if (head) head->lose();	if (inode) inode->lose();	ustack.destroy();	return e;}

⌨️ 快捷键说明

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