00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackSocket.h"
00021 #include "JackConstants.h"
00022 #include "JackTools.h"
00023 #include "JackError.h"
00024 #include <string.h>
00025 #include <stdio.h>
00026 #include <pthread.h>
00027 #include <fcntl.h>
00028
00029 namespace Jack
00030 {
00031
00032 static void BuildName(const char* client_name, char* res, const char* dir, int which, int size)
00033 {
00034 char ext_client_name[SYNC_MAX_NAME_SIZE + 1];
00035 JackTools::RewriteName(client_name, ext_client_name);
00036 if (getenv("JACK_PROMISCUOUS_SERVER")) {
00037 snprintf(res, size, "%s/jack_%s_%d", dir, ext_client_name, which);
00038 } else {
00039 snprintf(res, size, "%s/jack_%s_%d_%d", dir, ext_client_name, JackTools::GetUID(), which);
00040 }
00041 }
00042
00043 JackClientSocket::JackClientSocket(int socket): JackClientRequestInterface(), fSocket(socket),fTimeOut(0)
00044 {}
00045
00046 #if defined(__sun__) || defined(sun)
00047
00048 void JackClientSocket::SetReadTimeOut(long sec)
00049 {
00050 int flags;
00051 fTimeOut = sec;
00052
00053 if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) {
00054 jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_GETFL");
00055 return;
00056 }
00057
00058 flags |= O_NONBLOCK;
00059 if (fcntl(fSocket, F_SETFL, flags) < 0) {
00060 jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_SETFL");
00061 return;
00062 }
00063 }
00064
00065 void JackClientSocket::SetWriteTimeOut(long sec)
00066 {
00067 int flags;
00068 fTimeOut = sec;
00069
00070 if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) {
00071 jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_GETFL");
00072 return;
00073 }
00074
00075 flags |= O_NONBLOCK;
00076 if (fcntl(fSocket, F_SETFL, flags) < 0) {
00077 jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_SETFL");
00078 return;
00079 }
00080 }
00081
00082 #else
00083
00084 void JackClientSocket::SetReadTimeOut(long sec)
00085 {
00086 struct timeval timout;
00087 timout.tv_sec = sec;
00088 timout.tv_usec = 0;
00089 if (setsockopt(fSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
00090 jack_error("SetReadTimeOut fd = %ld err = %s", fSocket, strerror(errno));
00091 }
00092 }
00093
00094 void JackClientSocket::SetWriteTimeOut(long sec)
00095 {
00096 struct timeval timout;
00097 timout.tv_sec = sec ;
00098 timout.tv_usec = 0;
00099 if (setsockopt(fSocket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
00100 jack_error("SetWriteTimeOut fd = %ld err = %s", fSocket, strerror(errno));
00101 }
00102 }
00103
00104 #endif
00105
00106 void JackClientSocket::SetNonBlocking(bool onoff)
00107 {
00108 if (onoff) {
00109 long flags = 0;
00110 if (fcntl(fSocket, F_SETFL, flags | O_NONBLOCK) < 0) {
00111 jack_error("SetNonBlocking fd = %ld err = %s", fSocket, strerror(errno));
00112 }
00113 }
00114 }
00115
00116 int JackClientSocket::Connect(const char* dir, const char* name, int which)
00117 {
00118 struct sockaddr_un addr;
00119
00120 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00121 jack_error("Cannot create socket err = %s", strerror(errno));
00122 return -1;
00123 }
00124
00125 addr.sun_family = AF_UNIX;
00126 BuildName(name, addr.sun_path, dir, which, sizeof(addr.sun_path));
00127 jack_log("JackClientSocket::Connect : addr.sun_path %s", addr.sun_path);
00128
00129 if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00130 jack_error("Cannot connect to server socket err = %s", strerror(errno));
00131 close(fSocket);
00132 return -1;
00133 }
00134
00135 #ifdef __APPLE__
00136 int on = 1;
00137 if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
00138 jack_log("setsockopt SO_NOSIGPIPE fd = %ld err = %s", fSocket, strerror(errno));
00139 }
00140 #endif
00141
00142 return 0;
00143 }
00144
00145 int JackClientSocket::Close()
00146 {
00147 jack_log("JackClientSocket::Close");
00148 if (fSocket > 0) {
00149 shutdown(fSocket, SHUT_RDWR);
00150 close(fSocket);
00151 fSocket = -1;
00152 return 0;
00153 } else {
00154 return -1;
00155 }
00156 }
00157
00158 int JackClientSocket::Read(void* data, int len)
00159 {
00160 int res;
00161
00162 #if defined(__sun__) || defined(sun)
00163 if (fTimeOut > 0) {
00164
00165 struct timeval tv;
00166 fd_set fdset;
00167 ssize_t res;
00168
00169 tv.tv_sec = fTimeOut;
00170 tv.tv_usec = 0;
00171
00172 FD_ZERO(&fdset);
00173 FD_SET(fSocket, &fdset);
00174
00175 do {
00176 res = select(fSocket + 1, &fdset, NULL, NULL, &tv);
00177 } while (res < 0 && errno == EINTR);
00178
00179 if (res < 0) {
00180 return res;
00181 } else if (res == 0) {
00182 return -1;
00183 }
00184 }
00185 #endif
00186
00187 if ((res = read(fSocket, data, len)) != len) {
00188 if (errno == EWOULDBLOCK || errno == EAGAIN) {
00189 jack_error("JackClientSocket::Read time out");
00190 return 0;
00191 } else if (res != 0) {
00192 jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
00193
00194 return -1;
00195 } else {
00196 jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
00197 return -1;
00198 }
00199 } else {
00200 return 0;
00201 }
00202 }
00203
00204 int JackClientSocket::Write(void* data, int len)
00205 {
00206 int res;
00207
00208 #if defined(__sun__) || defined(sun)
00209 if (fTimeOut > 0) {
00210
00211 struct timeval tv;
00212 fd_set fdset;
00213 ssize_t res;
00214
00215 tv.tv_sec = fTimeOut;
00216 tv.tv_usec = 0;
00217
00218 FD_ZERO(&fdset);
00219 FD_SET(fSocket, &fdset);
00220
00221 do {
00222 res = select(fSocket + 1, NULL, &fdset, NULL, &tv);
00223 } while (res < 0 && errno == EINTR);
00224
00225 if (res < 0) {
00226 return res;
00227 } else if (res == 0) {
00228 return -1;
00229 }
00230 }
00231 #endif
00232
00233 if ((res = write(fSocket, data, len)) != len) {
00234 if (errno == EWOULDBLOCK || errno == EAGAIN) {
00235 jack_log("JackClientSocket::Write time out");
00236 return 0;
00237 } else if (res != 0) {
00238 jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
00239
00240 return -1;
00241 } else {
00242 jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
00243 return -1;
00244 }
00245 } else {
00246 return 0;
00247 }
00248 }
00249
00250 int JackServerSocket::Bind(const char* dir, const char* name, int which)
00251 {
00252 struct sockaddr_un addr;
00253
00254 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00255 jack_error("Cannot create server socket err = %s", strerror(errno));
00256 return -1;
00257 }
00258
00259 addr.sun_family = AF_UNIX;
00260
00261 BuildName(name, fName, dir, which, sizeof(addr.sun_path));
00262 strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1);
00263
00264 jack_log("JackServerSocket::Bind : addr.sun_path %s", addr.sun_path);
00265 unlink(fName);
00266
00267 if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00268 jack_error("Cannot bind server to socket err = %s", strerror(errno));
00269 goto error;
00270 }
00271
00272 if (listen(fSocket, 100) < 0) {
00273 jack_error("Cannot enable listen on server socket err = %s", strerror(errno));
00274 goto error;
00275 }
00276
00277 return 0;
00278
00279 error:
00280 unlink(fName);
00281 close(fSocket);
00282 return -1;
00283 }
00284
00285 JackClientSocket* JackServerSocket::Accept()
00286 {
00287 struct sockaddr_un client_addr;
00288 socklen_t client_addrlen;
00289
00290 memset(&client_addr, 0, sizeof(client_addr));
00291 client_addrlen = sizeof(client_addr);
00292
00293 int fd = accept(fSocket, (struct sockaddr*)&client_addr, &client_addrlen);
00294 if (fd < 0) {
00295 jack_error("Cannot accept new connection err = %s", strerror(errno));
00296 return 0;
00297 } else {
00298 return new JackClientSocket(fd);
00299 }
00300 }
00301
00302 int JackServerSocket::Close()
00303 {
00304 if (fSocket > 0) {
00305 jack_log("JackServerSocket::Close %s", fName);
00306 shutdown(fSocket, SHUT_RDWR);
00307 close(fSocket);
00308 unlink(fName);
00309 fSocket = -1;
00310 return 0;
00311 } else {
00312 return -1;
00313 }
00314 }
00315
00316 }
00317
00318