#ifndef _H_UNIXPLUSPLUS
#define _H_UNIXPLUSPLUS
#include <security_utilities/utilities.h>
#include <security_utilities/errors.h>
#include <security_utilities/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 <semaphore.h>
#include <cstdio>
#include <cstdarg>
#include <map>
namespace Security {
namespace UnixPlusPlus {
template <class Result>
inline Result checkError(Result result)
{
if (result == Result(-1))
UnixError::throwMe();
return result;
}
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; }
FileDesc(int fd, bool atEnd) : mFd(fd), mAtEnd(atEnd) { }
public:
FileDesc() : mFd(invalidFd), mAtEnd(false) { }
FileDesc(int fd) : mFd(fd), mAtEnd(false) { }
static const mode_t modeMissingOk = S_IFIFO;
explicit FileDesc(const char *path, int flag = O_RDONLY, mode_t mode = 0666)
: mFd(invalidFd) { this->open(path, flag, mode); }
explicit FileDesc(const std::string &path, int flag = O_RDONLY, mode_t mode = 0666)
: mFd(invalidFd) { this->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);
void open(const std::string &path, int flag = O_RDONLY, mode_t mode = 0666)
{ this->open(path.c_str(), flag, mode); }
size_t read(void *addr, size_t length);
size_t write(const void *addr, size_t length);
bool atEnd() const { return mAtEnd; }
size_t read(void *addr, size_t length, off_t position);
size_t write(const void *addr, size_t length, off_t position);
size_t readAll(void *addr, size_t length);
size_t readAll(std::string &content);
void writeAll(const void *addr, size_t length);
void writeAll(char *s) { writeAll(s, strlen(s)); }
void writeAll(const char *s) { writeAll(s, strlen(s)); }
template <class Data>
void writeAll(const Data &ds) { writeAll(ds.data(), ds.length()); }
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)); }
size_t seek(off_t position, int whence = SEEK_SET);
size_t position() const;
void *mmap(int prot = PROT_READ, size_t length = 0,
int flags = MAP_FILE | MAP_PRIVATE, off_t offset = 0, void *addr = NULL);
int fcntl(int cmd, void *arg = NULL) const;
template <class T> int fcntl(int cmd, T arg) const
{ return fcntl(cmd, reinterpret_cast<void *>(arg)); }
int flags() const { return fcntl(F_GETFL); }
void flags(int flags) const { fcntl(F_SETFL, flags); }
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; }
FileDesc dup() const;
FileDesc dup(int newFd) const;
struct Pos {
Pos(off_t s = 0, int wh = SEEK_SET, off_t siz = 0)
: start(s), size(siz), whence(wh) { }
off_t start;
off_t size;
int whence;
};
static Pos lockAll() { return Pos(0, SEEK_SET, 0); }
void lock(struct flock &args);
void lock(int type = F_WRLCK, const Pos &pos = lockAll());
bool tryLock(int type = F_WRLCK, const Pos &pos = lockAll());
void unlock(const Pos &pos = lockAll()) { lock(F_UNLCK, pos); }
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)); }
void setAttr(const char *name, const void *value, size_t length,
u_int32_t position = 0, int options = 0);
void setAttr(const std::string &name, const void *value, size_t length,
u_int32_t position = 0, int options = 0)
{ return setAttr(name.c_str(), value, length, position, options); }
ssize_t getAttr(const char *name, void *value, size_t length,
u_int32_t position = 0, int options = 0);
ssize_t getAttr(const std::string &name, void *value, size_t length,
u_int32_t position = 0, int options = 0)
{ return getAttr(name.c_str(), value, length, position, options); }
ssize_t getAttrLength(const char *name);
ssize_t getAttrLength(const std::string &name) { return getAttrLength(name.c_str()); }
void removeAttr(const char *name, int options = 0);
void removeAttr(const std::string &name, int options = 0)
{ return removeAttr(name.c_str(), options); }
size_t listAttr(char *value, size_t length, int options = 0);
size_t listAttr(const std::string &name, size_t length, int options = 0)
{ return listAttr(name.c_str(), length, options); }
void setAttr(const std::string &name, const std::string &value, int options = 0);
std::string getAttr(const std::string &name, int options = 0);
typedef struct stat UnixStat;
void fstat(UnixStat &st) const;
size_t fileSize() const;
bool isA(int type) const;
void chown(uid_t uid);
void chown(uid_t uid, gid_t gid);
void chgrp(gid_t gid);
void chmod(mode_t mode);
void chflags(u_int flags);
FILE *fdopen(const char *mode = NULL);
private:
int mFd;
private:
struct LockArgs : public flock {
LockArgs(int type, const Pos &pos)
{ l_start = pos.start; l_len = pos.size; l_type = type; l_whence = pos.whence; }
IFDEBUG(void debug(int fd, const char *what));
};
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(); }
};
void makedir(const char *path, int flags, mode_t mode = 0777);
int ffprintf(const char *path, int flags, mode_t mode, const char *format, ...);
int ffscanf(const char *path, const char *format, ...);
} }
#endif //_H_UNIXPLUSPLUS