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

📄 file.cxx

📁 eCos操作系统源码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
        FILEIO_RETURN(ret);}//==========================================================================// Change current directory__externC int chdir( const char *path ){    FILEIO_ENTRY();        int ret = 0;    cyg_mtab_entry *mte = cyg_cdir_mtab_entry;    cyg_dir dir = cyg_cdir_dir;    cyg_dir newdir;    const char *name = path;    ret = cyg_mtab_lookup( &dir, &name, &mte );        if( 0 != ret )        FILEIO_RETURN(ENOENT);    LOCK_FS(mte);        ret = mte->fs->chdir( mte, dir, name, &newdir );    UNLOCK_FS(mte);        if( 0 != ret )        FILEIO_RETURN(ret);#ifdef CYGPKG_IO_FILEIO_TRACK_CWD    update_cwd( mte, dir, name );#endif        if( cyg_cdir_mtab_entry != NULL && cyg_cdir_dir != CYG_DIR_NULL )    {        // Now detach from current cyg_cdir. We call the current directory's        // chdir routine with a NULL dir_out pointer.        LOCK_FS(cyg_cdir_mtab_entry);        ret = cyg_cdir_mtab_entry->fs->chdir( cyg_cdir_mtab_entry, cyg_cdir_dir, NULL, NULL );            UNLOCK_FS(cyg_cdir_mtab_entry);        // We really shouldn't get an error here.        if( 0 != ret )            FILEIO_RETURN(ret);    }        cyg_cdir_mtab_entry = mte;    cyg_cdir_dir = newdir;        FILEIO_RETURN(ENOERR);}//==========================================================================// Get file statistics__externC int stat( const char *path, struct stat *buf ){    FILEIO_ENTRY();        int ret = 0;    cyg_mtab_entry *mte = cyg_cdir_mtab_entry;    cyg_dir dir = cyg_cdir_dir;    const char *name = path;    ret = cyg_mtab_lookup( &dir, &name, &mte );        if( 0 != ret )        FILEIO_RETURN(ENOENT);    LOCK_FS( mte );        ret = mte->fs->stat( mte, dir, name, buf );        UNLOCK_FS( mte );        FILEIO_RETURN(ret);}//==========================================================================// Get file configurable pathname variables__externC long pathconf( const char *path, int vname ){    FILEIO_ENTRY();        int ret = 0;    cyg_mtab_entry *mte = cyg_cdir_mtab_entry;    cyg_dir dir = cyg_cdir_dir;    const char *name = path;    ret = cyg_mtab_lookup( &dir, &name, &mte );        if( 0 != ret )        FILEIO_RETURN(ENOENT);    struct cyg_pathconf_info info;    info.name = vname;    info.value = 0;            LOCK_FS( mte );        ret = mte->fs->getinfo( mte, dir, name,                            FS_INFO_CONF, (char *)&info, sizeof(info) );        UNLOCK_FS( mte );        if( 0 != ret )        FILEIO_RETURN(ret);    FILEIO_RETURN_VALUE(info.value);}//==========================================================================// Access() function.// This simply piggybacks onto stat().extern int 	access(const char *path, int amode){    FILEIO_ENTRY();    int ret;    struct stat buf;        ret = stat( path, &buf );    // Translate not found into EACCES if the F_OK bit is    // set.    if( (amode & F_OK) && (ret < 0) && (errno == ENOENT) )        FILEIO_RETURN(EACCES);    // All other errors go straight back to the user.    if( ret < 0 )        FILEIO_RETURN_VALUE(ret);    // At present we do not have any access modes, so there is nothing    // to test.  Just return success for all access modes.        FILEIO_RETURN(ENOERR);}//==========================================================================// getcwd()__externC char *getcwd( char *buf, size_t size ){    FILEIO_ENTRY();    int err = ENOERR;    cyg_mtab_entry *mte = cyg_cdir_mtab_entry;    cyg_dir dir = cyg_cdir_dir;    cyg_getcwd_info info;    if( size == 0 )    {        errno = EINVAL;        FILEIO_RETURN_VALUE(NULL);            }            info.buf = buf;    info.size = size;    LOCK_FS( mte );        err = mte->fs->getinfo( mte, dir, "",                            FS_INFO_GETCWD, (char *)&info, sizeof(info) );        UNLOCK_FS( mte );    if( err == ENOERR )        FILEIO_RETURN_VALUE(buf);    // Attempting to use filesystem support for getcwd() has    // failed.#ifdef CYGPKG_IO_FILEIO_TRACK_CWD    // If this option is set, the current directory path has been    // tracked in chdir(). Just report that value here.        if( size < cwd_size+1 )    {        errno = ERANGE;        FILEIO_RETURN_VALUE(NULL);            }    char *p = my_strcpy( buf, cwd );    *p = '\0';#else    // As a fallback we try to use ".." entries in the directory tree    // to climb back up to the root.  Because we cannot assume that    // any filesystem can handle more than one directory pointer we    // have to do the climbing textually, by manufacturing a path name    // consisting of ".."s. At each level we then scan the parent    // directory looking for the entry for the lower level directory    // by matching st_ino values. This is not guaranteed to work at    // all since there is no requirement on filesystems to support "."    // and "..", or for them to report distinct inode values in    // stat().    static char ddbuf[PATH_MAX];    char *p = buf+size-1;    int ddbufpos;    // Claim lock to serialize use of ddbuf.    FILEIO_MUTEX_LOCK(getcwd_lock);    // Initialize ddbuf with ".".    ddbuf[0] = '.';    ddbuf[1] = '\0';    ddbufpos = 1;    // Start result buffer with a zero terminator. We accumulate the    // path name in the top end of the result buffer.    *p = '\0';        for(;;)    {        struct stat sdbuf;        struct stat sddbuf;        // Get status for "." and "..". If the filesystem does not        // support these, then this whole function will fail here.                err = stat( ddbuf, &sdbuf );        if( err < 0 ) break;        ddbuf[ddbufpos++] = '/';        ddbuf[ddbufpos++] = '.';        ddbuf[ddbufpos++] = '.';        ddbuf[ddbufpos] = '\0';                err = stat( ddbuf, &sddbuf );        if( err < 0 ) break;        // See whether we are at the root. This will be true when        // the inode numbers of "." and ".." are the same.        if( sdbuf.st_ino == sddbuf.st_ino )            break;        // We now need to find an entry in the ".." directory that        // matches the inode number of ".".        struct dirent de;        DIR *d = opendir( ddbuf );        if( d == NULL )        {            err = -1;            break;        }                for(;;)        {            struct dirent *res;            struct stat objstat;            int i;                        err = readdir_r( d, &de, &res );            if( err < 0 || res == NULL ) break;            // Skip "." and ".." entries.            if( pathcmp( de.d_name, "." ) || pathcmp( de.d_name, ".." ) )                continue;                        // Tack the name of the directory entry on to the ddbuf            // and stat the object.                        ddbuf[ddbufpos] = '/';            for( i = 0; de.d_name[i] != '\0'; i++ )                ddbuf[ddbufpos+i+1] = de.d_name[i];            ddbuf[ddbufpos+i+1] = '\0';            // Take a look at it            err = stat( ddbuf, &objstat );            if( err < 0 ) break;            // Cast out directories            if( !S_ISDIR(objstat.st_mode) )                continue;            // We have a directory. Compare its inode with that of "."            // and if they are the same, we have found our entry.            if( sdbuf.st_ino == objstat.st_ino )                break;        }        ddbuf[ddbufpos] = '\0'; // reterminate ddbuf                closedir( d );        // Halt on any errors.        if( err < 0 )            break;        // Here de contains the name of the directory entry in ".."        // that has the same inode as ".". Add the name to the path we        // are accumulating in the buffer.        char *q = de.d_name;        while( *q != '\0' ) q++;        // skip to end of name        do        {            *--p = *--q;        } while( q != de.d_name );        *--p = '/';                     // add a separator    }    // We have finished using ddbuf now.    FILEIO_MUTEX_UNLOCK(getcwd_lock);        if( err < 0 )        FILEIO_RETURN_VALUE(NULL);    // We have the directory path in the top end of the buffer.  Add    // the mount point name at the beginning and copy the rest of the    // name down.    char *bp = buf;        bp = my_strcpy( bp, mte->name );    // Sort out the separators between the mount name and the    // pathname.  This is a bit messy since we have to deal with mount    // names of both "/" and "/foo" and pathnames that start with '/'    // or are empty.    if( *(bp-1) != '/' && *p != '\0' ) *bp++ = '/';    if( *p == '/' ) p++;    // Now copy the path over.    while( *p )        *bp++ = *p++;    *bp = '\0';                         // Terminate the string    // All done!    #endif        FILEIO_RETURN_VALUE(buf);}//==========================================================================// FS get info.__externC int cyg_fs_getinfo( const char *path, int key, void *buf, int len ){    FILEIO_ENTRY();        int ret = 0;    cyg_mtab_entry *mte = cyg_cdir_mtab_entry;    cyg_dir dir = cyg_cdir_dir;    const char *name = path;        ret = cyg_mtab_lookup( &dir, &name, &mte );        if( 0 != ret )        FILEIO_RETURN(ENOENT);    LOCK_FS( mte );        ret = mte->fs->getinfo( mte, dir, name, key, buf, len );        UNLOCK_FS( mte );        FILEIO_RETURN(ret);}//==========================================================================// FS set info.__externC int cyg_fs_setinfo( const char *path, int key, void *buf, int len ){    FILEIO_ENTRY();        int ret = 0;    cyg_mtab_entry *mte = cyg_cdir_mtab_entry;    cyg_dir dir = cyg_cdir_dir;    const char *name = path;        ret = cyg_mtab_lookup( &dir, &name, &mte );        if( 0 != ret )        FILEIO_RETURN(ENOENT);    LOCK_FS( mte );        ret = mte->fs->setinfo( mte, dir, name, key, buf, len );        UNLOCK_FS( mte );        FILEIO_RETURN(ret);}// -------------------------------------------------------------------------// EOF file.cxx

⌨️ 快捷键说明

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