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/conf/install.hpp | 30 +++++++++++++++++++ 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 ++ src/mmo/core.cpp | 5 ++++ src/shared/lib.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ src/strings/literal.hpp | 5 ++-- 12 files changed, 246 insertions(+), 3 deletions(-) create mode 100644 src/conf/install.hpp create mode 100644 src/io/dir.cpp create mode 100644 src/io/dir.hpp create mode 100644 src/shared/lib.cpp (limited to 'src') 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 +// +// 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 . + +// 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 +// +// 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(); 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 #include +#include + #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(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 +// shared/lib.cpp - Public library to ensure install is working. +// +// 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 "../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 { 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; public: iterator begin() const; -- cgit v1.2.3-60-g2f50