Refactoring
[invirt/third/libt4.git] / rpc / file.h
1 #ifndef file_h
2 #define file_h
3
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include "types.h"
7 #include <sys/socket.h>
8
9 class file_t {
10     private:
11         int fd_;
12
13         class flags_t {
14             private:
15                 const file_t & f_;
16                 int flags_;
17             public:
18                 flags_t(const file_t & f) : f_(f), flags_(fcntl(f_.fd_, F_GETFL, NULL)) { }
19                 ~flags_t() { fcntl(f_.fd_, F_SETFL, flags_); }
20                 operator int & () { return flags_; }
21         };
22     public:
23         inline file_t(int fd=-1) : fd_(fd) {}
24         inline file_t(const file_t &) = delete;
25         inline file_t(file_t && other) : fd_(-1) { std::swap(fd_, other.fd_); }
26         inline ~file_t() { if (fd_ != -1) ::close(fd_); }
27         static inline void pipe(file_t *ends) {
28             int fds[2];
29             VERIFY(::pipe(fds) == 0);
30             ends[0].fd_ = fds[0];
31             ends[1].fd_ = fds[1];
32         }
33         inline operator int() const { if (fd_ == -1) throw "no fd"; return fd_; }
34         inline flags_t flags() const { return *this; }
35         inline void close() {
36             ::close(fd_);
37             fd_ = -1;
38         }
39         template <class T>
40         inline ssize_t read(T & t) const { return ::read(fd_, &t, sizeof(T)); }
41         inline ssize_t read(void * t, size_t n) const { return ::read(fd_, t, n); }
42         template <class T>
43         inline ssize_t write(const T & t) const { return ::write(fd_, &t, sizeof(T)); }
44         inline ssize_t write(const void * t, size_t n) const { return ::write(fd_, t, n); }
45 };
46
47 class socket_t : public file_t {
48     public:
49         socket_t(int fd=-1) : file_t(fd) {}
50         template <class T>
51         int setsockopt(int level, int option, T && value) {
52             return ::setsockopt(*this, level, option, &value, sizeof(T));
53         }
54 };
55
56 #endif