예제 #1
0
파일: dfs_raw.c 프로젝트: samkrew/nxp-lpc
/*
+------------------------------------------------------------------------------
| Function    : dfile_raw_rename
+------------------------------------------------------------------------------
| Description : 
|
| Parameters  : 
| Returns     : 
|
+------------------------------------------------------------------------------
*/
int dfile_raw_rename(const char* oldpath, const char* newpath)
{
	struct dfs_filesystem *oldfs, *newfs;
	char *oldfullpath, *newfullpath;
#ifdef DFS_USING_WORKDIR
	/* Change DFS_PATH_MAX to DFS_PATH_MAX + 1, [email protected]*/
	char old_realpath[DFS_PATH_MAX + 1], new_realpath[DFS_PATH_MAX + 1];
#endif

	oldfullpath = (char*)oldpath;
	newfullpath = (char*)newpath;

	if ( oldfullpath[0] != '/' )
	{
#ifdef DFS_USING_WORKDIR
		/* build full path */
		oldfullpath = old_realpath;
		dfs_lock();
		build_fullpath(working_directory, oldpath, oldfullpath);
		dfs_unlock();
#else
		rt_kprintf("bad filename\n");
		return -1;
#endif
	}

	if ( newfullpath[0] != '/' )
	{
#ifdef DFS_USING_WORKDIR
		/* build full path */
		newfullpath = new_realpath;
		dfs_lock();
		build_fullpath(working_directory, newpath, newfullpath);
		dfs_unlock();
#else
		rt_kprintf("bad filename");
		return -1;
#endif
	}

	if ( (oldfs = dfs_filesystem_lookup(oldfullpath)) == RT_NULL )
	{
		return -DFS_STATUS_ENOENT;
	}

	if ( (newfs = dfs_filesystem_lookup(newfullpath)) == RT_NULL )
	{
		return -DFS_STATUS_ENOENT;
	}

	if ( oldfs == newfs )
	{
		if ( oldfs->ops->rename == RT_NULL ) return -DFS_STATUS_ENOSYS;
		
		return oldfs->ops->rename(oldfs, oldfullpath, newfullpath);
	}

	/* not at same file system, return EXDEV */
	return -DFS_STATUS_EXDEV;
}
예제 #2
0
파일: dfs_file.c 프로젝트: 1847123212/SFUD
/**
 * this function will rename an old path name to a new path name.
 *
 * @param oldpath the old path name.
 * @param newpath the new path name.
 *
 * @return 0 on successful, -1 on failed.
 */
int dfs_file_rename(const char *oldpath, const char *newpath)
{
    int result;
    struct dfs_filesystem *oldfs, *newfs;
    char *oldfullpath, *newfullpath;

    result = DFS_STATUS_OK;
    newfullpath = RT_NULL;
    oldfullpath = RT_NULL;

    oldfullpath = dfs_normalize_path(RT_NULL, oldpath);
    if (oldfullpath == RT_NULL)
    {
        result = -DFS_STATUS_ENOENT;
        goto __exit;
    }

    newfullpath = dfs_normalize_path(RT_NULL, newpath);
    if (newfullpath == RT_NULL)
    {
        result = -DFS_STATUS_ENOENT;
        goto __exit;
    }

    oldfs = dfs_filesystem_lookup(oldfullpath);
    newfs = dfs_filesystem_lookup(newfullpath);

    if (oldfs == newfs)
    {
        if (oldfs->ops->rename == RT_NULL)
        {
            result = -DFS_STATUS_ENOSYS;
        }
        else
        {
            if (oldfs->ops->flags & DFS_FS_FLAG_FULLPATH)
                result = oldfs->ops->rename(oldfs, oldfullpath, newfullpath);
            else
                /* use sub directory to rename in file system */
                result = oldfs->ops->rename(oldfs,
                                            dfs_subdir(oldfs->path, oldfullpath),
                                            dfs_subdir(newfs->path, newfullpath));
        }
    }
    else
    {
        result = -DFS_STATUS_EXDEV;
    }

__exit:
    rt_free(oldfullpath);
    rt_free(newfullpath);

    /* not at same file system, return EXDEV */
    return result;
}
예제 #3
0
/**
 * this funciton will rename an old path name to a new path name.
 *
 * @param oldpath the old path name.
 * @param newpath the new path name.
 *
 * @return 0 on successful, -1 on failed.
 */
