2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #include "hphp/util/afdt-util.h"
21 #include <system_error>
23 #include "hphp/util/assertions.h"
27 ///////////////////////////////////////////////////////////////////////////////
32 void append(std::vector
<iovec
>& iov
, const void* addr
, size_t size
) {
36 io
.iov_base
= const_cast<void*>(addr
);
42 void sappend(int afdt_fd
,
43 std::vector
<iovec
>& iov
, const void* addr
, size_t size
) {
44 if (iov
.size() == IOV_MAX
) {
48 append(iov
, addr
, size
);
51 void rappend(int afdt_fd
,
52 std::vector
<iovec
>& iov
, void* addr
, size_t size
) {
53 if (iov
.size() == IOV_MAX
) {
57 append(iov
, addr
, size
);
60 void send(int afdt_fd
, std::vector
<iovec
>& iov
) {
61 if (iov
.size() == 0) return;
64 memset(&msg
, 0, sizeof(msg
));
65 msg
.msg_iov
= &iov
[0];
66 msg
.msg_iovlen
= iov
.size();
67 ssize_t nwritten
= sendmsg(afdt_fd
, &msg
, MSG_WAITALL
);
69 throw std::system_error(errno
, std::generic_category(), "send failed");
71 for (auto& io
: iov
) {
72 nwritten
-= io
.iov_len
;
74 if (nwritten
) throw std::runtime_error("sent wrong number of bytes");
77 void recv(int afdt_fd
, std::vector
<iovec
>& iov
) {
78 if (iov
.size() == 0) return;
81 memset(&msg
, 0, sizeof(msg
));
82 msg
.msg_iov
= &iov
[0];
83 msg
.msg_iovlen
= iov
.size();
84 ssize_t nread
= recvmsg(afdt_fd
, &msg
, MSG_WAITALL
);
86 throw std::system_error(errno
, std::generic_category(), "recv failed");
88 for (auto& io
: iov
) {
91 if (nread
) throw std::runtime_error("recv received wrong number of bytes");
96 bool send_fd(int afdt_fd
, int fd
) {
97 afdt_error_t err
= AFDT_ERROR_T_INIT
;
99 int ret
= afdt_send_fd_msg(afdt_fd
, nullptr, 0, fd
, &err
);
100 if (ret
< 0 && errno
== 0) {
101 // Set non-empty errno if afdt_send_fd_msg doesn't set one on error
107 int recv_fd(int afdt_fd
) {
111 int flags
= fcntl(0, F_GETFD
);
112 always_assert(flags
!= -1 || errno
!= EBADF
);
116 afdt_error_t err
= AFDT_ERROR_T_INIT
;
117 uint32_t afdt_len
= 0;
119 if (afdt_recv_fd_msg(afdt_fd
, nullptr, &afdt_len
, &fd
, &err
) < 0) {
121 // Set non-empty errno if afdt_send_fd_msg doesn't set one on error
129 ///////////////////////////////////////////////////////////////////////////////