system.cc
Go to the documentation of this file.
00001 #include <utilmm/system/system.hh>
00002 
00003 #include <exception> // for std::exception
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006 #include <errno.h>  
00007 #include <string.h>  // for strerror
00008 #include <unistd.h>  // for close
00009 #include <boost/noncopyable.hpp>
00010 #include <boost/filesystem/operations.hpp>
00011 #include <vector>
00012 #include <stdio.h>
00013 
00014 using namespace utilmm;
00015 
00016 void unix_error::init_description(std::string const& desc)
00017 {
00018     size_t desc_len = desc.length();
00019     strncpy(m_desc, desc.c_str(), 500);
00020     m_desc[500] = 0;
00021     strcat(m_desc, ": ");
00022     // I wanted to use strerror_r, but no way to force the use
00023     // of the POSIX compliant version
00024     strncat(m_desc, strerror(m_error), 500 - desc_len);
00025 }
00026 unix_error::unix_error(std::string const& desc, int error_ = errno)
00027     : m_error(error_) { init_description(desc); }
00028 unix_error::unix_error(std::string const& desc)
00029     : m_error(errno) { init_description(desc); }
00030 unix_error::unix_error(int error_)
00031     : m_error(error_) { init_description(""); }
00032 unix_error::unix_error()
00033     : m_error(errno) { init_description(""); }
00034 unix_error::~unix_error() throw () {}
00035 
00036 int unix_error::error() const { return m_error; }
00037 char const* unix_error::what() const throw()
00038 { return m_desc; }
00039 
00040 auto_close::auto_close()
00041     : m_fileno(-1), m_stream(0) {}
00042 auto_close::auto_close(int fileno)
00043     : m_fileno(fileno), m_stream(0) {}
00044 auto_close::auto_close(FILE* stream)
00045     : m_fileno(-1), m_stream(stream) {}
00046 auto_close::~auto_close() { close(); }
00047 
00048 void auto_close::close()
00049 {
00050     int ret = 0;
00051     if (m_stream)
00052         ret = fclose(m_stream);
00053     else if (m_fileno != -1)
00054         ret = ::close(m_fileno);
00055 
00056     detach();
00057 
00058     if (ret == -1)
00059         throw unix_error();
00060 }
00061 
00062 void  auto_close::detach() 
00063 { m_fileno = -1; m_stream = 0; }
00064 
00065 template<> 
00066 FILE* auto_close::handle<FILE*>() const
00067 {
00068     if (m_stream ==  0) throw std::bad_cast();
00069     return m_stream; 
00070 }
00071 
00072 template<> 
00073 int   auto_close::handle<int>()   const
00074 {
00075     if (m_fileno == -1) throw std::bad_cast();
00076     return m_fileno; 
00077 }
00078 
00079 void auto_close::reset(int fileno)
00080 {
00081     close();
00082     m_fileno = fileno;
00083 }
00084 void auto_close::reset(FILE* stream)
00085 {
00086     close();
00087     m_stream = stream;
00088 }
00089 
00090 
00091 
00092 
00093 
00094 FILE* tempfile::create()
00095 { 
00096     FILE* fd = tmpfile(); 
00097     if (!fd)
00098         throw unix_error();
00099     return fd;
00100 }
00101 
00102 FILE* tempfile::mkstemp(std::string const& base, boost::filesystem::path& path)
00103 {
00104     int const base_length(base.length());
00105 
00106     std::vector<char> value;
00107     value.resize( base_length + 6 + 1 );
00108     strncpy(&value[0], base.c_str(), base_length);
00109     memset(&value[base_length], 'X', 6);
00110     value[base_length + 6] = '\0';
00111 
00112     int handle = ::mkstemp(&value[0]);
00113     if (handle < 0)
00114         throw unix_error();
00115 
00116     path = std::string(&value[0]);
00117     return fdopen(handle, "w");
00118 }
00119 
00120 tempfile::tempfile(std::string const& base)
00121     : m_path(), m_guard(mkstemp(base, m_path))
00122 {
00123     if (! handle())
00124         throw unix_error();
00125 }
00126 
00127 tempfile::tempfile()
00128     : m_guard(create()) {}
00129 
00130 tempfile::~tempfile() 
00131 {
00132     if (! m_path.empty())
00133     {
00134         try {
00135             m_guard.close();
00136             boost::filesystem::remove(m_path);
00137         } catch(...) {}
00138     }
00139 }
00140 
00141 FILE* tempfile::handle() const { 
00142     if (m_path.empty())
00143         return 0;
00144     else
00145         return m_guard.handle<FILE*>(); 
00146 }
00147 FILE* tempfile::detach()
00148 {
00149     FILE* h = handle();
00150     m_guard.detach();
00151     m_path = boost::filesystem::path();
00152     return h;
00153 }
00154 
00155 boost::filesystem::path tempfile::path() const { return m_path; }
00156 


utilmm
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Thu Jan 2 2014 11:38:31