📄 file.cxx
字号:
//==========================================================================//// file.cxx//// Fileio file operations////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####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/io_fileio.h>#include <pkgconf/isoinfra.h>#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//==========================================================================// Implement filesystem locking protocol. #define LOCK_FS( _mte_ ) { \ CYG_ASSERT(_mte_ != NULL, "Bad mount table entry"); \ 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 != cyg_cdir_mtab_entry || dir != cyg_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;}#else#ifdef CYGPKG_KERNELstatic Cyg_Mutex getcwd_lock CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO_FS);#endif#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 = cyg_cdir_mtab_entry; cyg_dir dir = cyg_cdir_dir; const char *name = path; // At least one of O_RDONLY, O_WRONLY, O_RDWR must be provided if( (oflag & O_RDWR) == 0 ) FILEIO_RETURN(EINVAL); 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 = 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->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 = cyg_cdir_mtab_entry; cyg_dir dir = cyg_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 = 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->rmdir( mte, dir, name ); UNLOCK_FS( mte ); FILEIO_RETURN(ret);}//==========================================================================// Rename a file__externC int rename( const char *path1, const char *path2 ) __THROW{ FILEIO_ENTRY(); int ret = 0; cyg_mtab_entry *mte1 = cyg_cdir_mtab_entry; cyg_mtab_entry *mte2 = cyg_cdir_mtab_entry; cyg_dir dir1 = cyg_cdir_dir; cyg_dir dir2 = cyg_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 = cyg_cdir_mtab_entry; cyg_mtab_entry *mte2 = cyg_cdir_mtab_entry; cyg_dir dir1 = cyg_cdir_dir; cyg_dir dir2 = cyg_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 hard-link between different filesystems if( mte1 != mte2 ) FILEIO_RETURN(EXDEV); LOCK_FS( mte1 ); ret = mte1->fs->link( mte1, dir1, name1, dir2, name2, CYG_FSLINK_HARD ); UNLOCK_FS( mte1 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -