www.pudn.com > dstile-0.2.rar > syskit.cpp


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#include "exceptions.h"
#include "syskit.h"

void MakeDirs(const string& path) {
    struct stat st;
    int i, p;
    string cur;

    if (!path.size()) return;
    if (path[path.size() - 1] == '/') cur = path.substr(0, path.size() - 1);
    else cur = path.substr(0, path.size());
    if (mkdir(cur.c_str(), 0777)) {
	if (errno == ENOENT) {
	    p = cur.rfind('/');
	    if (p > 0) MakeDirs(cur.substr(0, p));
	    if (mkdir(cur.c_str(), 0777)) {
		if (errno == EEXIST) {
		    if (stat(cur.c_str(), &st))
			throw SystemException("Unable to create directory '%s', stat failed with '%s'.", cur.c_str(), ErrnoToString(errno).c_str());
		    if (!S_ISDIR(st.st_mode))
			throw SystemException("Unable to create directory '%s', file exists and is not a directory.", cur.c_str());
		} else throw SystemException("Unable to create directory '%s', mkdir failed with '%s'.", cur.c_str(), ErrnoToString(errno).c_str());
	    }
	} else if (errno == EEXIST) {
	    if (stat(cur.c_str(), &st))
		throw SystemException("Unable to create directory '%s', stat failed with '%s'.", cur.c_str(), ErrnoToString(errno).c_str());
	    if (!S_ISDIR(st.st_mode))
		throw SystemException("Unable to create directory '%s', file exists and is not a directory.", cur.c_str());
	} else throw SystemException("Unable to create directory '%s', mkdir failed with '%s'.", cur.c_str(), ErrnoToString(errno).c_str());
    }
}

time_t GetFileModTime(const char *fn) {
    struct stat st;
    if (stat(fn, &st)) return 0;
    return st.st_mtime;
}

FileLock::FileLock() :
    m_fd(-1)
{
}

FileLock::~FileLock() {
    if (m_fd) {
	close(m_fd);
    }
}

void FileLock::Open(const string& fileName) {
    if (m_fd) close(m_fd);
    m_fd = open(fileName.c_str(), O_RDWR | O_CREAT, 0666);
    if (m_fd < 0) {
	int p = fileName.rfind('/');
	if ((errno == ENOENT) && (p > 0)) {
	    MakeDirs(fileName.substr(0, p));
	    m_fd = open(fileName.c_str(), O_RDWR | O_CREAT, 0666);
	    if (m_fd < 0) throw SystemException("Unable to open file '%s', open failed with '%s'.", fileName.c_str(), ErrnoToString(errno).c_str());
	} else throw SystemException("Unable to open file '%s', open failed with '%s'.", fileName.c_str(), ErrnoToString(errno).c_str());
    }
    m_fileName = fileName;
}

void FileLock::Close() {
    if (m_fd) {
	close(m_fd);
	m_fileName.clear();
    }
}

void FileLock::LockShared() {
    if (flock(m_fd, LOCK_SH)) throw SystemException("Unable to lock file '%s', flock failed with '%s'.", m_fileName.c_str(), ErrnoToString(errno).c_str());
}

void FileLock::LockExclusive() {
    if (flock(m_fd, LOCK_EX)) throw SystemException("Unable to lock file '%s', flock failed with '%s'.", m_fileName.c_str(), ErrnoToString(errno).c_str());
}

void FileLock::Unlock() {
    if (flock(m_fd, LOCK_UN)) throw SystemException("Unable to unlock file '%s', flock failed with '%s'.", m_fileName.c_str(), ErrnoToString(errno).c_str());
}

off_t FileLock::GetSize() {
    struct stat st;
    
    if (fstat(m_fd, &st)) throw SystemException("Unable to stat file '%s', fstat failed with '%s'.", m_fileName.c_str(), ErrnoToString(errno).c_str());
    return st.st_size;
}