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

📄 main.c

📁 微内核软实时操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
static int fs_unlink(tcb_t tcb, struct path_msg *msg){	char path[PATH_MAX];	if (msg->path == NULL)		return ENOENT;	tcb_conv(tcb, msg->path, path);	return sys_unlink(path);}static int fs_stat(tcb_t tcb, struct stat_msg *msg){	char path[PATH_MAX];	struct stat *st;	file_t fp;	int err;	tcb_conv(tcb, msg->path, path);	if ((err = sys_open(path, O_RDONLY, 0, &fp)) != 0)		return err;	st = &msg->st;	err = sys_fstat(fp, st);	sys_close(fp);	return err;}static int fs_getcwd(tcb_t tcb, struct path_msg *msg){	strcpy(msg->path, tcb->cwd);	return 0;}static int fs_dup(tcb_t tcb, struct msg *msg){	file_t fp;	int old_fd, new_fd;	old_fd = msg->data[0];	if (old_fd >= OPEN_MAX)		return EBADF;	fp = tcb->file[old_fd];	if (fp == NULL)		return EBADF;	/* Find smallest empty slot as new fd. */	for (new_fd = 0; new_fd < OPEN_MAX; new_fd++)		if (tcb->file[new_fd] == NULL)			break;	if (new_fd == OPEN_MAX)		return EMFILE;	tcb->file[new_fd] = fp;	msg->data[0] = new_fd;	return 0;}static int fs_dup2(tcb_t tcb, struct msg *msg){	file_t fp, org;	int old_fd, new_fd;	int err;	old_fd = msg->data[0];	new_fd = msg->data[1];	if (old_fd >= OPEN_MAX || new_fd >= OPEN_MAX)		return EBADF;	fp = tcb->file[old_fd];	if (fp == NULL)		return EBADF;	org = tcb->file[new_fd];	if (org != NULL) {		/* Close previous file if it's opened. */		err = sys_close(org);	}	tcb->file[new_fd] = fp;	msg->data[0] = new_fd;	return 0;}/* * Copy parent's cwd & file/directory descriptor to child's. */static int fs_fork(tcb_t tcb, struct msg *msg){	tcb_t new_tcb;	file_t fp;	int err, i;	if ((err = tcb_alloc((task_t)msg->data[0], &new_tcb)) != 0)		return err;	/*	 * Copy task related data	 */	new_tcb->cwd_fp = tcb->cwd_fp;	strcpy(new_tcb->cwd, tcb->cwd);	for (i = 0; i < OPEN_MAX; i++) {		fp = tcb->file[i];		new_tcb->file[i] = fp;		/* Increment file reference if it's already opened. */		if (fp != NULL) {			vref(fp->f_vnode);			fp->f_count++;		}	}	if (new_tcb->cwd_fp)		new_tcb->cwd_fp->f_count++;	/* Increment cwd's reference count */	if (new_tcb->cwd_fp)		vref(new_tcb->cwd_fp->f_vnode);	return 0;}/* * fs_exec() is called for POSIX exec(). * It closes all directory stream. * File descriptor which is marked close-on-exec are also closed. */static int fs_exec(tcb_t tcb, struct msg *msg){	task_t old_task, new_task;	tcb_t target;	file_t fp;	int fd;	old_task = (task_t)msg->data[0];	new_task = (task_t)msg->data[1];	if (!(target = tcb_lookup(old_task)))		return EINVAL;	/* Update task id in the tcb. */	tcb_update(target, new_task);	/* Close all directory descriptor */	for (fd = 0; fd < OPEN_MAX; fd++) {		fp = target->file[fd];		if (fp) {			if (fp->f_vnode->v_type == VDIR) {				sys_close(fp);				target->file[fd] = NULL;			}			/* XXX: need to check close-on-exec flag */		}	}	tcb_unlock(target);	return 0;}/* * fs_exit() cleans up data for task's termination. */static int fs_exit(tcb_t tcb, struct msg *msg){	file_t fp;	int fd;	/* Close all files opened by task. */	for (fd = 0; fd < OPEN_MAX; fd++) {		fp = tcb->file[fd];		if (fp != NULL)			sys_close(fp);	}	if (tcb->cwd_fp)		sys_close(tcb->cwd_fp);	tcb_free(tcb);	return 0;}/* * fs_boot() is called by boot tasks. * This can be called even when no fs is mounted. */static int fs_boot(tcb_t tcb, struct msg *msg){	tcb_t t;	int err;	err = tcb_alloc(msg->hdr.task, &t);	return err;}/* * Return version */static int fs_version(tcb_t tcb, struct msg *msg){	return 0;}/* * Shutdown */static int fs_shutdown(tcb_t tcb, struct msg *msg){	sys_sync();	return 0;}static int fs_debug(tcb_t tcb, struct msg *msg){#ifdef DEBUG	printf("<File System Server>\n");	tcb_dump();	vnode_dump();	mount_dump();#endif	return 0;}static void fs_init(void){	const struct vfssw *fs;	struct msg msg;	/*	 * Initialize VFS core.	 */	tcb_init();	bio_init();	vnode_init();	/*	 * Initialize each file system.	 */	for (fs = vfssw_table; fs->vs_name; fs++) {		syslog(LOG_INFO, "Initializing %s\n", fs->vs_name);		fs->vs_init();	}	/*	 * Create task data for ourselves.	 */	msg.hdr.task = task_self();	fs_boot(NULL, &msg);}/* * Run specified routine as a thread. */static int thread_run(void *entry){	task_t self;	thread_t th;	void *stack;	int err;	self = task_self();	if ((err = thread_create(self, &th)) != 0)		return err;	if ((err = vm_allocate(self, &stack, USTACK_SIZE, 1)) != 0)		return err;	if ((err = thread_load(th, entry, stack + USTACK_SIZE)) != 0)		return err;	return thread_resume(th);}/* * Message mapping */static const struct msg_map fsmsg_map[] = {	{STD_VERSION,	fs_version},	{STD_DEBUG,	fs_debug},	{STD_SHUTDOWN,	fs_shutdown},	{FS_MOUNT,	fs_mount},	{FS_UMOUNT,	fs_umount},	{FS_SYNC,	fs_sync},	{FS_OPEN,	fs_open},	{FS_CLOSE,	fs_close},	{FS_MKNOD,	fs_mknod},	{FS_LSEEK,	fs_lseek},	{FS_READ,	fs_read},	{FS_WRITE,	fs_write},	{FS_IOCTL,	fs_ioctl},	{FS_FSYNC,	fs_fsync},	{FS_FSTAT,	fs_fstat},	{FS_OPENDIR,	fs_opendir},	{FS_CLOSEDIR,	fs_closedir},	{FS_READDIR,	fs_readdir,},	{FS_REWINDDIR,	fs_rewinddir},	{FS_SEEKDIR,	fs_seekdir},	{FS_TELLDIR,	fs_telldir},	{FS_MKDIR,	fs_mkdir},	{FS_RMDIR,	fs_rmdir},	{FS_RENAME,	fs_rename},	{FS_CHDIR,	fs_chdir},	{FS_LINK,	fs_link},	{FS_UNLINK,	fs_unlink},	{FS_STAT,	fs_stat},	{FS_GETCWD,	fs_getcwd},	{FS_DUP,	fs_dup},	{FS_DUP2,	fs_dup2},	{FS_BOOT,	fs_boot},	{FS_FORK,	fs_fork},	{FS_EXEC,	fs_exec},	{FS_EXIT,	fs_exit},	{0,		0},};/* * File system thread. */static void fs_thread(void){	struct msg *msg;	const struct msg_map *map;	tcb_t tcb;	int err;	msg = (struct msg *)malloc(MSGBUF_SIZE);	/*	 * Message loop	 */	for (;;) {		/*  Wait for an incoming request. */		if ((err = msg_receive(fs_obj, msg, MSGBUF_SIZE)) != 0)			continue;		err = EINVAL;		map = &fsmsg_map[0];		while (map->code != 0) {			if (map->code == msg->hdr.code) {				if (map->code == FS_BOOT) {					err = fs_boot(NULL, msg);					break;				}				/* Lookup and lock tcb */				tcb = tcb_lookup(msg->hdr.task);				if (tcb == NULL)					break;				/* Dispatch request */				err = map->func(tcb, msg);				if (map->code != FS_EXIT)					tcb_unlock(tcb);				break;			}			map++;		}#ifdef DEBUG_VFS		if (err)			dprintf("code=%x error=%d\n", map->code, err);#endif		/*		 * Reply to the client.		 */		msg->hdr.status = err;		msg_reply(fs_obj, msg, MSGBUF_SIZE);	}}/* * Main routine for file system service */int main(int argc, char *argv[]){	int i;	syslog(LOG_INFO, "Starting File System Server\n");#if NR_FS_THREADS > 1	/* Force enable a multi-thread flag of library */	__isthreaded = 1;#endif	/*	 * Boost current priority.	 */	thread_setprio(thread_self(), PRIO_FS);	/*	 * Initialize file systems.	 */	fs_init();	/*	 * Create an object to expose our service.	 */	if (object_create(OBJNAME_FS, &fs_obj))		panic("fs: fail to create object");	/*	 * Create new server threads.	 */	i = NR_FS_THREADS;	while (--i > 0) {		if (thread_run(fs_thread))			goto err;	}	fs_thread();	exit(0); err:	panic("fs: failed to create thread");	return 0;}

⌨️ 快捷键说明

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