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

📄 wy__dirhandle.cpp

📁 一个不错
💻 CPP
字号:
#define WYLIB_SOURCE#include "wy__dirhandle.h"#include "wysysfile.h"       // for WySysFile::wy_close(int)#include "wy_atdestroy.h"#include <sys/stat.h>#include <fcntl.h>const char Wy__DirHandEnt::DirNameOfEmpty[]="./";WyRet Wy__DirHandEnt::_reset(void){  if(_rcnt<=0) {    return(Ok);  }  Wy__Base::cancel_point();  Wy__Base::NoCancel noc;  _rcnt=0;  if(::closedir(_dirp)!=0) {    const int en=errno;    WySysFile::wy_close(_fd); // errno ignored, for already had one    if((en==EBADF)||(en==0)) {      // closedir(_dirp) error should not return this      WY_THROW( WyRet(WyReply(en)) );    }    WY_RETURN(WyReply(en));  }  while(::close(_fd)!=0) {    const int en=errno;    if((en==EINTR)||(en==EAGAIN)) {    } else {      if((en==EBADF)||(en==0)) {  // error should not return this        // should not return this        WY_THROW( WyRet(WyReply(en)) );      }      WY_RETURN(WyReply(en));    }  };  return(Ok);};Wy__DirHandEnt::Wy__DirHandEnt(const Wy__DirHandEnt& src) WY__TSPC(){  _rcnt=0;  if(src._rcnt!=0) {    // src only supposed to be default    WY_TERMINATE("");  }};WyRet Wy__DirHandEnt::open(const char* dirname){  if(_rcnt>0) {    WY_RETURN(Wym_EACCES);  // added by library, app should avoid this  }  if(dirname==0) {    WY_RETURN(Wym_EFAULT);  }  Wy__Base::cancel_point();  Wy__Base::NoCancel noc;  _dirp=NULL;  _fd=WY__DEFAULT_FD;  try {   // open _dirp   _dirp=::opendir((*dirname==0)? DirNameOfEmpty:dirname);   if(_dirp==NULL) {     if(errno==0) {       WY_THROW( WyRet(WyReply(errno)) );     }     WY_RETURN(errno);   }   // open _fd   _fd=::open((*dirname==0)? DirNameOfEmpty:dirname,O_RDONLY|O_DIRECTORY);   if(_fd<0) {     ::closedir(_dirp);     WY_RETURN(errno);   }  }  catch(const WyRet& e) {    if(_dirp!=NULL) {      ::closedir(_dirp);    }    if(_fd>=0) {      WySysFile::wy_close(_fd); // errno ignored, for already had one    }    _rcnt=0;    throw;  };  _rcnt=1;  return(Ok);};WyRet Wy__DirHandEnt::check_in(void) WY__TSPC(){  if(_rcnt<=0) {    return(Wym_ENOENT);  }  if(_rcnt>=std::numeric_limits<size_t>::max()) {    return(Wym_ENFILE);  }  ++_rcnt;  return(Ok);};WyRet Wy__DirHandEnt::check_out(void) WY__TSPC(){  if(_rcnt<=1) {    if(_rcnt==0) {      WY_RETURN(Wym_ENOENT);    }    WY_RETURN( _reset() );  // reset will zero the count  }  --_rcnt;  return(Ok);};//--------------------------------------------------------------------const char Wy__DirHandle::class_name[]="Wy__DirHandle";Wy_Array<Wy__DirHandEnt> Wy__DirHandle::wy_tab(8,Wy__DirHandEnt());WyMutex Wy__DirHandle::wy_tab_mtx;Wy__DirHandle::Wy__DirHandle(const Wy__DirHandle& src) WY__TSPC(WyRet)try { if(src._idx==DefaultIdx) {  // src is defaut   _idx=DefaultIdx;   return; } WyLock aa(wy_tab_mtx); _idx=src._idx; if(_idx>=int(wy_tab.size())) {   WY_THROW(WyRet());  // src._idx out of range } const WyRet r=wy_tab[_idx].check_in(); if(r!=Ok) {   if(r==Wym_ENFILE) {     WY_THROW( Reply(r) ); // only this possible   }   WY_THROW(WyRet()); }}catch(const WyLock::Reply& e) {  WY_THROW( WyRet(e) );}catch(const Wy__DirHandle::Reply&) {  throw;}catch(const WyRet& e) {  WY_THROW(WyRet(e));}catch(...) {  WY_THROW(WyRet());};Wy__DirHandle::~Wy__DirHandle() WY__TSPC()try { if(_idx==DefaultIdx) {   return; } WyLock aa(wy_tab_mtx); if(_idx>=int(wy_tab.size())) {   WY_TERMINATE("");  // _idx out of range } wy_tab[_idx].check_out();    // error ignored}catch(const WyLock::Reply& e) {  WY_TERMINATE("");}catch(...) {  WY_TERMINATE("");};WyFileHandle Wy__DirHandle::fh(void) const WY__NOTHROW__try { if(_idx==DefaultIdx) {   return WyFileHandle(); }  WyLock aa(wy_tab_mtx); if(_idx>=int(wy_tab.size())) {   // _idx out of range   WY_THROW( WyRet(Wym_ERANGE) ); } return WyFileHandle(wy_tab[_idx].fd());}catch(const WyLock::Reply& e) {  WY_THROW( WyRet(e) );}catch(...) {  WY_TERMINATE("");};WyRet Wy__DirHandle::fstat(WyFileStat& filestat) consttry { if(_idx==DefaultIdx) {   WY_RETURN(Wym_EBADF); }  WyLock aa(wy_tab_mtx); if(_idx>=int(wy_tab.size())) {   // _idx out of range   WY_THROW( WyRet(Wym_ERANGE) ); } if(::fstat(wy_tab[_idx].fd(),filestat.wy_stat_ptr())!=0) {   if(errno==0) {     WY_THROW( WyRet(WyReply(errno)) );   }   WY_RETURN(errno); } return(Ok);}catch(const WyLock::Reply& e) {  WY_THROW( WyRet(e) );}catch(...) {  std::unexpected();};WyRet Wy__DirHandle::reset(void)try { if(_idx==DefaultIdx) {   return(Ok); } WyLock aa(wy_tab_mtx); if(_idx>=int(wy_tab.size())) {   // _idx out of range   WY_THROW( WyRet(Wym_ERANGE) ); } WyRet r=wy_tab[_idx].check_out(); _idx=DefaultIdx; WY_RETURN(r);}catch(const WyLock::Reply& e) { WY_THROW( WyRet(e) );};WyRet Wy__DirHandle::read(WyDirEnt& dirent)try { if(_idx==DefaultIdx) {   WY_RETURN(Wym_EBADF); }  WyLock aa(wy_tab_mtx); if(_idx>=int(wy_tab.size())) {   // _idx out of range   WY_THROW( WyRet(Wym_ERANGE) ); } Wy__Base::cancel_point();  Wy__Base::NoCancel noc; struct ::dirent* ptr=dirent.wy_dent_ptr();  const int v=::readdir_r(wy_tab[_idx].dirp(),ptr,&ptr); if(v!=0) {   if(v==EBADF) {     // should not get this     WY_THROW( WyRet(Wym_EBADF) );   }   WY_RETURN(WyReply(v)); } if(ptr==NULL) {   // end of directory   dirent.reset(); } return(Ok);}catch(const WyLock::Reply& e) { WY_THROW( WyRet(e) );};WyRet Wy__DirHandle::rewind(void)try { if(_idx==DefaultIdx) {   WY_RETURN(Wym_EBADF); }  WyLock aa(wy_tab_mtx); if(_idx>=int(wy_tab.size())) {   // _idx out of range   WY_THROW( WyRet(Wym_ERANGE) ); }  Wy__Base::NoCancel noc; ::rewinddir(wy_tab[_idx].dirp()); return(Ok);}catch(const WyLock::Reply& e) { WY_THROW( WyRet(e) );};WyRet Wy__DirHandle::open(const char* pathname)try {  if(_idx!=DefaultIdx) {    WY_RETURN(Wym_EACCES);  }  WyLock aa(wy_tab_mtx);  //   // Locate an empty entry of wy_tab (from 0)  //  size_t nidx;  for(nidx=0; nidx<wy_tab.size(); ++nidx) {    if(wy_tab[nidx].is_default()) {      break;    }  }  if(nidx>=wy_tab.size()) {    wy_tab.push_back(Wy__DirHandEnt()); // push a default entry and use it  }  //  // Open the entry wy_tab[_idx];  //  const WyRet r=wy_tab[nidx].open(pathname);  if(r!=Ok) {    WY_RETURN(r);  }  _idx=nidx;  return(Ok);}catch(const WyStr::Reply& e) {  WY_RETURN(e);}catch(const WyLock::Reply& e) {  WY_THROW( WyRet(e) );}catch(const WyRet& e) {  WY_THROW( WyRet(e) );}catch(const std::exception&) {  WY_THROW( WyRet() );};WyRet Wy__DirHandle::open(const WyStr& pathname){ WY_RETURN( this->open(pathname.c_str()) );};WyRet Wy__DirHandle::reset(const Wy__DirHandle& src)try { if(&src==this) {   return(Ok); } if(_idx!=DefaultIdx) {   WY_RETURN(Wym_EACCES); } if(src._idx==DefaultIdx) {  // src is defaut   _idx=DefaultIdx;   return(Ok); } WyLock aa(wy_tab_mtx); const int ridx=src._idx; if(ridx>=int(wy_tab.size())) {   // src._idx out of range   WY_THROW( WyRet(Wym_ERANGE) ); } WyRet r=wy_tab[ridx].check_in(); if(r!=Ok) {   if(r==Wym_ENFILE) {     WY_RETURN(r); // only this possible   }   WY_THROW(r); } _idx=ridx; return(Ok);}catch(const WyLock::Reply& e) { WY_THROW( WyRet(e) );};size_t Wy__DirHandle::ref_count(void) consttry { if(_idx==DefaultIdx) {   return(0); }  WyLock aa(wy_tab_mtx); if(_idx>=int(wy_tab.size())) {   WY_THROW( WyRet() );  // _idx out of range } return(wy_tab[_idx].ref_count());}catch(const WyLock::Reply& e) { WY_THROW( WyRet(e) );}catch(const WyRet& e) { WY_THROW( WyRet(e) );};

⌨️ 快捷键说明

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