int dfs_file_rename(const char* oldpath, const char* newpath)
{
	int result;
	struct dfs_filesystem *oldfs, *newfs;
	char *oldfullpath, *newfullpath;

	result = DFS_STATUS_OK;

	oldfullpath = dfs_normalize_path(RT_NULL, oldpath);
	if ( oldfullpath == RT_NULL )
	{
		result = -DFS_STATUS_ENOENT;
		goto __exit;
	}

	newfullpath = dfs_normalize_path(RT_NULL, newpath);
	if ( newfullpath == RT_NULL )
	{
		result = -DFS_STATUS_ENOENT;
		goto __exit;
	}

	if ( (oldfs = dfs_filesystem_lookup(oldfullpath)) == RT_NULL )
	{
		result = -DFS_STATUS_ENOENT;
		goto __exit;
	}

	if ( (newfs = dfs_filesystem_lookup(newfullpath)) == RT_NULL )
	{
		result = -DFS_STATUS_ENOENT;
		goto __exit;
	}

	if ( oldfs == newfs )
	{
		if ( oldfs->ops->rename == RT_NULL )
		{
			result = -DFS_STATUS_ENOSYS;
			goto __exit;
		}

		result = oldfs->ops->rename(oldfs, oldfullpath, newfullpath);
		goto __exit;
	}

	result = -DFS_STATUS_EXDEV;

__exit:
	rt_free(oldfullpath);
	rt_free(newfullpath);

	/* not at same file system, return EXDEV */
	return result;
}
예제 #4
0
파일: dfs_raw.c 프로젝트: samkrew/nxp-lpc
/*
+------------------------------------------------------------------------------
| Function    : dfile_raw_unlink
+------------------------------------------------------------------------------
| Description : 
|
| Parameters  : 
| Returns     : 
|
+------------------------------------------------------------------------------
*/
int dfile_raw_unlink(const char *path)
{
	struct dfs_filesystem* fs;
	char *fullpath, *real_path, search_path[DFS_PATH_MAX + 1];
#ifdef DFS_USING_WORKDIR
	char full_path[DFS_PATH_MAX+1];
#endif
	struct dfs_fd* fd;
	int index, fspathlen;

	/* Make sure we have an absolute path */
	fullpath = (char*)path;
	if ( fullpath[0] != '/')
	{
#ifdef DFS_USING_WORKDIR
		/* build full path */
		fullpath = full_path;
		dfs_lock();
		build_fullpath(working_directory, path, fullpath);
		dfs_unlock();
#else
#ifdef RT_USING_FINSH
		rt_kprintf("bad filename");
#endif
		return -1;
#endif
	}

	if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL) return -DFS_STATUS_ENOENT;

	/* Check whether file is already open */
	dfs_lock();
	for (index = 0; index < DFS_FD_MAX; index++)
	{
		fd = &(fd_table[index]);
		if (fd->fs == RT_NULL) continue;

		build_fullpath(fd->fs->path, fd->path, search_path);
		if (strcmp(fullpath, search_path) == 0)
		{
			dfs_unlock();
			return -DFS_STATUS_EEXIST;
		}
	}
	dfs_unlock();

	fspathlen = strlen(fs->path);
	real_path = search_path;
	rt_memset( real_path, 0, sizeof( real_path ) );
	if (*(fullpath + fspathlen) != '/') strcpy(real_path, "/");
	strcat(real_path, fullpath + fspathlen);

	if (fs->ops->unlink != RT_NULL) return fs->ops->unlink(fs, real_path);

	return -DFS_STATUS_ENOSYS;
}
예제 #5
0
/**
 * this function will get file information.
 *
 * @param path the file path.
 * @param buf the data buffer to save stat description.
 *
 * @return 0 on successful, -1 on failed.
 */
int dfs_file_stat(const char *path, struct stat *buf)
{
	int result;
	char* fullpath;
	struct dfs_filesystem* fs;

	fullpath = dfs_normalize_path(RT_NULL, path);
	if ( fullpath == RT_NULL )
	{
		return -1;
	}

	if ((fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
	{
		dfs_log(DFS_DEBUG_ERROR, ("can't find mounted filesystem on this path:%s", fullpath));
		rt_free(fullpath);
		return -DFS_STATUS_ENOENT;
	}

	if (fullpath[0] == '/' && fullpath[1] == '\0')
	{
		/* it's the root directory */
		buf->st_dev   = 0;

		buf->st_mode = DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
			DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
		buf->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;

		buf->st_size  = 0;
		buf->st_mtime = 0;
		buf->st_blksize = 512;

		/* release full path */
		rt_free(fullpath);

		return DFS_STATUS_OK;
	}
	
	/* get the real file path */
	
	if (fs->ops->stat == RT_NULL)
	{
		rt_free(fullpath);
		dfs_log(DFS_DEBUG_ERROR, ("the filesystem didn't implement this function"));
		return -DFS_STATUS_ENOSYS;
	}

	if (dfs_subdir(fs->path, fullpath) == RT_NULL)
		result = fs->ops->stat(fs, "/", buf);
	else
		result = fs->ops->stat(fs, dfs_subdir(fs->path, fullpath), buf);

	rt_free(fullpath);

	return result;
}
예제 #6
0
/** 
 * @ingroup Fd
 *
 * This function will return whether this file has been opend.
 * 
 * @param pathname the file path name.
 *
 * @return 0 on file has been open successfully, -1 on open failed.
 */
int fd_is_open(const char *pathname)
{
	char *fullpath;
	unsigned int index;
	struct dfs_filesystem *fs;
	struct dfs_fd *fd;

	fullpath = dfs_normalize_path(RT_NULL, pathname);
	if (fullpath != RT_NULL)
	{
		char *mountpath;
		fs = dfs_filesystem_lookup(fullpath);
		if (fs == RT_NULL)
		{
			/* can't find mounted file system */
			rt_free(fullpath);

			return -1;
		}

		/* get file path name under mounted file system */
		if (fs->path[0] == '/' && fs->path[1] == '\0')
			mountpath = fullpath;
		else 
			mountpath = fullpath + strlen(fs->path);

		dfs_lock();
		for (index = 0; index < DFS_FD_MAX; index++)
		{
			fd = &(fd_table[index]);
			if (fd->fs == RT_NULL) 
				continue;

			if (fd->fs == fs && strcmp(fd->path, mountpath) == 0)
			{
				/* found file in file descriptor table */
				rt_free(fullpath);
				dfs_unlock();

				return 0;
			}
		}
		dfs_unlock();

		rt_free(fullpath);
	}

	return -1;
}
예제 #7
0
파일: dfs_raw.c 프로젝트: samkrew/nxp-lpc
/*
+------------------------------------------------------------------------------
| Function    : dfile_raw_stat
+------------------------------------------------------------------------------
| Description : get the file or directory stat description
|
| Parameters  : path, the file or directory path
|               buf,  the stat description will be saved in it
| Returns     : 
|
+------------------------------------------------------------------------------
*/
int dfile_raw_stat(const char *path, struct dfs_stat *buf)
{
	struct dfs_filesystem* fs;
	char* fullpath, real_path[DFS_PATH_MAX + 1];
#ifdef DFS_USING_WORKDIR
	char full_path[DFS_PATH_MAX + 1];
#endif
	int fspathlen;

	fullpath = (char*)path;
	if ( fullpath[0] != '/' )
	{
#ifdef DFS_USING_WORKDIR
		/* build full path */
		fullpath = full_path;
		dfs_lock();
		build_fullpath(working_directory, path, fullpath);
		dfs_unlock();
#else
#ifdef RT_USING_FINSH
		rt_kprintf("not support working directory, bad filename\n");
#endif
		return -1;
#endif
	}

	if ( (fs = dfs_filesystem_lookup(fullpath)) == RT_NULL )
	{
		dfs_log(DFS_DEBUG_ERROR, ("can't find mounted filesystem on this path:%s", fullpath));
		return -DFS_STATUS_ENOENT;
	}

	fspathlen = strlen(fs->path);
	rt_memset(real_path, 0, sizeof(real_path));
	if (*(fullpath + fspathlen) != '/') strcpy(real_path, "/");
	strcat(real_path, fullpath + fspathlen);

	if (fs->ops->stat == RT_NULL)
	{
		dfs_log(DFS_DEBUG_ERROR, ("the filesystem didn't implement this function"));
		return -DFS_STATUS_ENOSYS;
	}

	return fs->ops->stat(fs, real_path, buf);
}
예제 #8
0
파일: dfs_file.c 프로젝트: 1847123212/SFUD
/**
 * this function will unlink (remove) a specified path file from file system.
 *
 * @param path the specified path file to be unlinked.
 *
 * @return 0 on successful, -1 on failed.
 */
int dfs_file_unlink(const char *path)
{
    int result;
    char *fullpath;
    struct dfs_filesystem *fs;

    /* Make sure we have an absolute path */
    fullpath = dfs_normalize_path(RT_NULL, path);
    if (fullpath == RT_NULL)
    {
        return -DFS_STATUS_EINVAL;
    }

    /* get filesystem */
    if ((fs = dfs_filesystem_lookup(fullpath)) == RT_NULL)
    {
        result = -DFS_STATUS_ENOENT;
        goto __exit;
    }

    /* Check whether file is already open */
    if (fd_is_open(fullpath) == 0)
    {
        result = -DFS_STATUS_EBUSY;
        goto __exit;
    }

    if (fs->ops->unlink != RT_NULL)
    {
        if (!(fs->ops->flags & DFS_FS_FLAG_FULLPATH))
        {
            if (dfs_subdir(fs->path, fullpath) == RT_NULL)
                result = fs->ops->unlink(fs, "/");
            else
                result = fs->ops->unlink(fs, dfs_subdir(fs->path, fullpath));
        }
        else
            result = fs->ops->unlink(fs, fullpath);
    }
    else result = -DFS_STATUS_ENOSYS;

__exit:
    rt_free(fullpath);
    return result;
}
예제 #9
0
파일: dfs_raw.c 프로젝트: samkrew/nxp-lpc
/*
+------------------------------------------------------------------------------
| Function    : dfile_raw_open
+------------------------------------------------------------------------------
| Description : 
|
| Parameters  : 
| Returns     : 
|
+------------------------------------------------------------------------------
*/
int dfile_raw_open(struct dfs_fd* fd, const char *path, int flags)
{
	struct dfs_filesystem* fs;
	char *fullpath;
#ifdef DFS_USING_WORKDIR
	char full_path[DFS_PATH_MAX + 1];
#endif
	int fspathlen, result;

	/* parameter check */
	if ( fd == RT_NULL ) return -DFS_STATUS_EINVAL;

	/* make sure we have an absolute path */
	fullpath = (char*)path;
	if ( fullpath[0] != '/')
	{
#ifdef DFS_USING_WORKDIR
		/* build full path */
		fullpath = &full_path[0];
		dfs_lock();
		build_fullpath(working_directory, path, fullpath);
		dfs_unlock();
#else
#ifdef RT_USING_FINSH
		rt_kprintf("bad filename");
#endif
		return -1;
#endif
	}

	dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath));

	/* find filesystem */
	fs = dfs_filesystem_lookup(fullpath);
	if ( fs == RT_NULL ) return -DFS_STATUS_ENOENT;

	dfs_log(DFS_DEBUG_INFO, ("open in filesystem:%s", fs->ops->name));
	fd->fs = fs;

	/* initilize the fd item */
	fd->type = FT_REGULAR;
	//fd->ref_count = 1;
	fd->flags = flags;
	fd->size = 0;
	fd->pos = 0;

	fspathlen = strlen(fs->path);
	rt_memset(fd->path, 0, DFS_PATH_MAX + 1);
	if (*(fullpath + fspathlen) != '/') strcpy(fd->path, "/");
	strcat(fd->path, fullpath + fspathlen);

	/* specific file system open routine */
	if (fs->ops->open == RT_NULL)
	{
		/* clear fd */
		rt_memset(fd->path, 0, DFS_PATH_MAX + 1);

		fd->type = FT_REGULAR;
		fd->ref_count = 0;
		fd->fs = RT_NULL;
		fd->flags = 0;
		fd->size = 0;
		fd->pos = 0;
		fd->data = RT_NULL;

		return -DFS_STATUS_ENOSYS;
	}

	if ((result = fs->ops->open(fd)) < 0)
	{
		/* clear fd */
		fd->fs = RT_NULL;
		fd->flags = 0;
		fd->data = RT_NULL;

		dfs_log(DFS_DEBUG_INFO, ("open failed"));

		return result;
	}

	fd->flags |= DFS_F_OPEN;
	if ( flags & DFS_O_DIRECTORY )
	{
		fd->type = FT_DIRECTORY;
		fd->flags |= DFS_F_DIRECTORY;
	}

	dfs_log(DFS_DEBUG_INFO, ("open successful"));
	return 0;
}
예제 #10
0
/**
 * This function will do a executable program with main function and parameters.
 *
 * @param path the full path of application module
 * @param cmd_line the command line of program
 * @param size the size of command line of program
 *
 * @return the module object
 */
rt_module_t rt_module_exec_cmd(const char *path, const char* cmd_line, int line_size)
{
    struct dfs_filesystem *fs;
    appentry_t fptr;
    HINSTANCE hinstlib;
	rt_module_t module;

	char * winpath = RT_NULL;
    char * name = RT_NULL;
	char *full_path = RT_NULL;

    RT_DEBUG_NOT_IN_INTERRUPT;

    /* check parameters */
    RT_ASSERT(path != RT_NULL);

	if (*path != '/')
	{
		full_path = dfs_normalize_path(RT_NULL, path);
	}
	else
	{
		full_path = (const char*)path;
	}

    /* app module should only in DFS_WIN32 */
    fs = dfs_filesystem_lookup(full_path);
    if ((fs == RT_NULL) || (strcmp(fs->ops->name,"wdir") != 0))
    {
        rt_kprintf("invalid path: %s\n", path);
        goto __exit;
    }

    /* change path */
    // len = strlen(full_path + 1);
    if ((winpath = dfs_win32_dirdup((char *)full_path)) == RT_NULL)
    {
        rt_kprintf("out of memory, exit", path);
		goto __exit;
    }

    hinstlib = LoadLibrary(winpath);
    if (hinstlib == NULL)
    {
        rt_kprintf("error: unable to open %s\n", winpath);
		goto __exit;
    }

    fptr = (appentry_t)GetProcAddress(hinstlib, "main");
    if (fptr == NULL)
    {
        rt_kprintf("error: unable to find function in %s\n", winpath);
        FreeLibrary(hinstlib);
		goto __exit;
    }

	/* release winpath */
	rt_free(winpath);

    /* get the name of the module */
    name = _module_name(path);

    /* allocate module */
    module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module, name);
    if (!module) 
	{
		goto __exit;
	}

    module->nref = 0;
    module->module_entry = fptr;

    /* init module object container */
    rt_module_init_object_container(module);

    /* increase module reference count */
    module->nref ++;

    if (module->module_entry != 0)
    {
		/* set module argument */
		module->module_cmd_line = (rt_uint8_t*)rt_malloc(line_size + 1);
		rt_memcpy(module->module_cmd_line, cmd_line, line_size);
		module->module_cmd_line[line_size] = '\0';
		module->module_cmd_size = line_size;

#ifdef RT_USING_SLAB
        /* init module memory allocator */
        module->mem_list = RT_NULL;

        /* create page array */
        module->page_array =
            (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
        module->page_cnt = 0;
#endif

		/* create module thread */
		module->module_thread =	rt_thread_create(name,
			module_main_entry, module,
			2048, RT_THREAD_PRIORITY_MAX - 2, 10);

        /* set module id */
        module->module_thread->module_id = (void *)module;
        module->parent.flag = RT_MODULE_FLAG_WITHENTRY;

        /* startup module thread */
        rt_thread_startup(module->module_thread);
    }
    else
    {
        /* without entry point */
        module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY;
    }

#ifdef RT_USING_HOOK
    if (rt_module_load_hook != RT_NULL)
    {
        rt_module_load_hook(module);
    }
#endif

    rt_free(name);
    return module;

__exit:
	if (full_path != path) rt_free(full_path);
	if (name != RT_NULL)   rt_free(full_path);
	if (winpath != RT_NULL)rt_free(winpath);

	return RT_NULL;
    /* FreeLibrary(hinstlib); */
}
예제 #11
0
/**
 * This function will load a module from a file
 *
 * @param path the full path of application module
 *
 * @return the module object
 */
rt_module_t rt_module_open(const char *path)
{
    struct dfs_filesystem *fs;
    appentry_t fptr;
    HINSTANCE hinstlib;
    int len;
    char * winpath;
    rt_module_t module;
    char * name;

    RT_DEBUG_NOT_IN_INTERRUPT;

    /* check parameters */
    RT_ASSERT(path != RT_NULL);

    /* app module should only in DFS_WIN32 */
    fs = dfs_filesystem_lookup(path);
    if ((fs == RT_NULL) || (strcmp(fs->ops->name,"wdir") != 0))
    {
        rt_kprintf("invalid path: %s\n", path);
        return RT_NULL;
    }

    /* change path */
    len = strlen(path+1);
    if ((winpath = dfs_win32_dirdup((char *)path)) == RT_NULL)
    {
        rt_kprintf("out of memory, exit", path);
        return RT_NULL;
    }

    hinstlib = LoadLibrary(winpath);
    if (hinstlib == NULL)
    {
        rt_kprintf("error: unable to open %s\n", winpath);
        return RT_NULL;
    }

    fptr = (appentry_t)GetProcAddress(hinstlib, "main");
    if (fptr == NULL)
    {
        rt_kprintf("error: unable to find function in %s\n", winpath);
        FreeLibrary(hinstlib);
        return RT_NULL;
    }

    /* get the name of the module */
    name = _module_name(path);

    /* allocate module */
    module = (struct rt_module *)rt_object_allocate(RT_Object_Class_Module,
        name);
    if (!module)
        return RT_NULL;

    module->nref = 0;
    module->module_entry = fptr;

    /* init module object container */
    rt_module_init_object_container(module);

    /* increase module reference count */
    module->nref ++;

    if (module->module_entry != 0)
    {
        rt_uint32_t *stack_size;
        rt_uint8_t  *priority;

#ifdef RT_USING_SLAB
        /* init module memory allocator */
        module->mem_list = RT_NULL;

        /* create page array */
        module->page_array = 
            (void *)rt_malloc(PAGE_COUNT_MAX * sizeof(struct rt_page_info));
        module->page_cnt = 0;
#endif

        /* get the main thread stack size */
        module->stack_size = 2048;
        module->thread_priority = RT_THREAD_PRIORITY_MAX - 2;

        /* create module thread */
        module->module_thread =
            rt_thread_create(name,
            (void(*)(void *))module->module_entry,
            RT_NULL,
            module->stack_size,
            module->thread_priority,
            10);

        RT_DEBUG_LOG(RT_DEBUG_MODULE, ("thread entry 0x%x\n",
            module->module_entry));

        /* set module id */
        module->module_thread->module_id = (void *)module;
        module->parent.flag = RT_MODULE_FLAG_WITHENTRY;

        /* startup module thread */
        rt_thread_startup(module->module_thread);
    }
    else
    {
        /* without entry point */
        module->parent.flag |= RT_MODULE_FLAG_WITHOUTENTRY;
    }

#ifdef RT_USING_HOOK
    if (rt_module_load_hook != RT_NULL)
    {
        rt_module_load_hook(module);
    }
#endif

    rt_free(name);
    return module;
    /* FreeLibrary(hinstlib); */
}
예제 #12
0
/**
 * this function will open a file which specified by path with specified flags.
 *
 * @param fd the file descriptor pointer to return the corresponding result.
 * @param path the spaciefied file path.
 * @param flags the flags for open operator.
 *
 * @return 0 on successful, -1 on failed.
 */
