summaryrefslogtreecommitdiff
path: root/src/io/fd.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/io/fd.hpp')
-rw-r--r--src/io/fd.hpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/src/io/fd.hpp b/src/io/fd.hpp
new file mode 100644
index 0000000..e4bcff7
--- /dev/null
+++ b/src/io/fd.hpp
@@ -0,0 +1,159 @@
+#ifndef TMWA_IO_FD_HPP
+#define TMWA_IO_FD_HPP
+// io/fd.hpp - typesafe (but not scopesafe) file descriptors
+//
+// 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 "../sanity.hpp"
+
+# include <sys/select.h>
+# include <sys/socket.h>
+
+# include <unistd.h>
+
+# include "../strings/fwd.hpp"
+
+
+namespace io
+{
+ class FD
+ {
+ private:
+ int fd;
+
+ explicit
+ FD(int f)
+ : fd(f)
+ {}
+ public:
+ FD()
+ : fd(-1)
+ {}
+
+ int uncast_dammit() { return fd; }
+ static
+ FD cast_dammit(int f) { return FD(f); }
+
+ static
+ FD stdin() { return FD(0); }
+ static
+ FD stdout() { return FD(1); }
+ static
+ FD stderr() { return FD(2); }
+ static
+ FD open(ZString path, int flags, int mode=0666);
+ static
+ FD socket(int domain, int type, int protocol);
+ FD accept(struct sockaddr *addr, socklen_t *addrlen);
+ static
+ int pipe(FD& r, FD& w);
+ static
+ int pipe2(FD& r, FD& w, int flags);
+ static
+ FD sysconf_SC_OPEN_MAX();
+
+ FD next() { return FD(fd + 1); }
+ FD prev() { return FD(fd - 1); }
+
+ ssize_t read(void *buf, size_t count);
+ ssize_t write(const void *buf, size_t count);
+ ssize_t pread(void *buf, size_t count, off_t offset);
+ ssize_t pwrite(const void *buf, size_t count, off_t offset);
+ ssize_t readv(const struct iovec *iov, int iovcnt);
+ ssize_t writev(const struct iovec *iov, int iovcnt);
+ ssize_t preadv(const struct iovec *iov, int iovcnt, off_t offset);
+ ssize_t pwritev(const struct iovec *iov, int iovcnt, off_t offset);
+
+ int close();
+ int shutdown(int);
+ int getsockopt(int level, int optname, void *optval, socklen_t *optlen);
+ int setsockopt(int level, int optname, const void *optval, socklen_t optlen);
+ // ...
+ int fcntl(int cmd);
+ int fcntl(int cmd, int arg);
+ int fcntl(int cmd, void *arg);
+ int listen(int backlog);
+ int bind(const struct sockaddr *addr, socklen_t addrlen);
+ int connect(const struct sockaddr *addr, socklen_t addrlen);
+ FD dup();
+ FD dup2(FD newfd);
+ FD dup3(FD newfd, int flags);
+
+
+ friend
+ bool operator == (FD l, FD r)
+ {
+ return l.fd == r.fd;
+ }
+ friend
+ bool operator != (FD l, FD r)
+ {
+ return l.fd != r.fd;
+ }
+ friend
+ bool operator < (FD l, FD r)
+ {
+ return l.fd < r.fd;
+ }
+ friend
+ bool operator <= (FD l, FD r)
+ {
+ return l.fd <= r.fd;
+ }
+ friend
+ bool operator > (FD l, FD r)
+ {
+ return l.fd > r.fd;
+ }
+ friend
+ bool operator >= (FD l, FD r)
+ {
+ return l.fd >= r.fd;
+ }
+ };
+
+ class FD_Set
+ {
+ private:
+ fd_set fds;
+ public:
+ FD_Set()
+ {
+ FD_ZERO(&fds);
+ }
+ void clr(FD fd)
+ {
+ FD_CLR(fd.uncast_dammit(), &fds);
+ }
+ bool isset(FD fd)
+ {
+ return FD_ISSET(fd.uncast_dammit(), &fds);
+ }
+ void set(FD fd)
+ {
+ FD_SET(fd.uncast_dammit(), &fds);
+ }
+
+ static
+ int select(int nfds, FD_Set *readfds, FD_Set *writefds, FD_Set *exceptfds, struct timeval *timeout);
+ static
+ int pselect(int nfds, FD_Set *readfds, FD_Set *writefds, FD_Set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);
+ };
+} // namespace io
+
+#endif //TMWA_IO_FD_HPP