📄 wysysfile.cpp
字号:
/* Copyright is licensed under GNU LGPL. by I.J.Wang 2005*/#define WYLIB_SOURCE#include "wysysfile.h"#include "wy_atdestroy.h"#include <typeinfo>#include <memory>Wy__FtBits::Wy__FtBits(mode_t m){ switch(m) { case S_IFREG: _bts=0x01; return; case S_IFCHR: _bts=0x02; return; case S_IFSOCK: _bts=0x04; return; case S_IFIFO: _bts=0x08; return; case S_IFDIR: _bts=0x10; return; case S_IFLNK: _bts=0x20; return; case S_IFBLK: _bts=0x40; return; default: WY_TERMINATE("Unrecognized mode_t"); };};//-------------------------------------------------------------------------const char WySysFile::class_name[]="WySysFile";Wy__FtBits WySysFile::cftbits(void) WY__NOTHROW__{ static const Wy__FtBits fb( Wy__FtBits(S_IFREG)+ Wy__FtBits(S_IFCHR)+ Wy__FtBits(S_IFSOCK)+ Wy__FtBits(S_IFIFO) ); return(fb);};//-------------------------------------------------------------------------#ifdef WY_DEBUGint WySysFile::_dbg_objcnt=0;::pthread_mutex_t WySysFile::_dbg_mtx= PTHREAD_MUTEX_INITIALIZER;int WySysFile::wydbg_get_objcnt(void) throw(){ int v( ::pthread_mutex_lock(&_dbg_mtx) ); if(v!=0) { WY_TERMINATE(""); } v=_dbg_objcnt; if(::pthread_mutex_unlock(&_dbg_mtx)!=0) { WY_TERMINATE(""); } return(v);};void WySysFile::wydbg_inc_objcnt(void) throw(){ int v( ::pthread_mutex_lock(&_dbg_mtx) ); if(v!=0) { WY_TERMINATE(""); } ++_dbg_objcnt; if(::pthread_mutex_unlock(&_dbg_mtx)!=0) { WY_TERMINATE(""); }};void WySysFile::wydbg_dec_objcnt(void) throw(){ int v( ::pthread_mutex_lock(&_dbg_mtx) ); if(v!=0) { WY_TERMINATE(""); } --_dbg_objcnt; if(::pthread_mutex_unlock(&_dbg_mtx)!=0) { WY_TERMINATE(""); }};#endif//-------------------------------------------------------------------------// [Cancel Point]// [Internal] close fd (modified version of ::close)//// Note: This function assumes fd is always sucessfully closed (freely reusable)// fd is also closed in failure or cancellation//// 1. Test program t_close.cpp has never caught EINTR from ::close(int)// (Fedora Core 3)//// 2. A post 37748e5c16749481_002.html suggests that the file descriptor// has been closed by ::close(int) returning EINTR on Linux//// 3. Spec. from these URL's indicate that close(fd) failure postcondition// is unspecified (except EBADF), but this is not deterministic for this// concern.// http://www.die.net/doc/linux/man/man3/close.3.html// http://www.opengroup.org/onlinepubs/000095399/functions/close.html//// [Ret] errno//int WySysFile::wy_close(const Wy__TypeFD& fd){#ifdef WY_DEBUG if(fd!=WY__DEFAULT_FD) { wydbg_dec_fdcnt(); }#endif return (::close(fd)==0)? 0: errno;};inline void WySysFile::_init(const char* pathname,int flags){ if(flags&O_CREAT) { WY_THROW( Reply(Wym_EINVAL) ); } _m_fd=wyc_open(pathname,flags); if(_m_fd==-1) { WY_THROW( Reply(WyReply(errno)) ); } Wy_AtDestroy<int,const Wy__TypeFD&> rrid(WySysFile::wy_close,_m_fd); WyFileStat stt; if(wyc_fstat(_m_fd,stt.wy_stat_ptr())==-1) { WY_THROW( Reply(WyReply(errno)) ); } _m_ftype=stt.sf_mode()&S_IFMT; if(_cif.is_joint(_m_ftype)==false) { WY_THROW( Reply(Wym_EBADF) ); } rrid.release();};WySysFile::WySysFile(const Wy__FtBits cif) : _cif(cif), _m_fd(DefaultFd),_m_ftype(DefaultFType){#ifdef WY_DEBUG WySysFile::wydbg_inc_objcnt();#endif};WySysFile::WySysFile(WyFileHandle fh, const Wy__FtBits cif) : _cif(cif), _m_fd(DefaultFd),_m_ftype(DefaultFType){ if(fh.is_default()) {#ifdef WY_DEBUG WySysFile::wydbg_inc_objcnt();#endif return; } WyRet r; WyFileStat stt; if((r=fh.stat(stt))!=Ok) { WY_THROW( Reply(r) ); } _m_ftype=stt.sf_mode()&S_IFMT; if(_cif.is_joint(_m_ftype)==false) { WY_THROW( Reply(Wym_EBADF) ); } _m_fd=wyc_dup(fh.fd()); if(_m_fd==-1) { WY_THROW( Reply(WyReply(errno)) ); }#ifdef WY_DEBUG WySysFile::wydbg_inc_objcnt();#endif};WySysFile::WySysFile(const WySysFile& sysf, const Wy__FtBits cif) : _cif(cif),_m_fd(DefaultFd),_m_ftype(sysf._m_ftype){ if(sysf.is_default()) { // default object is runtime checked for types that may be consistent if(_cif.is_joint(sysf._cif)==false) { WY_THROW( Reply(Wym_EBADF) ); }#ifdef WY_DEBUG WySysFile::wydbg_inc_objcnt();#endif return; } if(_cif.is_joint(_m_ftype)==false) { WY_THROW( Reply(Wym_EBADF) ); } _m_fd=wyc_dup(sysf._m_fd); if(_m_fd==-1) { WY_THROW( Reply(WyReply(errno)) ); }#ifdef WY_DEBUG WySysFile::wydbg_inc_objcnt();#endif};WySysFile::WySysFile(const char* pathname,int flags,const Wy__FtBits cif) : _cif(cif), _m_fd(DefaultFd),_m_ftype(DefaultFType){ this->_init(pathname,flags);#ifdef WY_DEBUG WySysFile::wydbg_inc_objcnt();#endif};WySysFile::WySysFile(const WyStr& pathname,int flags,const Wy__FtBits cif) : _cif(cif), _m_fd(DefaultFd),_m_ftype(DefaultFType){ this->_init(pathname.c_str(),flags);#ifdef WY_DEBUG WySysFile::wydbg_inc_objcnt();#endif};WySysFile::WySysFile(WySysFile& sysf,Wy::ByMove_t) WY__TSPC() : _cif(sysf._cif), _m_fd(sysf._m_fd),_m_ftype(sysf._m_ftype){ // 'Clear' resource mark of sysf // This is not required but for safety sysf._m_fd=DefaultFd; sysf._m_ftype=DefaultFType;};WySysFile::~WySysFile()try {#ifdef WY_DEBUG WySysFile::wydbg_dec_objcnt();#endif if(_m_fd==DefaultFd) { return; } Wy__Base::NoCancel noc; // dtor cannot be cancellation point WySysFile::wy_close(_m_fd); // return code ignored}catch(int e) { WY_THROW( WyRet(WyReply(e)) );};bool WySysFile::is_default(void) const WY__TSPC(){ return(_m_fd==DefaultFd);};WyFileHandle WySysFile::fh(void) const WY__TSPC(){ return WyFileHandle(_m_fd);};mode_t WySysFile::ftype(void) const WY__TSPC(){ return _m_ftype; };WyRet WySysFile::stat(WyFileStat& stt) const{ if(wyc_fstat(_m_fd,stt.wy_stat_ptr())==-1) { WY_RETURN(errno); } return(Ok);};WyRet WySysFile::reset(void){ if(_m_fd==DefaultFd) { #ifdef WY_DEBUG if(_m_ftype!=DefaultFType) { WY_THROW( WyRet() ); } #endif return(Ok); } #ifdef WY_DEBUG if(_m_ftype==DefaultFType) { WY_THROW( WyRet() ); } #endif const Wy__TypeFD pfd(_m_fd); _m_fd=DefaultFd; _m_ftype=DefaultFType; const int v( WySysFile::wy_close(pfd) ); if(v!=0) { WY_RETURN(WyReply(v)); } return(Ok);};// Failure poscondition for the following _reset(..) members://// return- object intact// throw - Reply: same as return// Others: complete or intact, which is unspecified// cancel- complete or intact, which is unspecified//WyRet WySysFile::reset(WyFileHandle fh){ if(fh.is_default()) { this->reset(); return(Ok); } WyRet r; WyFileStat stt; if((r=fh.stat(stt))!=Ok) { WY_RETURN(r); } const mode_t fh_ftype=stt.sf_mode()&S_IFMT; if(_cif.is_joint(fh_ftype)==false) { WY_RETURN(Wym_EBADF); } Wy__TypeFD tfd=wyc_dup(fh.fd()); if(tfd==-1) { WY_RETURN(errno); } Wy__Base::vswap(_m_fd,tfd); _m_ftype=fh_ftype; WySysFile::wy_close(tfd); return(Ok);};WyRet WySysFile::reset(const WySysFile& sysf){ if(sysf.is_default()) { if(_cif.is_joint(sysf._cif)==false) { WY_RETURN(Wym_EBADF); } this->reset(); return(Ok); } if(_cif.is_joint(sysf._m_ftype)==false) { WY_RETURN(Wym_EBADF); } Wy__TypeFD tfd=wyc_dup(sysf._m_fd); if(tfd==-1) { WY_RETURN(errno); } Wy__Base::vswap(_m_fd,tfd); _m_ftype=sysf._m_ftype; WySysFile::wy_close(tfd); return(Ok);};WyRet WySysFile::reset(const char*pathname, int flags){ // note: report of closing provious fd is ignored // if(flags&O_CREAT) { WY_RETURN(Wym_EINVAL); } Wy__TypeFD tfd=wyc_open(pathname,flags); if(tfd==-1) { WY_RETURN(errno); } Wy_AtDestroy<int,const Wy__TypeFD&> rrid(WySysFile::wy_close,tfd); WyFileStat stt; if(wyc_fstat(tfd,stt.wy_stat_ptr())==-1) { WY_RETURN(errno); } const mode_t p_ftype=stt.sf_mode()&S_IFMT; if(_cif.is_joint(p_ftype)==false) { WY_RETURN(Wym_EBADF); } Wy__Base::vswap(_m_fd,tfd); _m_ftype=p_ftype; return(Ok);};WyRet WySysFile::reset(const WyStr& pathname, int flags){ return this->reset(pathname.c_str(),flags);};WyRet WySysFile::_swap(WySysFile& sysf) WY__TSPC(){ if(WY__EQU_TYPEID(*this,sysf)==false) { WY_RETURN(Wym_EBADTYPE); } Wy__Base::vswap(_m_fd,sysf._m_fd); Wy__Base::vswap(_m_ftype,sysf._m_ftype); return(Ok);};WySysFile* WySysFile::_alloc(WyRet& r) consttry { if(WY__EQU_TYPEID(*this,WySysFile)==false) { r=Wym_ENOSYS; WY_HERE(r); // _alloc not overridden return(NULL); } WySysFile* p=new(std::nothrow) WySysFile(); if(p==NULL) { r=Wym_ENOMEM; WY_HERE(r); } else { r=Ok; } return(p);}catch(const Reply& e) { r=e; WY_HERE(r); return(NULL);}catch(const WyRet& e) { WY_THROW( WyRet(e) );};void WySysFile::_overwrite(Wy__TypeFD fd, mode_t ftype) WY__NOTHROW__{ this->_m_fd=fd; this->_m_ftype=ftype;};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -