summaryrefslogtreecommitdiff
path: root/src/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/io')
-rw-r--r--src/io/dir.cpp54
-rw-r--r--src/io/dir.hpp50
-rw-r--r--src/io/fd.cpp4
-rw-r--r--src/io/fd.hpp8
-rw-r--r--src/io/read.cpp4
-rw-r--r--src/io/read.hpp3
-rw-r--r--src/io/write.cpp3
-rw-r--r--src/io/write.hpp3
8 files changed, 128 insertions, 1 deletions
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();