diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2014-07-17 16:50:40 -0700 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2014-07-17 23:35:14 -0700 |
commit | 25070b355b8a0394c1fbd9cf82c44752b5a8b8c3 (patch) | |
tree | 5e8edf1e5e3f58a8b11b1fcdd2fa851b2322df35 /src | |
parent | 3b0b6deecf156916a9fb68dda9ca4b8a47d65aab (diff) | |
download | tmwa-25070b355b8a0394c1fbd9cf82c44752b5a8b8c3.tar.gz tmwa-25070b355b8a0394c1fbd9cf82c44752b5a8b8c3.tar.bz2 tmwa-25070b355b8a0394c1fbd9cf82c44752b5a8b8c3.tar.xz tmwa-25070b355b8a0394c1fbd9cf82c44752b5a8b8c3.zip |
Add dir annoyances
Diffstat (limited to 'src')
-rw-r--r-- | src/conf/install.hpp | 30 | ||||
-rw-r--r-- | src/io/dir.cpp | 54 | ||||
-rw-r--r-- | src/io/dir.hpp | 50 | ||||
-rw-r--r-- | src/io/fd.cpp | 4 | ||||
-rw-r--r-- | src/io/fd.hpp | 8 | ||||
-rw-r--r-- | src/io/read.cpp | 4 | ||||
-rw-r--r-- | src/io/read.hpp | 3 | ||||
-rw-r--r-- | src/io/write.cpp | 3 | ||||
-rw-r--r-- | src/io/write.hpp | 3 | ||||
-rw-r--r-- | src/mmo/core.cpp | 5 | ||||
-rw-r--r-- | src/shared/lib.cpp | 80 | ||||
-rw-r--r-- | src/strings/literal.hpp | 5 |
12 files changed, 246 insertions, 3 deletions
diff --git a/src/conf/install.hpp b/src/conf/install.hpp new file mode 100644 index 0000000..42fd125 --- /dev/null +++ b/src/conf/install.hpp @@ -0,0 +1,30 @@ +#pragma once +// conf/install.hpp - Import configuration variables related to install. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// 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 <http://www.gnu.org/licenses/>. + +// just mention "fwd.hpp" to make formatter happy + +#include "conf-raw/str-PACKAGESYSCONFDIR.h" +#include "conf-raw/str-PACKAGELOCALSTATEDIR.h" +#include "conf-raw/str-PACKAGEDATADIR.h" + + +namespace tmwa +{ +} // namespace tmwa 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 <b.r.longbons@gmail.com> +// +// 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 <http://www.gnu.org/licenses/>. + +#include <fcntl.h> + +#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 <b.r.longbons@gmail.com> +// +// 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 <http://www.gnu.org/licenses/>. + +#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(); diff --git a/src/mmo/core.cpp b/src/mmo/core.cpp index 2264ec6..f1a8d07 100644 --- a/src/mmo/core.cpp +++ b/src/mmo/core.cpp @@ -27,6 +27,8 @@ #include <csignal> #include <cstdlib> +#include <tmwa/shared.hpp> + #include "../strings/zstring.hpp" #include "../strings/literal.hpp" @@ -107,6 +109,9 @@ void sig_proc(int) int main(int argc, char **argv) { using namespace tmwa; + + check_paths(); + // ZString args[argc]; is (deliberately!) not supported by clang yet ZString *args = static_cast<ZString *>(alloca(argc * sizeof(ZString))); for (int i = 0; i < argc; ++i) diff --git a/src/shared/lib.cpp b/src/shared/lib.cpp new file mode 100644 index 0000000..a9dc9b1 --- /dev/null +++ b/src/shared/lib.cpp @@ -0,0 +1,80 @@ +#include <tmwa/shared.hpp> +// shared/lib.cpp - Public library to ensure install is working. +// +// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com> +// +// 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 <http://www.gnu.org/licenses/>. + +#include "../conf/install.hpp" + +#include "../strings/literal.hpp" +#include "../strings/astring.hpp" +#include "../strings/zstring.hpp" + +#include "../io/cxxstdio.hpp" +#include "../io/dir.hpp" +#include "../io/read.hpp" +#include "../io/write.hpp" + +#include "../poison.hpp" + + +namespace tmwa +{ +#define PRINT_VAR(var) PRINTF("%s = %s\n"_fmt, #var##_s, var) + + static + void try_read(const io::DirFd& dirfd, ZString filename) + { + io::ReadFile rf(dirfd, filename); + if (!rf.is_open()) + abort(); + AString line; + if (!rf.getline(line)) + abort(); + } + + static + void try_write(const io::DirFd& dirfd, ZString filename) + { + io::WriteFile wf(dirfd, filename); + if (!wf.is_open()) + abort(); + wf.put_line("Hello, World!"_s); + if (!wf.close()) + abort(); + } + + void check_paths() + { + ZString portable_root(strings::really_construct_from_a_pointer, getenv("TMWA_PORTABLE") ?: "", nullptr); + bool portable = bool(portable_root); + if (!portable) + portable_root = "."_s; + + io::DirFd root(portable_root); + + io::DirFd etc(root, PACKAGESYSCONFDIR.xslice_t(portable)); + io::DirFd var(root, PACKAGELOCALSTATEDIR.xslice_t(portable)); + io::DirFd share(root, PACKAGEDATADIR.xslice_t(portable)); + + try_read(etc, "shared.conf"_s); + try_read(share, "shared.data"_s); + try_write(var, "shared.test"_s); + + // io::FD::open(); + } +} // namespace tmwa diff --git a/src/strings/literal.hpp b/src/strings/literal.hpp index 5e27a9f..67bd317 100644 --- a/src/strings/literal.hpp +++ b/src/strings/literal.hpp @@ -32,11 +32,12 @@ namespace strings class LString : public _crtp_string<LString, AString, LPair> { iterator _b, _e; - // optional - const RString *_base; private: LString(const char *b, const char *e); friend LString operator "" _s(const char *, size_t); + // for tail slicing + LString(const char *b, const char *e, const RString *) : LString(b, e) {} + friend class _crtp_string<LString, AString, LPair>; public: iterator begin() const; |