From 25070b355b8a0394c1fbd9cf82c44752b5a8b8c3 Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Thu, 17 Jul 2014 16:50:40 -0700 Subject: Add dir annoyances --- src/io/dir.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/dir.hpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/io/fd.cpp | 4 ++++ src/io/fd.hpp | 8 +++++++- src/io/read.cpp | 4 ++++ src/io/read.hpp | 3 +++ src/io/write.cpp | 3 +++ src/io/write.hpp | 3 +++ 8 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/io/dir.cpp create mode 100644 src/io/dir.hpp (limited to 'src/io') diff --git a/src/io/dir.cpp b/src/io/dir.cpp new file mode 100644 index 0000000..2acb75a --- /dev/null +++ b/src/io/dir.cpp @@ -0,0 +1,54 @@ +#include "dir.hpp" +// io/dir.cpp - rooted file operations +// +// Copyright © 2014 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include + +#include "../strings/zstring.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ +namespace io +{ + DirFd::DirFd() + : dirfd(FD::cast_dammit(AT_FDCWD)) + {} + + DirFd::DirFd(ZString path) + : dirfd(FD::open(path, O_DIRECTORY | O_RDONLY, 0)) + {} + + DirFd::DirFd(const DirFd& root, ZString path) + : dirfd(FD::openat(root.dirfd, path, O_DIRECTORY | O_RDONLY, 0)) + {} + + DirFd::~DirFd() + { + dirfd.close(); + } + + FD DirFd::open_fd(ZString name, int flags, int mode) const + { + return FD::openat(dirfd, name, flags, mode); + } +} // namespace io +} // namespace tmwa diff --git a/src/io/dir.hpp b/src/io/dir.hpp new file mode 100644 index 0000000..071f309 --- /dev/null +++ b/src/io/dir.hpp @@ -0,0 +1,50 @@ +#pragma once +// io/dir.hpp - rooted file operations +// +// Copyright © 2014 Ben Longbons +// +// This file is part of The Mana World (Athena server) +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "fwd.hpp" + +#include "../strings/fwd.hpp" + +#include "fd.hpp" + + +namespace tmwa +{ +namespace io +{ + class DirFd + { + private: + FD dirfd; + + public: + DirFd(); + explicit + DirFd(ZString); + DirFd(const DirFd&, ZString); + + DirFd(const DirFd&) = delete; + ~DirFd(); + DirFd& operator = (const DirFd&) = delete; + + FD open_fd(ZString name, int flags, int mode=FD::DEFAULT_MODE) const; + }; +} // namespace io +} // namespace tmwa diff --git a/src/io/fd.cpp b/src/io/fd.cpp index 4c61a6f..c0b44e8 100644 --- a/src/io/fd.cpp +++ b/src/io/fd.cpp @@ -34,6 +34,10 @@ namespace io { return FD(::open(path.c_str(), flags, mode)); } + FD FD::openat(FD dirfd, ZString path, int flags, int mode) + { + return FD(::openat(dirfd.fd, path.c_str(), flags, mode)); + } FD FD::socket(int domain, int type, int protocol) { return FD(::socket(domain, type, protocol)); diff --git a/src/io/fd.hpp b/src/io/fd.hpp index 6fb745d..d04d5bf 100644 --- a/src/io/fd.hpp +++ b/src/io/fd.hpp @@ -56,8 +56,13 @@ namespace io FD stdout() { return FD(1); } static FD stderr() { return FD(2); } + + static const int DEFAULT_MODE = 0666; + static - FD open(ZString path, int flags, int mode=0666); + FD open(ZString path, int flags, int mode=DEFAULT_MODE); + static + FD openat(FD dirfd, ZString path, int flags, int mode=DEFAULT_MODE); static FD socket(int domain, int type, int protocol); FD accept(struct sockaddr *addr, socklen_t *addrlen); @@ -65,6 +70,7 @@ namespace io int pipe(FD& r, FD& w); static int pipe2(FD& r, FD& w, int flags); + static FD sysconf_SC_OPEN_MAX(); diff --git a/src/io/read.cpp b/src/io/read.cpp index d057ca6..3ae5246 100644 --- a/src/io/read.cpp +++ b/src/io/read.cpp @@ -42,6 +42,10 @@ namespace io : fd(FD::open(name, O_RDONLY | O_CLOEXEC)), start(0), end(0) { } + ReadFile::ReadFile(const DirFd& dir, ZString name) + : fd(dir.open_fd(name, O_RDONLY | O_CLOEXEC)), start(0), end(0) + { + } ReadFile::~ReadFile() { fd.close(); diff --git a/src/io/read.hpp b/src/io/read.hpp index 6a44de6..1ec26ca 100644 --- a/src/io/read.hpp +++ b/src/io/read.hpp @@ -22,6 +22,7 @@ #include "../strings/fwd.hpp" +#include "dir.hpp" #include "fd.hpp" namespace tmwa @@ -39,6 +40,8 @@ namespace io ReadFile(FD fd); explicit ReadFile(ZString name); + ReadFile(const DirFd& dir, ZString name); + ReadFile& operator = (ReadFile&&) = delete; ReadFile(ReadFile&&) = delete; ~ReadFile(); diff --git a/src/io/write.cpp b/src/io/write.cpp index 3326d2c..833b173 100644 --- a/src/io/write.cpp +++ b/src/io/write.cpp @@ -41,6 +41,9 @@ namespace io WriteFile::WriteFile(ZString name, bool linebuffered) : fd(FD::open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)), lb(linebuffered), buflen(0) {} + WriteFile::WriteFile(const DirFd& dir, ZString name, bool linebuffered) + : fd(dir.open_fd(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)), lb(linebuffered), buflen(0) + {} WriteFile::~WriteFile() { if (fd != FD()) diff --git a/src/io/write.hpp b/src/io/write.hpp index 11bc679..1ab05f3 100644 --- a/src/io/write.hpp +++ b/src/io/write.hpp @@ -24,6 +24,7 @@ #include "../strings/fwd.hpp" +#include "dir.hpp" #include "fd.hpp" @@ -43,6 +44,8 @@ namespace io WriteFile(FD fd, bool linebuffered=false); explicit WriteFile(ZString name, bool linebuffered=false); + WriteFile(const DirFd& dir, ZString name, bool linebuffered=false); + WriteFile(WriteFile&&) = delete; WriteFile& operator = (WriteFile&&) = delete; ~WriteFile(); -- cgit v1.2.3-70-g09d2