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