JackSocket.cpp

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 "JackError.h"
00022 #include <string.h>
00023 
00024 namespace Jack
00025 {
00026 
00027 JackClientSocket::JackClientSocket(int socket): fSocket(socket)
00028 {}
00029 
00030 void JackClientSocket::SetReadTimeOut(long sec)
00031 {
00032     struct timeval timout;
00033     timout.tv_sec = sec;
00034     timout.tv_usec = 0;
00035     if (setsockopt(fSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
00036         JackLog("setsockopt SO_RCVTIMEO fd = %ld err = %s\n", fSocket, strerror(errno));
00037     }
00038 }
00039 
00040 void JackClientSocket::SetWriteTimeOut(long sec)
00041 {
00042     struct timeval timout;
00043     timout.tv_sec = sec ;
00044     timout.tv_usec = 0;
00045     if (setsockopt(fSocket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
00046         JackLog("setsockopt SO_SNDTIMEO fd = %ld err = %s\n", fSocket, strerror(errno));
00047     }
00048 }
00049 
00050 int JackClientSocket::Connect(const char* dir, const char* name, int which) // A revoir : utilisation de "which"
00051 {
00052     struct sockaddr_un addr;
00053 
00054     if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00055         jack_error("Cannot create socket err = %s", strerror(errno));
00056         return -1;
00057     }
00058 
00059     addr.sun_family = AF_UNIX;
00060     snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%s_%d", dir, name, which);
00061     JackLog("Connect: addr.sun_path %s\n", addr.sun_path);
00062 
00063     if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00064         jack_error("Cannot connect to server socket err = %s", strerror(errno));
00065         close(fSocket);
00066         return -1;
00067     }
00068 
00069 #ifdef __APPLE__
00070     int on = 1 ;
00071     if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
00072         JackLog("setsockopt SO_NOSIGPIPE fd = %ld err = %s\n", fSocket, strerror(errno));
00073     }
00074 #endif
00075 
00076     return 0;
00077 }
00078 
00079 int JackClientSocket::Connect(const char* dir, int which)
00080 {
00081     struct sockaddr_un addr;
00082 
00083     if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00084         jack_error("Cannot create socket err = %s", strerror(errno));
00085         return -1;
00086     }
00087 
00088     addr.sun_family = AF_UNIX;
00089     snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
00090     JackLog("Connect: addr.sun_path %s\n", addr.sun_path);
00091 
00092     if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00093         jack_error("Cannot connect to server socket err = %s", strerror(errno));
00094         close(fSocket);
00095         return -1;
00096     }
00097 
00098 #ifdef __APPLE__
00099     int on = 1 ;
00100     if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
00101         JackLog("setsockopt SO_NOSIGPIPE fd = %ld err = %s\n", fSocket, strerror(errno));
00102     }
00103 #endif
00104 
00105     return 0;
00106 }
00107 
00108 int JackClientSocket::Close()
00109 {
00110     JackLog("JackClientSocket::Close\n");
00111     //shutdown(fSocket, SHUT_RDWR);
00112     if (fSocket > 0) {
00113         close(fSocket);
00114         fSocket = -1;
00115         return 0;
00116     } else {
00117         return -1;
00118     }
00119 }
00120 
00121 int JackClientSocket::Read(void* data, int len)
00122 {
00123     int len1;
00124 
00125     if ((len1 = read(fSocket, data, len)) != len) {
00126         jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
00127         if (errno == EWOULDBLOCK) {
00128             JackLog("JackClientSocket::Read time out\n");
00129             return 0;
00130         } else {
00131             return -1;
00132         }
00133     } else {
00134         return 0;
00135     }
00136 }
00137 
00138 int JackClientSocket::Write(void* data, int len)
00139 {
00140     if (write(fSocket, data, len) != len) {
00141         jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
00142         return -1;
00143     } else {
00144         return 0;
00145     }
00146 }
00147 
00148 int JackServerSocket::Bind(const char* dir, const char* name, int which) // A revoir : utilisation de "which"
00149 {
00150     struct sockaddr_un addr;
00151 
00152     if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00153         jack_error("Cannot create server socket err = %s", strerror(errno));
00154         return -1;
00155     }
00156 
00157     addr.sun_family = AF_UNIX;
00158 
00159     // TO CORRECT: always reuse the same name for now...
00160     snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%s_%d", dir, name, which);
00161         strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1);
00162     /*
00163     if (access(addr.sun_path, F_OK) == 0) {
00164         goto error;
00165     }
00166     */
00167 
00168     JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
00169     unlink(fName); // Security...
00170 
00171     if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00172         jack_error("Cannot bind server to socket err = %s", strerror(errno));
00173         goto error;
00174     }
00175 
00176     if (listen(fSocket, 1) < 0) {
00177         jack_error("Cannot enable listen on server socket err = %s", strerror(errno));
00178         goto error;
00179     }
00180 
00181     return 0;
00182 
00183 error:
00184     unlink(fName);
00185     close(fSocket);
00186     return -1;
00187 }
00188 
00189 int JackServerSocket::Bind(const char* dir, int which) // A revoir : utilisation de "which"
00190 {
00191     struct sockaddr_un addr;
00192 
00193     if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00194         jack_error("Cannot create server socket err = %s", strerror(errno));
00195         return -1;
00196     }
00197 
00198     addr.sun_family = AF_UNIX;
00199 
00200     /*
00201     for (int i = 0; i < 999; i++) {
00202         snprintf(addr.sun_path, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
00203         snprintf(fName, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
00204         if (access(addr.sun_path, F_OK) != 0) {
00205                 break;
00206         }
00207     }
00208     */
00209 
00210     // TO CORRECT: always reuse the same name for now...
00211     snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
00212         strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1);
00213     /*
00214     if (access(addr.sun_path, F_OK) == 0) {
00215         goto error;
00216     }
00217     */
00218 
00219     JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
00220     unlink(fName); // Security...
00221 
00222     if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00223         jack_error("Cannot bind server to socket err = %s", strerror(errno));
00224         goto error;
00225     }
00226 
00227     if (listen(fSocket, 1) < 0) {
00228         jack_error("Cannot enable listen on server socket err = %s", strerror(errno));
00229         goto error;
00230     }
00231 
00232     return 0;
00233 
00234 error:
00235     unlink(fName);
00236     close(fSocket);
00237     return -1;
00238 }
00239 
00240 JackClientSocket* JackServerSocket::Accept()
00241 {
00242     struct sockaddr_un client_addr;
00243     socklen_t client_addrlen;
00244 
00245     memset(&client_addr, 0, sizeof(client_addr));
00246     client_addrlen = sizeof(client_addr);
00247 
00248     int fd = accept(fSocket, (struct sockaddr*) & client_addr, &client_addrlen);
00249     if (fd < 0) {
00250         jack_error("Cannot accept new connection err = %s", strerror(errno));
00251         return 0;
00252     } else {
00253         return new JackClientSocket(fd);
00254     }
00255 }
00256 
00257 int JackServerSocket::Close()
00258 {
00259     JackLog("JackServerSocket::Close %s\n", fName);
00260     //shutdown(fSocket, SHUT_RDWR);
00261     if (fSocket > 0) {
00262         //shutdown(fSocket, SHUT_RDWR);
00263         close(fSocket);
00264         unlink(fName);
00265         fSocket = -1;
00266         return 0;
00267     } else {
00268         return -1;
00269     }
00270 }
00271 
00272 } // end of namespace
00273 
00274 

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1