📄 file.cxx
字号:
//==========================================================================//// file.cxx//// Fileio file operations////==========================================================================//####COPYRIGHTBEGIN####// // ------------------------------------------- // The contents of this file are subject to the Red Hat eCos Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.redhat.com/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations under // the License. // // The Original Code is eCos - Embedded Configurable Operating System, // released September 30, 1998. // // The Initial Developer of the Original Code is Red Hat. // Portions created by Red Hat are // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): nickg// Contributors: nickg// Date: 2000-05-25// Purpose: Fileio file operations// Description: These are the functions that operate on files as a whole,// such as open(), creat(), mkdir() etc.// // ////####DESCRIPTIONEND####////==========================================================================#include <pkgconf/hal.h>#include <pkgconf/kernel.h>#include <pkgconf/io_fileio.h>#include <pkgconf/isoinfra.h>#include <cyg/kernel/ktypes.h> // base kernel types#include <cyg/infra/cyg_trac.h> // tracing macros#include <cyg/infra/cyg_ass.h> // assertion macros#include <string.h> // string functions#include <dirent.h>#include <stdio.h> // stdin, stdout, stderr#include "fio.h" // Private header#include <cyg/kernel/mutex.hxx> // mutex definitions//==========================================================================// Implement filesystem locking protocol. #define LOCK_FS( _mte_ ) cyg_fs_lock( _mte_, (_mte_)->fs->syncmode)#define UNLOCK_FS( _mte_ ) cyg_fs_unlock( _mte_, (_mte_)->fs->syncmode)//==========================================================================// A local strcpy clone that returns a pointer to the end of the copied// string, not the beginning.static char *my_strcpy( char *s1, const char *s2 ){ while( (*s1++ = *s2++) != 0); return s1-1;}//==========================================================================// Compare a pathname fragment with an element in a pathname. This// deals with zero or separator termination and avoids substring// matches.static int pathcmp( const char *path, const char *name ){ while( *path == *name && *path != '\0' ) path++, name++; if( *name != '\0' ) return false; if( *path == '/' || *path == '\0' ) return true; return false;}//==========================================================================// CWD support#ifdef CYGPKG_IO_FILEIO_TRACK_CWD// buffer for storing CWD pathstatic char cwd[PATH_MAX];static size_t cwd_size = 0;static void update_cwd( cyg_mtab_entry *mte, cyg_dir dir, const char *path ){ char *p = cwd; if( mte != cdir_mtab_entry || dir != cdir_dir ) { // Here, the path is relative to the root of the filesystem, // or in a totally new filesystem, initialize the cwd with the // mount point name of the filesystem. p = my_strcpy( p, mte->name ); } else p = cwd+cwd_size; // We must now copy the path into the cwd buffer while dealing // with any "." and ".." components textually. while( *path != '\0' ) { // skip any stray directory separators. if( *path == '/' ) path++; // Look for a "." entry and just ignore it. if( pathcmp( path, "." ) ) { path++; continue; } // Look for a ".." entry. If found, chew off the last cwd // entry. if( pathcmp( path, ".." ) ) { while( *(--p) != '/' ); // back up to last '/' path += 2; // skip "..". continue; } // Otherwise just copy the name fragment over to the cwd. if( *(p-1) != '/' ) *p++ = '/'; // add a directory separator while( *path != '/' && *path != '\0' ) *p++ = *path++; } // Zero terminate the cwd. *p = '\0'; // update size cwd_size = p-cwd;}#elsestatic Cyg_Mutex getcwd_lock CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);#endif//==========================================================================// Open a file__externC int open( const char *path, int oflag, ... ){ FILEIO_ENTRY(); // we want to be sure we pull in stdin/out/err, so they can be // assigned to fds 0, 1 and 2#ifdef CYGINT_ISO_STDIO_STREAMS CYG_REFERENCE_OBJECT(stdin); CYG_REFERENCE_OBJECT(stdout); CYG_REFERENCE_OBJECT(stderr);#endif CYG_CANCELLATION_POINT; int ret = 0; int fd; cyg_file *file; cyg_mtab_entry *mte = cdir_mtab_entry; cyg_dir dir = cdir_dir; const char *name = path; fd = cyg_fd_alloc(0); if( fd < 0 ) FILEIO_RETURN(EMFILE); file = cyg_file_alloc(); if( file == NULL ) { cyg_fd_free(fd); FILEIO_RETURN(ENFILE); } ret = cyg_mtab_lookup( &dir, &name, &mte ); if( 0 != ret ) { cyg_fd_free(fd); cyg_file_free(file); FILEIO_RETURN(ENOENT); } LOCK_FS( mte ); ret = mte->fs->open( mte, dir, name, oflag, file ); UNLOCK_FS( mte ); if( 0 != ret ) { cyg_fd_free(fd); cyg_file_free(file); FILEIO_RETURN(ret); } file->f_mte = mte; file->f_syncmode = mte->fs->syncmode; cyg_fd_assign( fd, file ); FILEIO_RETURN_VALUE(fd);}//==========================================================================// create a file__externC int creat( const char *path, mode_t mode ){ return open( path, O_WRONLY | O_CREAT | O_TRUNC, mode );}//==========================================================================// Unlink/remove a file__externC int unlink( const char *path ){ FILEIO_ENTRY(); int ret = 0; cyg_mtab_entry *mte = cdir_mtab_entry; cyg_dir dir = 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->unlink( mte, dir, name ); UNLOCK_FS( mte ); FILEIO_RETURN(ret);}//==========================================================================// Make a directory__externC int mkdir( const char *path, mode_t mode ){ FILEIO_ENTRY(); int ret = 0; cyg_mtab_entry *mte = cdir_mtab_entry; cyg_dir dir = cdir_dir; const char *name = path; mode=mode; ret = cyg_mtab_lookup( &dir, &name, &mte ); if( 0 != ret ) FILEIO_RETURN(ENOENT); LOCK_FS( mte ); ret = mte->fs->mkdir( mte, dir, name ); UNLOCK_FS( mte ); FILEIO_RETURN(ret);}//==========================================================================// Remove a directory__externC int rmdir( const char *path ){ FILEIO_ENTRY(); int ret = 0; cyg_mtab_entry *mte = cdir_mtab_entry; cyg_dir dir = 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->rmdir( mte, dir, name ); UNLOCK_FS( mte ); FILEIO_RETURN(ret);}//==========================================================================// Rename a file__externC int rename( const char *path1, const char *path2 ){ FILEIO_ENTRY(); int ret = 0; cyg_mtab_entry *mte1 = cdir_mtab_entry; cyg_mtab_entry *mte2 = cdir_mtab_entry; cyg_dir dir1 = cdir_dir; cyg_dir dir2 = cdir_dir; const char *name1 = path1; const char *name2 = path2; ret = cyg_mtab_lookup( &dir1, &name1, &mte1 ); if( 0 != ret ) FILEIO_RETURN(ENOENT); ret = cyg_mtab_lookup( &dir2, &name2, &mte2 ); if( 0 != ret ) FILEIO_RETURN(ENOENT); // Cannot rename between different filesystems if( mte1 != mte2 ) FILEIO_RETURN(EXDEV); LOCK_FS( mte1 ); ret = mte1->fs->rename( mte1, dir1, name1, dir2, name2 ); UNLOCK_FS( mte1 ); FILEIO_RETURN(ret);}//==========================================================================// Create a link from an existing file (path1) to a new one (path2)__externC int link( const char *path1, const char *path2 ){ FILEIO_ENTRY(); int ret = 0; cyg_mtab_entry *mte1 = cdir_mtab_entry; cyg_mtab_entry *mte2 = cdir_mtab_entry; cyg_dir dir1 = cdir_dir; cyg_dir dir2 = cdir_dir; const char *name1 = path1; const char *name2 = path2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -