Jack2 1.9.8
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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) // A revoir : utilisation de "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; // For a non blocking socket, a read failure is not considered as an error 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; // For a non blocking socket, a write failure is not considered as an error 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) // A revoir : utilisation de "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); // Security... 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 } // end of namespace 00310 00311