posix/dirimpl.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) Sergey P. Derevyago, 2008.
00003  *
00004  * Permission to copy, use, modify, sell and distribute this software is granted
00005  * provided this copyright notice appears in all copies.
00006  * This software is provided "as is" without express or implied warranty, and
00007  * with no claim as to its suitability for any purpose.
00008  *
00009  */
00010 
00015 #include <ders/dir.hpp>
00016 #include <dirent.h>
00017 #include <errno.h>
00018 #include <sys/stat.h>
00019 #include <ders/file.hpp>
00020 #include <ders/text_buf.hpp>
00021 
00022 namespace {
00023 
00024 using namespace ders;
00025 
00026 struct pos_dir : public dir {
00027        sh_text dn;
00028        DIR* dr;
00029 
00030        pos_dir(sh_text dname) : dn(dname), dr(0) {}
00031        ~pos_dir() { if (dr) closedir(dr); }
00032 
00033        virtual bool find_next(entry&);
00034        virtual sh_text full_name(const entry& dent);
00035 
00036        virtual void destroy(mem_pool& mp2) { destroy_this(this, mp2); }
00037 };
00038 
00039 bool pos_dir::find_next(entry& dent)
00040 {
00041  mem_pool& mp=dn.pool();
00042 
00043  if (!dr) {
00044     if ( !(dr=opendir(dn->size() ? dn->c_str() : ".")) ) {
00045        throw newFileErrorException(mp, _FLINE_, "Can't find first file",
00046          convert_errno(errno), dn);
00047     }
00048  }
00049 
00050  dirent *ent=readdir(dr);
00051  if (!ent) return false;
00052 
00053  *dent.name=ent->d_name;
00054  dent.isdir=false;
00055  dent.size=0;
00056 
00057  struct stat statbuf;
00058  if (stat(pos_dir::full_name(dent)->c_str(), &statbuf)==0) {
00059     dent.isdir=statbuf.st_mode&S_IFDIR;
00060     dent.size=statbuf.st_size;
00061  }
00062 
00063  return true;
00064 }
00065 
00066 sh_text pos_dir::full_name(const entry& dent)
00067 {
00068  text_buf buf(dn);
00069  if (dn->size() && dn->back()!='/') buf+'/';
00070 
00071  return buf+dent.name;
00072 }
00073 
00074 }  // unnamed
00075 
00076 namespace ders {  // ::ders
00077 
00078 sh_dir new_dir(mem_pool& mp, const ch_rng& dname)
00079 {
00080  mp_newbuf<pos_dir> buf(mp);
00081  return sh_dir(buf.pool(), buf.rls(::new(buf.get()) pos_dir(nt(mp, dname))));
00082 }
00083 
00084 error make_dir(mem_pool& mp, const ch_rng& dname)
00085 {
00086  return (mkdir(text(mp, dname).c_str(), S_IRWXU|S_IRWXG|S_IRWXO)==-1) ?
00087    convert_errno(errno) : ezero;
00088 }
00089 
00090 }  // namespace ::ders
00091 

Generated on Tue Dec 8 11:35:32 2009 for derslib by  doxygen 1.5.5