Пример #1
0
// Grow or shrink a file to exactly a specified size.
// If growing a file, then fills the new space with zeros.
// Returns 0 if successful, or returns -1 and sets errno on error.
int
fileino_truncate(int ino, off_t newsize)
{
	assert(fileino_isvalid(ino));
	assert(newsize >= 0 && newsize <= FILE_MAXSIZE);

	size_t oldsize = files->fi[ino].size;
	size_t oldpagelim = ROUNDUP(files->fi[ino].size, PAGESIZE);
	size_t newpagelim = ROUNDUP(newsize, PAGESIZE);
	if (newsize > oldsize) {
		// Grow the file and fill the new space with zeros.
		sys_get(SYS_PERM | SYS_READ | SYS_WRITE, 0, NULL, NULL,
			FILEDATA(ino) + oldpagelim,
			newpagelim - oldpagelim);
		memset(FILEDATA(ino) + oldsize, 0, newsize - oldsize);
	} else if (newsize > 0) {
		// Shrink the file, but not all the way to empty.
		// Would prefer to use SYS_ZERO to free the file content,
		// but SYS_ZERO isn't guaranteed to work at page granularity.
		sys_get(SYS_PERM, 0, NULL, NULL,
			FILEDATA(ino) + newpagelim, FILE_MAXSIZE - newpagelim);
	} else {
		// Shrink the file to empty.  Use SYS_ZERO to free completely.
		sys_get(SYS_ZERO, 0, NULL, NULL, FILEDATA(ino), FILE_MAXSIZE);
	}
	files->fi[ino].size = newsize;
	files->fi[ino].ver++;	// truncation is always an exclusive change
	return 0;
}
Пример #2
0
/*
 * Register application in ctx. As the matter of fact it is normal
 * to register it in app->ctx, but that depends on what you want.
 */
int
register_app(struct ctx_t *ctx, struct app_t *app)
{
	struct str_t *app_name;

	log(ctx, 0, "register app: %s\n", app->name);

	/* Main application */
	app_name = sys_get(ctx, "app");

	if(NULL == app_name)
	{
		app_name = sys_create(ctx, "app", T_STR);

		if(NULL == app_name)
			return E_NOMEM;
	}
	else
		log(ctx,1,"already got app [%s]!\n", app_name);

	app_name->str = app->name;
	app_name->len = strlen(app->name);

	if(!add_app(ctx, app))
		return E_SYS;

	return E_NONE;
}
Пример #3
0
/*
 * Only ints here
 * Priority funcs are now generic so if you need make your own print
 */
