#ifndef _H_UNIXPLUSPLUS
#define _H_UNIXPLUSPLUS
#include <Security/utilities.h>
#include <Security/timeflow.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <signal.h>
#include <fcntl.h>
#include <cstdio>
#include <cstdarg>
#include <map>
namespace Security {
namespace UnixPlusPlus {
inline void checkError(int result)
{
if (result == -1)
UnixError::throwMe();
}
class IOVec : public iovec {
public:
IOVec() { }
IOVec(const void *data, size_t length) { set(data, length); }
IOVec(void *data, size_t length) { set(data, length); }
void set(const void *data, size_t length)
{ iov_base = reinterpret_cast<char *>(const_cast<void *>(data)); iov_len = length; }
void *data() const { return iov_base; }
size_t length() const { return iov_len; }
};
class FileDesc {
protected:
static const int invalidFd = -1;
void setFd(int fd) { mFd = fd; mAtEnd = false; }
void checkSetFd(int fd) { checkError(fd); mFd = fd; mAtEnd = false; }
public:
FileDesc() : mFd(invalidFd), mAtEnd(false) { }
FileDesc(int fd) : mFd(fd), mAtEnd(false) { }
FileDesc(const char *path, int flag = O_RDONLY, mode_t mode = 0666) : mFd(invalidFd)
{ open(path, flag, mode); }
FileDesc(const std::string &path, int flag = O_RDONLY, mode_t mode = 0666) : mFd(invalidFd)
{ open(path.c_str(), flag, mode); }
FileDesc &operator = (int fd) { mFd = fd; mAtEnd = false; return *this; }
FileDesc &operator = (const FileDesc &fd) { mFd = fd.mFd; mAtEnd = fd.mAtEnd; return *this; }
bool isOpen() const { return mFd != invalidFd; }
operator bool() const { return isOpen(); }
int fd() const { return mFd; }
operator int() const { return fd(); }
void clear() { mFd = invalidFd; }
void close();
void open(const char *path, int flag = O_RDONLY, mode_t mode = 0666);
size_t read(void *addr, size_t length);
size_t write(const void *addr, size_t length);
bool atEnd() const { return mAtEnd; }
template <class T> size_t read(T &obj) { return read(&obj, sizeof(obj)); }
template <class T> size_t write(const T &obj) { return write(&obj, sizeof(obj)); }
off_t seek(off_t position, int whence = SEEK_SET);
void *mmap(int prot = PROT_READ, size_t length = 0, int flags = MAP_FILE,
off_t offset = 0, void *addr = NULL);
int fcntl(int cmd, int arg = 0) const;
int fcntl(int cmd, void *arg) const;
int flags() const;
void flags(int flags) const;
void setFlag(int flag, bool on = true) const;
void clearFlag(int flag) const { setFlag(flag, false); }
int openMode() const { return flags() & O_ACCMODE; }
bool isWritable() const { return openMode() != O_RDONLY; }
bool isReadable() const { return openMode() != O_WRONLY; }
int ioctl(int cmd, void *arg) const;
template <class Arg> Arg iocget(int cmd) const
{ Arg arg; ioctl(cmd, &arg); return arg; }
template <class Arg> void iocget(int cmd, Arg &arg) const
{ ioctl(cmd, &arg); }
template <class Arg> void iocset(int cmd, const Arg &arg)
{ ioctl(cmd, const_cast<Arg *>(&arg)); }
typedef struct stat UnixStat;
void fstat(UnixStat &st) const;
size_t fileSize() const;
FILE *fdopen(const char *mode = NULL);
private:
int mFd;
protected:
bool mAtEnd; };
class AutoFileDesc : public FileDesc {
public:
AutoFileDesc() { }
AutoFileDesc(int fd) : FileDesc(fd) { }
AutoFileDesc(const char *path, int flag = O_RDONLY, mode_t mode = 0666)
: FileDesc(path, flag, mode) { }
AutoFileDesc(const std::string &path, int flag = O_RDONLY, mode_t mode = 0666)
: FileDesc(path, flag, mode) { }
~AutoFileDesc() { close(); }
};
class SigSet {
public:
SigSet() { sigemptyset(&mValue); }
SigSet(const sigset_t &s) : mValue(s) { }
SigSet &operator += (int sig)
{ sigaddset(&mValue, sig); return *this; }
SigSet &operator -= (int sig)
{ sigdelset(&mValue, sig); return *this; }
bool contains(int sig)
{ return sigismember(&mValue, sig); }
sigset_t &value() { return mValue; }
operator sigset_t () const { return mValue; }
private:
sigset_t mValue;
};
SigSet sigMask(SigSet set, int how = SIG_SETMASK);
class StaticForkMonitor {
public:
bool operator () () const
{
if (mLastPid == 0) {
mLastPid = getpid();
return false;
} else if (getpid() != mLastPid) {
mLastPid = getpid();
return true;
}
return false;
}
protected:
mutable pid_t mLastPid;
};
class ForkMonitor : public StaticForkMonitor {
public:
ForkMonitor() { mLastPid = getpid(); }
};
} }
#endif //_H_UNIXPLUSPLUS