21#include <sys/socket.h>
23#include <netinet/in.h>
36 enum { default_backlog = 128 };
39 explicit inline fd(
int f);
40 inline fd(
const fd& f);
44 inline fd& operator=(
const fd& f);
45 inline fd& operator=(fd&& f);
47 static void open(
const char* filename,
int flags, mode_t mode,
49 static inline void open(
const char* filename,
int flags, event<fd> result);
50 static fd open(
const char* filename,
int flags, mode_t mode = 0777);
52 static fd socket(
int domain,
int type,
int protocol);
53 static int pipe(fd& rfd, fd& wfd);
54 static inline int pipe(fd pfd[2]);
56 inline bool valid()
const;
57 inline explicit operator bool()
const;
58 inline int error()
const;
59 inline int fdnum()
const;
60 inline int recent_fdnum()
const;
62 inline void at_close(event<> e);
64 inline void close(event<int> done);
66 inline void close(
int errcode);
67 inline void error_close(
int errcode);
69 void read(
void* buf,
size_t size,
size_t* nread_ptr, event<int> done);
70 inline void read(
void* buf,
size_t size,
size_t& nread, event<int> done);
71 inline void read(
void* buf,
size_t size,
size_t& nread, event<> done);
72 inline void read(
void* buf,
size_t size, event<int> done);
73 inline void read(
void* buf,
size_t size, event<> done);
74 void read(
struct iovec* iov,
int iov_count,
size_t* nread_ptr, event<int> done);
75 inline void read(
struct iovec* iov,
int iov_count,
size_t& nread, event<int> done);
76 inline void read(
struct iovec* iov,
int iov_count,
size_t& nread, event<> done);
77 void read_once(
void* buf,
size_t size,
size_t& nread, event<int> done);
78 inline void read_once(
void* buf,
size_t size,
size_t& nread, event<> done);
79 void read_once(
const struct iovec* iov,
int iov_count,
size_t& nread, event<int> done);
80 inline void read_once(
const struct iovec* iov,
int iov_count,
size_t& nread, event<> done);
82 void write(
const void* buf,
size_t size,
size_t* nwritten_ptr, event<int> done);
83 inline void write(
const void* buf,
size_t size,
size_t& nwritten, event<int> done);
84 inline void write(
const void* buf,
size_t size,
size_t& nwritten, event<> done);
85 inline void write(
const void* buf,
size_t size, event<int> done);
86 inline void write(
const void* buf,
size_t size, event<> done);
87 void write(std::string buf,
size_t* nwritten_ptr, event<int> done);
88 inline void write(
const std::string& buf,
size_t& nwritten, event<int> done);
89 inline void write(
const std::string& buf,
size_t& nwritten, event<> done);
90 inline void write(
const std::string& buf, event<int> done);
91 inline void write(
const std::string& buf, event<> done);
92 void write(
struct iovec* iov,
int iov_count,
size_t* nwritten_ptr, event<int> done);
93 inline void write(
struct iovec* iov,
int iov_count,
size_t& nwritten, event<int> done);
94 inline void write(
struct iovec* iov,
int iov_count,
size_t& nwritten, event<> done);
95 void write_once(
const void* buf,
size_t size,
size_t& nwritten, event<int> done);
96 inline void write_once(
const void* buf,
size_t size,
size_t& nwritten, event<> done);
97 void write_once(
const struct iovec* iov,
int iov_count,
size_t& nwritten, event<int> done);
98 inline void write_once(
const struct iovec* iov,
int iov_count,
size_t& nwritten, event<> done);
99 bool write_closed()
const;
101 void sendmsg(
const void* buf,
size_t size,
int transfer_fd, event<int> done);
102 inline void sendmsg(
const void* buf,
size_t size, event<int> done);
104 void fstat(
struct stat& stat, event<int> done);
106 int listen(
int backlog = default_backlog);
107 int bind(
const struct sockaddr* addr, socklen_t addrlen);
108 void accept(
struct sockaddr* addr, socklen_t* addrlen, event<fd> result);
109 inline void accept(event<fd> result);
110 void connect(
const struct sockaddr* addr, socklen_t addrlen,
112 inline int shutdown(
int how);
113 inline int socket_error()
const;
115 ssize_t direct_read(
void* buf,
size_t size);
116 ssize_t direct_write(
const void* buf,
size_t size);
118 static int open_limit();
119 static int open_limit(
int n);
121 static int make_nonblocking(
int f);
122 static int make_blocking(
int f);
123 inline int make_nonblocking();
132#if HAVE_TAMER_FDHELPER
136 unsigned weak_count_;
139 : fde_(fd < 0 ? fd : 0), fdv_(fd)
140#if HAVE_TAMER_FDHELPER
143 , ref_count_(1), weak_count_(0) {
148 if (!ref_count_ && !weak_count_)
152 if (!--weak_count_ && !ref_count_)
155 int close(
int leave_error = -EBADF);
159 fdcloser(fd::fdimp* imp)
172 class closure__accept__P8sockaddrP9socklen_tQ2fd_;
void accept(closure__accept__P8sockaddrP9socklen_tQ2fd_&);
173 class closure__connect__PK8sockaddr9socklen_tQi_;
void connect(closure__connect__PK8sockaddr9socklen_tQi_&);
174 class closure__read__PvkPkQi_;
void read(closure__read__PvkPkQi_&);
175 class closure__read__P5ioveciPkQi_;
void read(closure__read__P5ioveciPkQi_&);
176 class closure__read_once__PvkRkQi_;
void read_once(closure__read_once__PvkRkQi_ &);
177 class closure__read_once__PK5ioveciRkQi_;
void read_once(closure__read_once__PK5ioveciRkQi_&);
178 class closure__write__PKvkPkQi_;
void write(closure__write__PKvkPkQi_ &);
179 class closure__write__SsPkQi_;
void write(closure__write__SsPkQi_ &);
180 class closure__write__P5ioveciPkQi_;
void write(closure__write__P5ioveciPkQi_&);
181 class closure__write_once__PKvkRkQi_;
void write_once(closure__write_once__PKvkRkQi_ &);
182 class closure__write_once__PK5ioveciRkQi_;
void write_once(closure__write_once__PK5ioveciRkQi_&);
183 class closure__sendmsg__PKvkiQi_;
void sendmsg(closure__sendmsg__PKvkiQi_ &);
184 class closure__open__PKci6mode_tQ2fd_;
static void open(closure__open__PKci6mode_tQ2fd_ &);
188 friend bool operator==(
const fd &a,
const fd &b);
189 friend bool operator!=(
const fd &a,
const fd &b);
195 enum ref_type { strong = 0, weak = 1 };
197 explicit inline fdref(
const fd& f);
198 explicit inline fdref(fd&& f);
199 inline fdref(
const fd& f, ref_type ref);
200 inline fdref(fd&& f, ref_type ref);
203 inline explicit operator bool()
const;
204 inline int fdnum()
const;
206 inline void acquire_read(event<> done);
207 inline void release_read();
208 inline ssize_t read(
void* buf,
size_t size);
210 inline void acquire_write(event<> done);
211 inline void release_write();
212 inline ssize_t write(
const void* buf,
size_t size);
215 inline void close(
int errcode);
218 enum { read_locked = 2, write_locked = 4 };
222 fdref(
const fdref&) =
delete;
223 fdref& operator=(
const fdref&) =
delete;
232void tcp_connect(
struct in_addr addr,
int port,
event<fd> result);
233inline void tcp_connect(
int port,
event<fd> result);
235void udp_connect(
struct in_addr addr,
int port,
event<fd> result);
237fd unix_stream_listen(std::string path,
int backlog);
238inline fd unix_stream_listen(std::string path);
239void unix_stream_connect(std::string path,
event<fd> result);
244 fdtype_newin, fdtype_newout, fdtype_share, fdtype_transfer
249 inline exec_fd(
int child_fd, fdtype type, fd f = fd());
252pid_t exec(std::vector<exec_fd>& exec_fds,
const char* program,
bool path,
253 const std::vector<const char*> &argv,
char*
const envp[]);
254inline pid_t execv(fd& in, fd& out,
const char* program,
255 const std::vector<const char*>& argv);
256inline pid_t execv(fd& in, fd& out, fd& err,
const char* program,
257 const std::vector<const char*>& argv);
258inline pid_t execvp(fd& in, fd& out,
const char* program,
259 const std::vector<const char*>& argv);
260inline pid_t execvp(fd& in, fd& out, fd& err,
const char* program,
261 const std::vector<const char*>& argv);
283inline fd::fd(
int value)
284 : _p(value == -EBADF ? 0 : new fdimp(value)) {
295inline fd::fd(
const fd &f)
318inline fd& fd::operator=(
const fd& f) {
327inline fd& fd::operator=(fd&& f) {
345inline void fd::open(
const char* filename,
int flags, event<fd> f) {
346 open(filename, flags, 0777, f);
355inline int fd::pipe(fd pfd[2]) {
356 return pipe(pfd[0], pfd[1]);
362inline bool fd::valid()
const {
363 return _p && _p->fde_ >= 0;
369inline fd::operator bool()
const {
370 return _p && _p->fde_ >= 0;
377inline int fd::error()
const {
378 return _p ? _p->fde_ : -EBADF;
385inline int fd::fdnum()
const {
386 assert(_p && _p->fde_ >= 0);
393inline int fd::recent_fdnum()
const {
394 return _p ? _p->fdv_ : -EBADF;
404inline void fd::at_close(event<> e) {
406 _p->_at_close += std::move(e);
417inline void fd::close(event<int> done)
419 done.trigger(*
this ? _p->close() : -EBADF);
424inline void fd::close()
436inline void fd::accept(event<fd> result) {
437 accept(0, 0, result);
442inline int fd::shutdown(
int how) {
443 if (_p && _p->fde_ >= 0)
444 return ::shutdown(_p->fdv_, how);
450inline int fd::socket_error()
const {
451 if (_p && _p->fde_ >= 0) {
453 socklen_t len =
sizeof(error);
454 int r = getsockopt(_p->fdv_, SOL_SOCKET, SO_ERROR, &error, &len);
455 return r ? -error : 0;
474inline void fd::read(
void* buf,
size_t size,
size_t& nread, event<int> done) {
475 read(buf, size, &nread, done);
478inline void fd::read(
void* buf,
size_t size,
size_t& nread, event<> done) {
479 read(buf, size, &nread, rebind<int>(done));
492inline void fd::read(
void* buf,
size_t size, event<int> done) {
493 read(buf, size, (
size_t*) 0, done);
496inline void fd::read(
void* buf,
size_t size, event<> done) {
497 read(buf, size, (
size_t*) 0, rebind<int>(done));
514inline void fd::read(
struct iovec* iov,
int iov_count,
size_t& nread, event<int> done) {
515 read(iov, iov_count, &nread, done);
518inline void fd::read(
struct iovec* iov,
int iov_count,
size_t& nread, event<> done) {
519 read(iov, iov_count, &nread, rebind<int>(done));
537inline void fd::read_once(
void *buf,
size_t size,
size_t& nread, event<> done) {
538 read_once(buf, size, nread, rebind<int>(done));
556inline void fd::read_once(
const struct iovec* iov,
int iov_count,
size_t& nread, event<> done) {
557 read_once(iov, iov_count, nread, rebind<int>(done));
572inline void fd::write(
const void *buf,
size_t size,
size_t& nwritten, event<int> done) {
573 write(buf, size, &nwritten, done);
576inline void fd::write(
const void *buf,
size_t size,
size_t& nwritten, event<> done) {
577 write(buf, size, &nwritten, rebind<int>(done));
592inline void fd::write(
struct iovec* iov,
int iov_count,
size_t& nwritten, event<int> done) {
593 write(iov, iov_count, &nwritten, done);
596inline void fd::write(
struct iovec* iov,
int iov_count,
size_t& nwritten, event<> done) {
597 write(iov, iov_count, &nwritten, rebind<int>(done));
608inline void fd::write(
const void *buf,
size_t size, event<int> done) {
609 write(buf, size, 0, done);
612inline void fd::write(
const void *buf,
size_t size, event<> done) {
613 write(buf, size, 0, rebind<int>(done));
623inline void fd::write(
const std::string& buf,
size_t& nwritten, event<int> done) {
624 write(buf, &nwritten, done);
627inline void fd::write(
const std::string& buf,
size_t& nwritten, event<> done) {
628 write(buf, &nwritten, rebind<int>(done));
637inline void fd::write(
const std::string& buf, event<int> done) {
638 write(buf, (
size_t*) 0, done);
641inline void fd::write(
const std::string &buf, event<> done) {
642 write(buf, (
size_t*) 0, rebind<int>(done));
645inline void fd::write_once(
const void *buf,
size_t size,
size_t& nwritten, event<> done) {
646 write_once(buf, size, nwritten, rebind<int>(done));
649inline void fd::write_once(
const struct iovec* iov,
int iov_count,
size_t& nwritten, event<> done) {
650 write_once(iov, iov_count, nwritten, rebind<int>(done));
655inline void fd::sendmsg(
const void *buf,
size_t size, event<int> done) {
656 sendmsg(buf, size, -1, done);
665inline void fd::close(
int errcode) {
668 else if (errcode < 0 && errcode != -EBADF)
669 _p =
new fdimp(errcode);
673inline void fd::error_close(
int errcode) {
680inline int fd::make_nonblocking() {
681 return make_nonblocking(_p ? _p->fde_ : -EBADF);
704 : imp_(0), flags_(0) {
707inline fdref::fdref(
const fd& f)
708 : imp_(f._p), flags_(0) {
713inline fdref::fdref(fd&& f)
714 : imp_(f._p), flags_(0) {
718inline fdref::fdref(
const fd& f, ref_type ref)
719 : imp_(f._p), flags_(ref) {
720 if (imp_ && ref == weak)
726inline fdref::fdref(fd&& f, ref_type ref)
727 : imp_(f._p), flags_(ref) {
729 if (imp_ && ref == weak) {
735inline fdref::~fdref() {
736 if (imp_ && (flags_ & read_locked))
737 imp_->rlock_.release();
738 if (imp_ && (flags_ & write_locked))
739 imp_->wlock_.release();
740 if (imp_ && (flags_ & weak))
746inline fdref::operator bool()
const {
747 return imp_ && imp_->fde_ >= 0;
750inline int fdref::fdnum()
const {
751 assert(imp_ && imp_->fde_ >= 0);
755inline void fdref::acquire_read(event<> done) {
756 assert(!(flags_ & read_locked));
757 flags_ |= read_locked;
759 imp_->rlock_.acquire(std::move(done));
764inline void fdref::release_read() {
765 assert(flags_ & read_locked);
766 flags_ &= ~read_locked;
768 imp_->rlock_.release();
771inline ssize_t fdref::read(
void* buf,
size_t size) {
772 assert(flags_ & read_locked);
773 if (imp_ && imp_->fde_ >= 0)
774 return ::read(imp_->fdv_, buf, size);
781inline void fdref::acquire_write(event<> done) {
782 assert(!(flags_ & write_locked));
783 flags_ |= write_locked;
785 imp_->wlock_.acquire(std::move(done));
790inline void fdref::release_write() {
791 assert(flags_ & write_locked);
792 flags_ &= ~write_locked;
794 imp_->wlock_.release();
797inline ssize_t fdref::write(
const void* buf,
size_t size) {
798 assert(flags_ & write_locked);
799 if (imp_ && imp_->fde_ >= 0)
800 return ::write(imp_->fdv_, buf, size);
807inline void fdref::close() {
812inline void fdref::close(
int errcode) {
814 imp_->close(errcode);
839 tcp_listen(port, fd::default_backlog, result);
852inline void tcp_connect(
int port, event<fd> result) {
854 in.s_addr = ntohl(INADDR_LOOPBACK);
855 tcp_connect(in, port, std::move(result));
858inline fd unix_stream_listen(std::string path) {
859 return unix_stream_listen(std::move(path), fd::default_backlog);
862inline exec_fd::exec_fd(
int child_fd, fdtype type, fd f)
863 : child_fd(child_fd), type(type), f(f) {
866inline pid_t execv(fd &in, fd &out,
const char *program,
867 const std::vector<const char *> &argv) {
868 std::vector<exec_fd> efd;
869 efd.push_back(exec_fd(STDIN_FILENO, exec_fd::fdtype_newin));
870 efd.push_back(exec_fd(STDOUT_FILENO, exec_fd::fdtype_newout));
871 pid_t r = exec(efd, program,
false, argv, 0);
877inline pid_t execv(fd &in, fd &out, fd &err,
const char *program,
878 const std::vector<const char *> &argv) {
879 std::vector<exec_fd> efd;
880 efd.push_back(exec_fd(STDIN_FILENO, exec_fd::fdtype_newin));
881 efd.push_back(exec_fd(STDOUT_FILENO, exec_fd::fdtype_newout));
882 efd.push_back(exec_fd(STDERR_FILENO, exec_fd::fdtype_newout));
883 pid_t r = exec(efd, program,
false, argv, 0);
890inline pid_t execvp(fd &in, fd &out,
const char *program,
891 const std::vector<const char *> &argv) {
892 std::vector<exec_fd> efd;
893 efd.push_back(exec_fd(STDIN_FILENO, exec_fd::fdtype_newin));
894 efd.push_back(exec_fd(STDOUT_FILENO, exec_fd::fdtype_newout));
895 pid_t r = exec(efd, program,
true, argv, 0);
901inline pid_t execvp(fd &in, fd &out, fd &err,
const char *program,
902 const std::vector<const char *> &argv) {
903 std::vector<exec_fd> efd;
904 efd.push_back(exec_fd(STDIN_FILENO, exec_fd::fdtype_newin));
905 efd.push_back(exec_fd(STDOUT_FILENO, exec_fd::fdtype_newout));
906 efd.push_back(exec_fd(STDERR_FILENO, exec_fd::fdtype_newout));
907 pid_t r = exec(efd, program,
true, argv, 0);
A future occurrence.
Definition event.hh:116
void trigger(T0 v0, T1 v1, T2 v2, T3 v3)
Trigger event.
Definition event.hh:742
Classes for event-based synchronization.
Namespace containing public Tamer classes and functions for the Tamer core.
Definition adapter.hh:17
fd tcp_listen(int port)
Open a nonblocking TCP connection on port port.
Definition fd.hh:848
bool operator!=(const fd &a, const fd &b)
Test whether two file descriptors refer to the same object.
Definition fd.hh:698
bool operator==(const fd &a, const fd &b)
Test whether two file descriptors refer to the same object.
Definition fd.hh:689
The main Tamer header file.