void
print_parsers(struct ctx_t *src)
{
	struct parser_t *p;
	struct store_t *sys;
	struct store_t *bs;
	int i,j;

	sys = sys_get(src, "parser");

	if(NULL == sys)
		log(ctx,4,"no parsers found\n");
	else
	{
		log(ctx,4,"found parser array size %d\n", sys->last);

		for(i = 0; i < sys->last; i++)
		{
			bs = store_idx_get(sys, i);

			for(j = 0; j < bs->last; j++)
			{
				p = store_idx_get(bs, j);
				log(src,4,"%s[%d] ", p->name, p->prio);
			}
			log(ctx,4,"\n");
		}
		log(ctx,4,"\n");
	}
}
Пример #4
0
void *
parser_sys_init(struct ctx_t *dst)
{
	struct store_t *sys;

	if(NULL == SYS(dst))
		return NULL;

	log(dst, 4, "parser sys init\n");

	sys = sys_get(dst, "parser");

	if(NULL == sys)
	{
		log(dst, 4, "create parser sys\n");
		sys = sys_create(dst, "parser", T_STORE);

		if(NULL == sys)
			return NULL;

		store_set(sys, 2, sizeof(struct store_t), parserbscmp);
	}

	return sys;
}
Пример #5
0
Файл: app.c Проект: rvba/minuit
void app_init_current( t_app *app)
{
	char path[_PATH_];
	if( sys_get( "pwd", path, _PATH_))
	{
		s_cp( app->path_current, path, _PATH_);
	}
	else
	{
		printf("[APP] Error, can't get current directory\n");
	}
}
Пример #6
0
intptr_t
exec_copyargs(char *const argv[])
{
	// Give the process a nice big 4MB, zero-filled stack.
	sys_get(SYS_ZERO | SYS_PERM | SYS_READ | SYS_WRITE, 0, NULL,
		NULL, (void*)VM_SCRATCHLO, PTSIZE);

#if SOL >= 4
	// How many arguments?
	int argc;
	for (argc = 0; argv[argc] != NULL; argc++)
		;

	// Make room for the argv array
	intptr_t esp = VM_STACKHI;
	intptr_t scratchofs = VM_SCRATCHLO - (VM_STACKHI-PTSIZE);
	esp -= (argc+1) * sizeof(intptr_t);	// room for arguments plus NULL
	intptr_t dargv = esp;

	// Copy the argument strings
	int i;
	for (i = 0; i < argc; i++) {
		int len = strlen(argv[i]);
		esp -= len+1;
		strcpy((void*)esp + scratchofs, argv[i]);
		((intptr_t*)(dargv + scratchofs))[i] = esp;
	}
	esp &= ~3;	// get esp word-aligned again

	// Push the arguments to main()
	esp -= 4;	*(intptr_t*)(esp + scratchofs) = dargv;
	esp -= 4;	*(intptr_t*)(esp + scratchofs) = argc;
#else // ! SOL >= 4
	// Lab 4: insert your code here to copy our command-line arguments
	// onto the new process's stack, taking into account the fact that
	// the stack area is mapped at VM_SCRATCHLO to VM_SCRATCHLO+PTSIZE
	// in _our_ address space while we're copying the arguments,
	// but the pointers we're writing into this space will be
	// interpreted by the newly executed process,
	// where the stack will be mapped from VM_STACKHI-PTSIZE to VM_STACKHI.
	warn("exec_copyargs not implemented yet");
	intptr_t esp = VM_STACKHI;	// no arguments - fix this.
#endif // ! SOL >= 4

	// Copy the stack into its correct position in child 0.
	sys_put(SYS_COPY, 0, NULL, (void*)VM_SCRATCHLO,
		(void*)VM_STACKHI-PTSIZE, PTSIZE);

	return esp;
}
Пример #7
0
/*
 * Add app to context
 * Creates system called app->name and put app in it
 */
