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 +----------------------------------------------------------------------+
19 #include "hphp/runtime/base/file.h"
21 #include <folly/portability/Sockets.h>
23 #include <sys/types.h>
28 #define SOCKET_ERROR(sock, msg, errn) \
29 sock->setError(errn); \
30 if (errn != EAGAIN && errn != EWOULDBLOCK && errn != EINPROGRESS) { \
31 raise_warning("%s [%d]: %s", msg, errn, \
32 folly::errnoStr(errn).c_str()); \
36 ///////////////////////////////////////////////////////////////////////////////
38 struct SocketData
: FileData
{
39 explicit SocketData(bool nonblocking
) : FileData(nonblocking
) { }
40 SocketData(int port
, int type
, bool nonblocking
);
42 bool closeImpl() override
;
43 ~SocketData() override
;
47 std::string m_address
;
50 int64_t m_bytesSent
{0};
52 int m_timeout
{0}; // in micro-seconds;
53 bool m_timedOut
{false};
60 struct Socket
: File
{
61 DECLARE_RESOURCE_ALLOCATION(Socket
);
65 // overriding ResourceData
66 const String
& o_getClassNameHook() const override
{ return classnameof(); }
69 bool open(const String
& filename
, const String
& mode
) override
;
70 int64_t readImpl(char *buffer
, int64_t length
) override
;
71 int64_t writeImpl(const char *buffer
, int64_t length
) override
;
73 Array
getMetaData() override
;
74 int64_t tell() override
;
76 // check if the socket is still open
77 virtual bool checkLiveness();
79 void setError(int err
);
80 int getError() const { return m_data
->m_error
;}
81 static int getLastError() { return *s_lastErrno
; }
82 static void clearLastError() {*s_lastErrno
= 0; }
83 int getType() const { return m_data
->m_type
;}
85 // This is only for updating a local copy of timeouts set by setsockopt()
86 // outside of this class.
87 void internalSetTimeout(struct timeval
&tv
);
89 std::string
getAddress() const { return m_data
->m_address
; }
90 int getPort() const { return m_data
->m_port
; }
92 std::shared_ptr
<SocketData
> getData() const {
93 return std::static_pointer_cast
<SocketData
>(File::getData());
98 bool timedOut() const { return m_data
->m_timedOut
; }
100 explicit Socket(bool nonblocking
= true);
101 Socket(int sockfd
, int type
, const char *address
= nullptr, int port
= 0,
102 double timeout
= 0, const StaticString
& streamType
= empty_string_ref
,
103 bool nonblocking
= true);
104 Socket(std::shared_ptr
<SocketData
> data
,
107 const char *address
= nullptr,
110 const StaticString
& streamType
= empty_string_ref
);
111 explicit Socket(std::shared_ptr
<SocketData
> data
);
114 SocketData
* getSocketData() { return m_data
; }
115 const SocketData
* getSocketData() const { return m_data
; }
118 void inferStreamType();
120 static RDS_LOCAL(int, s_lastErrno
);
123 // This class provides exactly the same functionality as Socket but reports as a
124 // class/resource of 'Socket' instead of 'stream'.
125 struct ConcreteSocket final
: Socket
{
126 CLASSNAME_IS("Socket");
127 RESOURCENAME_IS("Socket");
129 explicit ConcreteSocket(bool nonblocking
= true)
130 : Socket(nonblocking
)
132 ConcreteSocket(int sockfd
, int type
, const char *address
= nullptr,
133 int port
= 0, double timeout
= 0,
134 const StaticString
& streamType
= empty_string_ref
,
135 bool nonblocking
= true)
136 : Socket(sockfd
, type
, address
, port
, timeout
, streamType
, nonblocking
)
138 explicit ConcreteSocket(std::shared_ptr
<SocketData
> data
) : Socket(data
) { }
140 // overriding ResourceData
141 const String
& o_getClassNameHook() const override
{ return classnameof(); }
142 const String
& o_getResourceName() const override
{ return resourcenameof(); }
145 // This class provides exactly the same functionality as ConcreteSocket but
146 // reports the default behavior for File.
147 struct StreamSocket final
: Socket
{
148 explicit StreamSocket(bool nonblocking
= true)
149 : Socket(nonblocking
)
151 StreamSocket(int sockfd
, int type
, const char *address
= nullptr,
152 int port
= 0, double timeout
= 0,
153 const StaticString
& streamType
= empty_string_ref
,
154 bool nonblocking
= true)
155 : Socket(sockfd
, type
, address
, port
, timeout
, streamType
, nonblocking
)
157 explicit StreamSocket(std::shared_ptr
<SocketData
> data
) : Socket(data
) { }
160 ///////////////////////////////////////////////////////////////////////////////