diff --git a/hphp/runtime/base/file/socket.cpp b/hphp/runtime/base/file/socket.cpp index ca93e58e8..ba4fcd576 100644 --- a/hphp/runtime/base/file/socket.cpp +++ b/hphp/runtime/base/file/socket.cpp @@ -53,15 +53,20 @@ Socket::Socket() } Socket::Socket(int sockfd, int type, const char *address /* = NULL */, - int port /* = 0 */) + int port /* = 0 */, double timeout /* = 0 */) : File(true), m_port(port), m_type(type), m_error(0), m_eof(false), m_timeout(0), m_timedOut(false), m_bytesSent(0) { if (address) m_address = address; m_fd = sockfd; struct timeval tv; - tv.tv_sec = RuntimeOption::SocketDefaultTimeout; - tv.tv_usec = 0; + if (timeout <= 0) { + tv.tv_sec = RuntimeOption::SocketDefaultTimeout; + tv.tv_usec = 0; + } else { + tv.tv_sec = (int)timeout; + tv.tv_usec = (timeout - tv.tv_sec) * 1e6; + } setsockopt(m_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); s_socket_data->m_lastErrno = errno; setsockopt(m_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); diff --git a/hphp/runtime/base/file/socket.h b/hphp/runtime/base/file/socket.h index f1713d315..aef78125b 100644 --- a/hphp/runtime/base/file/socket.h +++ b/hphp/runtime/base/file/socket.h @@ -38,7 +38,8 @@ public: // we need to support pfsockopen() that can make a socket persistent. Socket(); - Socket(int sockfd, int type, const char *address = nullptr, int port = 0); + Socket(int sockfd, int type, const char *address = nullptr, int port = 0, + double timeout = 0); virtual ~Socket(); static StaticString s_class_name; diff --git a/hphp/runtime/ext/ext_socket.cpp b/hphp/runtime/ext/ext_socket.cpp index 84f46f8f1..0bfd99bd4 100644 --- a/hphp/runtime/ext/ext_socket.cpp +++ b/hphp/runtime/ext/ext_socket.cpp @@ -281,7 +281,8 @@ static int php_read(Socket *sock, void *buf, int maxlen, int flags) { } static bool create_new_socket(const char *&name, int port, Variant &errnum, - Variant &errstr, Object &ret, Socket *&sock) { + Variant &errstr, Object &ret, Socket *&sock, + double timeout) { int domain = AF_INET; int type = SOCK_STREAM; if (strncmp(name, "udp://", 6) == 0 || strncmp(name, "udg://", 6) == 0) { @@ -294,7 +295,7 @@ static bool create_new_socket(const char *&name, int port, Variant &errnum, name += 7; } - sock = new Socket(socket(domain, type, 0), domain, name, port); + sock = new Socket(socket(domain, type, 0), domain, name, port, timeout); ret = Object(sock); if (!sock->valid()) { SOCKET_ERROR(sock, "unable to create socket", errno); @@ -664,7 +665,7 @@ Variant f_socket_server(CStrRef hostname, int port /* = -1 */, Object ret; Socket *sock = NULL; const char *name = hostname.data(); - if (!create_new_socket(name, port, errnum, errstr, ret, sock)) { + if (!create_new_socket(name, port, errnum, errstr, ret, sock, 0.0)) { return false; } assert(ret.get() && sock); @@ -1000,12 +1001,14 @@ static Variant sockopen_impl(CStrRef hostname, int port, Variant &errnum, const char *name = hostname.data(); Socket *sock = NULL; + if (timeout <= 0) timeout = RuntimeOption::SocketDefaultTimeout; // test if protocol is SSL SSLSocket *sslsock = SSLSocket::Create(name, port, timeout); if (sslsock) { sock = sslsock; ret = sock; - } else if (!create_new_socket(name, port, errnum, errstr, ret, sock)) { + } else if (!create_new_socket(name, port, errnum, errstr, + ret, sock, timeout)) { return false; } assert(ret.get() && sock);