THRIFT-900. cpp: Unix domain socket
This patch adds a new Unix Socket transport.
Patch: Roger Meier
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@1002179 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TSocket.cpp b/lib/cpp/src/transport/TSocket.cpp
index 5da33bb..951ddcf 100644
--- a/lib/cpp/src/transport/TSocket.cpp
+++ b/lib/cpp/src/transport/TSocket.cpp
@@ -21,6 +21,7 @@
#include <cstring>
#include <sstream>
#include <sys/socket.h>
+#include <sys/un.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <arpa/inet.h>
@@ -50,6 +51,23 @@
TSocket::TSocket(string host, int port) :
host_(host),
port_(port),
+ path_(""),
+ socket_(-1),
+ connTimeout_(0),
+ sendTimeout_(0),
+ recvTimeout_(0),
+ lingerOn_(1),
+ lingerVal_(0),
+ noDelay_(1),
+ maxRecvRetries_(5) {
+ recvTimeval_.tv_sec = (int)(recvTimeout_/1000);
+ recvTimeval_.tv_usec = (int)((recvTimeout_%1000)*1000);
+}
+
+TSocket::TSocket(string path) :
+ host_(""),
+ port_(0),
+ path_(path),
socket_(-1),
connTimeout_(0),
sendTimeout_(0),
@@ -65,6 +83,7 @@
TSocket::TSocket() :
host_(""),
port_(0),
+ path_(""),
socket_(-1),
connTimeout_(0),
sendTimeout_(0),
@@ -80,6 +99,7 @@
TSocket::TSocket(int socket) :
host_(""),
port_(0),
+ path_(""),
socket_(socket),
connTimeout_(0),
sendTimeout_(0),
@@ -130,7 +150,12 @@
return;
}
- socket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (! path_.empty()) {
+ socket_ = socket(PF_UNIX, SOCK_STREAM, IPPROTO_IP);
+ } else {
+ socket_ = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ }
+
if (socket_ == -1) {
int errno_copy = errno;
GlobalOutput.perror("TSocket::open() socket() " + getSocketInfo(), errno_copy);
@@ -179,7 +204,24 @@
}
// Connect the socket
- int ret = connect(socket_, res->ai_addr, res->ai_addrlen);
+ int ret;
+ if (! path_.empty()) {
+ struct sockaddr_un address;
+ socklen_t len;
+
+ if (path_.length() > sizeof(address.sun_path)) {
+ int errno_copy = errno;
+ GlobalOutput.perror("TSocket::open() Unix Domain socket path too long", errno_copy);
+ throw TTransportException(TTransportException::NOT_OPEN, " Unix Domain socket path too long");
+ }
+
+ address.sun_family = AF_UNIX;
+ sprintf(address.sun_path, path_.c_str());
+ len = sizeof(address);
+ ret = connect(socket_, (struct sockaddr *) &address, len);
+ } else {
+ ret = connect(socket_, res->ai_addr, res->ai_addrlen);
+ }
// success case
if (ret == 0) {
@@ -237,6 +279,24 @@
if (isOpen()) {
return;
}
+ if (! path_.empty()) {
+ unix_open();
+ } else {
+ local_open();
+ }
+}
+
+void TSocket::unix_open(){
+ if (! path_.empty()) {
+ // Unix Domain SOcket does not need addrinfo struct, so we pass NULL
+ openConnection(NULL);
+ }
+}
+
+void TSocket::local_open(){
+ if (isOpen()) {
+ return;
+ }
// Validate port number
if (port_ < 0 || port_ > 0xFFFF) {