int dfs_file_open(struct dfs_fd* fd, const char *path, int flags)
{
	struct dfs_filesystem* fs;
	char *fullpath;
	int result;

	/* parameter check */
	if ( fd == RT_NULL ) return -DFS_STATUS_EINVAL;

	/* make sure we have an absolute path */
	fullpath = dfs_normalize_path(RT_NULL, path);
	if (fullpath == RT_NULL)
	{
		return -1;
	}

	dfs_log(DFS_DEBUG_INFO, ("open file:%s", fullpath));

	/* find filesystem */
	fs = dfs_filesystem_lookup(fullpath);
	if ( fs == RT_NULL )
	{
		rt_free(fullpath); /* release path */
		return -DFS_STATUS_ENOENT;
	}

	dfs_log(DFS_DEBUG_INFO, ("open in filesystem:%s", fs->ops->name));
	fd->fs = fs;

	/* initilize the fd item */
	fd->type = FT_REGULAR;
	fd->flags = flags;
	fd->size = 0;
	fd->pos = 0;

	if (dfs_subdir(fs->path, fullpath) == RT_NULL)
		fd->path = rt_strdup("/");
	else
		fd->path = rt_strdup(dfs_subdir(fs->path, fullpath));
	rt_free(fullpath);
	dfs_log(DFS_DEBUG_INFO, ("actul file path: %s\n", fd->path));

	/* specific file system open routine */
	if (fs->ops->open == RT_NULL)
	{
		/* clear fd */
		rt_free(fd->path);		
		rt_memset(fd, 0, sizeof(*fd));

		return -DFS_STATUS_ENOSYS;
	}

	if ((result = fs->ops->open(fd)) < 0)
	{
		/* clear fd */
		rt_free(fd->path);
		rt_memset(fd, 0, sizeof(*fd));

		dfs_log(DFS_DEBUG_INFO, ("open failed"));

		return result;
	}

	fd->flags |= DFS_F_OPEN;
	if ( flags & DFS_O_DIRECTORY )
	{
		fd->type = FT_DIRECTORY;
		fd->flags |= DFS_F_DIRECTORY;
	}

	dfs_log(DFS_DEBUG_INFO, ("open successful"));
	return 0;
}