File/Directory Enhancement

- Migrated enhanced code out of taskd.
This commit is contained in:
Paul Beckingham 2011-04-16 00:44:07 -04:00
parent e9273cd6c3
commit 87c285e6b2
5 changed files with 234 additions and 20 deletions

View file

@ -30,7 +30,7 @@
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include "Directory.h"
#include <Directory.h>
#include "../cmake.h"
////////////////////////////////////////////////////////////////////////////////
@ -87,7 +87,41 @@ bool Directory::create ()
////////////////////////////////////////////////////////////////////////////////
bool Directory::remove ()
{
return rmdir (data.c_str ()) == 0 ? true : false;
return remove_directory (data);
}
////////////////////////////////////////////////////////////////////////////////
bool Directory::remove_directory (const std::string& dir)
{
DIR* dp = opendir (dir.c_str ());
if (dp != NULL)
{
struct dirent* de;
while ((de = readdir (dp)) != NULL)
{
if (!strcmp (de->d_name, ".") ||
!strcmp (de->d_name, ".."))
continue;
#if defined (SOLARIS) || defined (HAIKU)
struct stat s;
stat (de->d_name, &s);
if (s.st_mode & S_IFDIR)
remove_directory (dir + "/" + de->de_name);
else
unlink ((dir + "/" + de->d_name).c_str ());
#else
if (de->d_type == DT_DIR)
remove_directory (dir + "/" + de->d_name);
else
unlink ((dir + "/" + de->d_name).c_str ());
#endif
}
closedir (dp);
}
return rmdir (dir.c_str ()) ? false : true;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -49,6 +49,7 @@ public:
private:
void list (const std::string&, std::vector <std::string>&, bool);
bool remove_directory (const std::string&);
};
#endif

View file

@ -27,46 +27,56 @@
#include <fstream>
#include <sys/types.h>
#include <sys/file.h>
#include <pwd.h>
#include <unistd.h>
#include "File.h"
#include <File.h>
#include <util.h>
////////////////////////////////////////////////////////////////////////////////
File::File ()
: Path::Path ()
, fh (NULL)
, h (-1)
{
}
////////////////////////////////////////////////////////////////////////////////
File::File (const Path& other)
: Path::Path (other)
, fh (NULL)
, h (-1)
{
}
////////////////////////////////////////////////////////////////////////////////
File::File (const File& other)
: Path::Path (other)
, fh (NULL)
, h (-1)
{
}
////////////////////////////////////////////////////////////////////////////////
File::File (const std::string& in)
: Path::Path (in)
, fh (NULL)
, h (-1)
{
}
////////////////////////////////////////////////////////////////////////////////
File::~File ()
{
if (fh)
close ();
}
////////////////////////////////////////////////////////////////////////////////
File& File::operator= (const File& other)
{
if (this != &other)
{
Path::operator= (other);
}
return *this;
}
@ -74,10 +84,9 @@ File& File::operator= (const File& other)
////////////////////////////////////////////////////////////////////////////////
bool File::create ()
{
std::ofstream out (data.c_str ());
if (out.good ())
if (open ())
{
out.close ();
close ();
return true;
}
@ -90,6 +99,161 @@ bool File::remove ()
return unlink (data.c_str ()) == 0 ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
bool File::open ()
{
if (data != "" && fh == NULL)
{
bool already_exists = exists ();
if (already_exists)
if (!readable () || !writable ())
throw std::string ("Task does not have the correct permissions for '") +
data + "'.";
fh = fopen (data.c_str (), (already_exists ? "r+" : "w+"));
if (fh)
{
h = fileno (fh);
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool File::openAndLock ()
{
return open () && lock ();
}
////////////////////////////////////////////////////////////////////////////////
void File::close ()
{
if (fh)
{
fclose (fh);
fh = NULL;
h = -1;
}
}
////////////////////////////////////////////////////////////////////////////////
bool File::lock ()
{
if (fh && h != -1)
{
// Try three times before failing.
int retry = 0;
while (flock (h, LOCK_NB | LOCK_EX) && ++retry <= 3)
;
if (retry <= 3)
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
bool File::waitForLock ()
{
if (fh && h != -1)
return flock (h, LOCK_EX) == 0 ? true : false;
return false;
}
////////////////////////////////////////////////////////////////////////////////
// Opens if necessary.
void File::read (std::string& contents)
{
contents = "";
std::ifstream in (data.c_str ());
if (in.good ())
{
std::string line;
while (getline (in, line))
contents += line + "\n";
in.close ();
}
}
////////////////////////////////////////////////////////////////////////////////
// Opens if necessary.
void File::read (std::vector <std::string>& contents)
{
contents.clear ();
std::ifstream in (data.c_str ());
if (in.good ())
{
std::string line;
while (getline (in, line))
contents.push_back (line);
in.close ();
}
}
////////////////////////////////////////////////////////////////////////////////
// Opens if necessary.
void File::write (const std::string& line)
{
if (!fh)
open ();
if (fh)
fputs (line.c_str (), fh);
}
////////////////////////////////////////////////////////////////////////////////
// Opens if necessary.
void File::write (const std::vector <std::string>& lines)
{
if (!fh)
open ();
if (fh)
{
std::vector <std::string>::const_iterator it;
for (it = lines.begin (); it != lines.end (); ++it)
fputs (it->c_str (), fh);
}
}
////////////////////////////////////////////////////////////////////////////////
// Opens if necessary.
void File::append (const std::string& line)
{
if (!fh)
open ();
if (fh)
{
fseek (fh, 0, SEEK_END);
fputs (line.c_str (), fh);
}
}
////////////////////////////////////////////////////////////////////////////////
// Opens if necessary.
void File::append (const std::vector <std::string>& lines)
{
if (!fh)
open ();
if (fh)
{
fseek (fh, 0, SEEK_END);
std::vector <std::string>::const_iterator it;
for (it = lines.begin (); it != lines.end (); ++it)
fputs (((*it) + "\n").c_str (), fh);
}
}
////////////////////////////////////////////////////////////////////////////////
// S_IFMT 0170000 type of file
// S_IFIFO 0010000 named pipe (fifo)

View file

@ -24,9 +24,11 @@
// USA
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_FILE
#define INCLUDED_FILE
#include <stdio.h>
#include <string>
#include <vector>
#include <sys/stat.h>
@ -46,19 +48,21 @@ public:
virtual bool create ();
virtual bool remove ();
// bool open ();
// bool openAndLock ();
// void close ();
bool open ();
bool openAndLock ();
void close ();
// bool lock ();
// bool lockNoWait ();
// void unlock ();
bool lock ();
bool waitForLock ();
// void read (std::string&);
// void read (std::vector <std::string>&);
void read (std::string&);
void read (std::vector <std::string>&);
// void write (const std::string&);
// void write (const std::vector <std::string>&);
void write (const std::string&);
void write (const std::vector <std::string>&);
void append (const std::string&);
void append (const std::vector <std::string>&);
virtual mode_t mode ();
virtual size_t size () const;
@ -75,7 +79,8 @@ public:
static bool remove (const std::string&);
private:
// int handle;
FILE* fh;
int h;
};
#endif