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

📄 file.cxx

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 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 + -