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 return -1;
00192 }
00193 } else {
00194 return 0;
00195 }
00196 }
00197
00198 int JackClientSocket::Write(void* data, int len)
00199 {
00200 int res;
00201
00202 #if defined(__sun__) || defined(sun)
00203 if (fTimeOut > 0) {
00204
00205 struct timeval tv;
00206 fd_set fdset;
00207 ssize_t res;
00208
00209 tv.tv_sec = fTimeOut;
00210 tv.tv_usec = 0;
00211
00212 FD_ZERO(&fdset);
00213 FD_SET(fSocket, &fdset);
00214
00215 do {
00216 res = select(fSocket + 1, NULL, &fdset, NULL, &tv);
00217 } while (res < 0 && errno == EINTR);
00218
00219 if (res < 0) {
00220 return res;
00221 } else if (res == 0) {
00222 return -1;
00223 }
00224 }
00225 #endif
00226
00227 if ((res = write(fSocket, data, len)) != len) {
00228 if (errno == EWOULDBLOCK || errno == EAGAIN) {
00229 jack_log("JackClientSocket::Write time out");
00230 return 0;
00231 } else if (res != 0) {
00232 jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
00233 return 0;
00234 } else {
00235 return -1;
00236 }
00237 } else {
00238 return 0;
00239 }
00240 }
00241
00242 int JackServerSocket::Bind(const char* dir, const char* name, int which)
00243 {
00244 struct sockaddr_un addr;
00245
00246 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00247 jack_error("Cannot create server socket err = %s", strerror(errno));
00248 return -1;
00249 }
00250
00251 addr.sun_family = AF_UNIX;
00252 BuildName(name, fName, dir, which);
00253 strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1);
00254
00255 jack_log("Bind: addr.sun_path %s", addr.sun_path);
00256 unlink(fName);
00257
00258 if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00259 jack_error("Cannot bind server to socket err = %s", strerror(errno));
00260 goto error;
00261 }
00262
00263 if (listen(fSocket, 100) < 0) {
00264 jack_error("Cannot enable listen on server socket err = %s", strerror(errno));
00265 goto error;
00266 }
00267
00268 return 0;
00269
00270 error:
00271 unlink(fName);
00272 close(fSocket);
00273 return -1;
00274 }
00275
00276 JackClientSocket* JackServerSocket::Accept()
00277 {
00278 struct sockaddr_un client_addr;
00279 socklen_t client_addrlen;
00280
00281 memset(&client_addr, 0, sizeof(client_addr));
00282 client_addrlen = sizeof(client_addr);
00283
00284 int fd = accept(fSocket, (struct sockaddr*)&client_addr, &client_addrlen);
00285 if (fd < 0) {
00286 jack_error("Cannot accept new connection err = %s", strerror(errno));
00287 return 0;
00288 } else {
00289 return new JackClientSocket(fd);
00290 }
00291 }
00292
00293 int JackServerSocket::Close()
00294 {
00295 if (fSocket > 0) {
00296 jack_log("JackServerSocket::Close %s", fName);
00297 shutdown(fSocket, SHUT_RDWR);
00298 close(fSocket);
00299 unlink(fName);
00300 fSocket = -1;
00301 return 0;
00302 } else {
00303 return -1;
00304 }
00305 }
00306
00307 }
00308
00309