int
add_app(struct ctx_t *ctx, struct app_t *app)
{
	struct app_t *sys;

	sys = sys_get(ctx, app->name);

	if(NULL == sys)
	{
		sys = sys_create(ctx, app->name, T_APP);

		if(NULL == sys)
			return E_NOMEM;
	}
	else
		log(ctx,1,"warn: already got [%s] system!\n", app->name);

	memcpy(sys, app, sizeof(struct app_t)); 
	return E_NONE;
}
Пример #8
0
// Write 'count' data elements each of size 'eltsize'
// starting at absolute byte offset 'ofs' within the file in inode 'ino'.
// Returns the number of elements actually written,
// which should always be equal to the 'count' input parameter
// unless an error occurs, in which case this function
// returns -1 and sets errno appropriately.
// Since PIOS files can be up to only FILE_MAXSIZE bytes in size (4MB),
// one particular reason an error might occur is if an application
// tries to grow a file beyond this maximum file size,
// in which case this function generates the EFBIG error.
ssize_t
fileino_write(int ino, off_t ofs, const void *buf, size_t eltsize, size_t count)
{
	assert(fileino_isreg(ino));
	assert(ofs >= 0);
	assert(eltsize > 0);

	fileinode *fi = &files->fi[ino];
	assert(fi->size <= FILE_MAXSIZE);

#if SOL >= 4
	// Return an error if we'd be growing the file too big.
	size_t len = eltsize * count;
	size_t lim = ofs + len;
	if (lim < ofs || lim > FILE_MAXSIZE) {
		errno = EFBIG;
		return -1;
	}

	// Grow the file as necessary.
	if (lim > fi->size) {
		size_t oldpagelim = ROUNDUP(fi->size, PAGESIZE);
		size_t newpagelim = ROUNDUP(lim, PAGESIZE);
		if (newpagelim > oldpagelim)
			sys_get(SYS_PERM | SYS_READ | SYS_WRITE, 0, NULL, NULL,
				FILEDATA(ino) + oldpagelim,
				newpagelim - oldpagelim);
		fi->size = lim;
	}

	// Write the data.
	memmove(FILEDATA(ino) + ofs, buf, len);
	return count;
#else	// ! SOL >= 4
	// Lab 4: insert your file writing code here.
	warn("fileino_write() not implemented");
	errno = EINVAL;
	return -1;
#endif	// ! SOL >= 4
}
Пример #9
0
Файл: app.c Проект: rvba/minuit
void app_init_home( t_app *app)
{
	int size = 16;
	char name[size];

	int size_home = _PATH_;
	char path_home[size_home]; 

	sys_get( "whoami", name, size);
	
	s_cp( path_home, "/home/", size_home);
	s_cat( path_home, name, size);
	s_cat( path_home, "/.minuit/", size_home);

	if( !sys_file_exists( path_home))
	{
		printf("Creating minuit home directory: %s\n", path_home);
		mkdir( path_home, 0777);
	}

	s_cp( app->path_home, path_home, _PATH_);
}
Пример #10
0
void *
parser_scope_init(struct ctx_t *scope)
{
	struct store_t *sys;

	if(NULL == SYS(scope))
		return NULL;

	sys = sys_get(scope, "parser");

	if(NULL == sys)
	{
		sys = sys_create(scope, "parser", T_STORE);

		if(NULL == sys)
			return NULL;

		store_set(sys, 2, sizeof(struct store_t), pbscmp);
	}

	return sys;
}
Пример #11
0
void migrate(int node)
{
	cprintf("testmigr: migrating to node %d...\n", node);
	sys_get(0, (node << 8) | 0, NULL, NULL, NULL, 0);
	cprintf("testmigr: now on node %d.\n", node);
}
Пример #12
0
void
proc_check(void)
{
	// Spawn 2 child processes, executing on statically allocated stacks.

	cprintf("in proc_check()\n");
	int i;
	for (i = 0; i < 4; i++) {
		// Setup register state for child
		uint32_t *esp = (uint32_t*) &child_stack[i][PAGESIZE];
		*--esp = i;	// push argument to child() function
		*--esp = 0;	// fake return address
		child_state.tf.eip = (uint32_t) child;
		child_state.tf.esp = (uint32_t) esp;

		// Use PUT syscall to create each child,
		// but only start the first 2 children for now.
		cprintf("spawning child %d\n", i);
		sys_put(SYS_REGS | (i < 2 ? SYS_START : 0), i, &child_state,
			NULL, NULL, 0);
	}
	cprintf("proc_check() created childs\n");


	// Wait for both children to complete.
	// This should complete without preemptive scheduling
	// when we're running on a 2-processor machine.
	for (i = 0; i < 2; i++) {
		cprintf("waiting for child %d\n", i);
		sys_get(SYS_REGS, i, &child_state, NULL, NULL, 0);
	}
	cprintf("proc_check() 2-child test succeeded\n");

	// (Re)start all four children, and wait for them.
	// This will require preemptive scheduling to complete
	// if we have less than 4 CPUs.
	cprintf("proc_check: spawning 4 children\n");
	for (i = 0; i < 4; i++) {
		cprintf("spawning child %d\n", i);
		sys_put(SYS_START, i, NULL, NULL, NULL, 0);
	}

	// Wait for all 4 children to complete.
	for (i = 0; i < 4; i++)
		sys_get(0, i, NULL, NULL, NULL, 0);
	cprintf("proc_check() 4-child test succeeded\n");

	// Now do a trap handling test using all 4 children -
	// but they'll _think_ they're all child 0!
	// (We'll lose the register state of the other children.)
	i = 0;
	sys_get(SYS_REGS, i, &child_state, NULL, NULL, 0);
		// get child 0's state
	assert(recovargs == NULL);
	do {
		sys_put(SYS_REGS | SYS_START, i, &child_state, NULL, NULL, 0);
		sys_get(SYS_REGS, i, &child_state, NULL, NULL, 0);
		if (recovargs) {	// trap recovery needed
			trap_check_args *args = recovargs;
			cprintf("recover from trap %d\n",
				child_state.tf.trapno);
			child_state.tf.eip = (uint32_t) args->reip;
			args->trapno = child_state.tf.trapno;
		} else
			assert(child_state.tf.trapno == T_SYSCALL);
		i = (i+1) % 4;	// rotate to next child proc
	} while (child_state.tf.trapno != T_SYSCALL);
	assert(recovargs == NULL);

	cprintf("proc_check() trap reflection test succeeded\n");

	cprintf("proc_check() succeeded!\n");
}
Пример #13
0
int
exec_readelf(const char *path)
{
	// We'll load the ELF image into a scratch area in our address space.
	sys_get(SYS_ZERO, 0, NULL, NULL, (void*)VM_SCRATCHLO, EXEMAX);

	// Open the ELF image to load.
	filedesc *fd = filedesc_open(NULL, path, O_RDONLY, 0);
	if (fd == NULL)
		return -1;
	void *imgdata = FILEDATA(fd->ino);
	size_t imgsize = files->fi[fd->ino].size;

	// Make sure it looks like an ELF image.
	elfhdr *eh = imgdata;
	if (imgsize < sizeof(*eh) || eh->e_magic != ELF_MAGIC) {
		warn("exec_readelf: ELF header not found");
		goto err;
	}

	// Load each program segment into the scratch area
	proghdr *ph = imgdata + eh->e_phoff;
	proghdr *eph = ph + eh->e_phnum;
	if (imgsize < (void*)eph - imgdata) {
		warn("exec_readelf: ELF program header truncated");
		goto err;
	}
	for (; ph < eph; ph++) {
		if (ph->p_type != ELF_PROG_LOAD)
			continue;

		// The executable should fit in the first 4MB of user space.
		intptr_t valo = ph->p_va;
		intptr_t vahi = valo + ph->p_memsz;
		if (valo < VM_USERLO || valo > VM_USERLO+EXEMAX ||
				vahi < valo || vahi > VM_USERLO+EXEMAX) {
			warn("exec_readelf: executable image too large "
				"(%d bytes > %d max)", vahi-valo, EXEMAX);
			goto err;
		}

		// Map all pages the segment touches in our scratch region.
		// They've already been zeroed by the SYS_ZERO above.
		intptr_t scratchofs = VM_SCRATCHLO - VM_USERLO;
		intptr_t pagelo = ROUNDDOWN(valo, PAGESIZE);
		intptr_t pagehi = ROUNDUP(vahi, PAGESIZE);
		sys_get(SYS_PERM | SYS_READ | SYS_WRITE, 0, NULL, NULL,
			(void*)pagelo + scratchofs, pagehi - pagelo);

		// Initialize the file-loaded part of the ELF image.
		// (We could use copy-on-write if SYS_COPY
		// supports copying at arbitrary page boundaries.)
		intptr_t filelo = ph->p_offset;
		intptr_t filehi = filelo + ph->p_filesz;
		if (filelo < 0 || filelo > imgsize
				|| filehi < filelo || filehi > imgsize) {
			warn("exec_readelf: loaded section out of bounds");
			goto err;
		}
		memcpy((void*)valo + scratchofs, imgdata + filelo,
			filehi - filelo);

		// Finally, remove write permissions on read-only segments.
		if (!(ph->p_flags & ELF_PROG_FLAG_WRITE))
			sys_get(SYS_PERM | SYS_READ, 0, NULL, NULL,
				(void*)pagelo + scratchofs, pagehi - pagelo);
	}

	// Copy the ELF image into its correct position in child 0.
	sys_put(SYS_COPY, 0, NULL, (void*)VM_SCRATCHLO,
		(void*)VM_USERLO, EXEMAX);

	// The new program should have the same entrypoint as we do!
	if (eh->e_entry != (intptr_t)start) {
		warn("exec_readelf: executable has a different start address");
		goto err;
	}

	filedesc_close(fd);	// Done with the ELF file
	return 0;

err:
	filedesc_close(fd);
	return -1;
}