Jack2 1.9.6
|
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) { 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 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) { 00229 jack_log("JackClientSocket::Write time out"); 00230 return 0; // For a non blocking socket, a write failure is not considered as an error 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) // A revoir : utilisation de "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); // Security... 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, 1) < 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 } // end of namespace 00308 00309