JackSocket.cpp

00001 /*
00002 Copyright (C) 2004-2006 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 (%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", dir, name);
00061 
00062     JackLog("Connect: addr.sun_path %s\n", addr.sun_path);
00063 
00064     if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00065         jack_error("Cannot connect to server socket (%s)", strerror(errno));
00066         close(fSocket);
00067         return -1;
00068     }
00069 
00070 #ifdef __APPLE__
00071     int on = 1 ;
00072     if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
00073         JackLog("setsockopt SO_NOSIGPIPE fd = %ld err = %s\n", fSocket, strerror(errno));
00074     }
00075 #endif
00076 
00077     return 0;
00078 }
00079 
00080 int JackClientSocket::Connect(const char* dir, int which)
00081 {
00082     struct sockaddr_un addr;
00083 
00084     if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00085         jack_error("Cannot create socket (%s)", strerror(errno));
00086         return -1;
00087     }
00088 
00089     addr.sun_family = AF_UNIX;
00090     snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
00091 
00092     JackLog("Connect: addr.sun_path %s\n", addr.sun_path);
00093 
00094     if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00095         jack_error("Cannot connect to server socket (%s)", strerror(errno));
00096         close(fSocket);
00097         return -1;
00098     }
00099 
00100 #ifdef __APPLE__
00101     int on = 1 ;
00102     if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
00103         JackLog("setsockopt SO_NOSIGPIPE fd = %ld err = %s\n", fSocket, strerror(errno));
00104     }
00105 #endif
00106 
00107     return 0;
00108 }
00109 
00110 int JackClientSocket::Close()
00111 {
00112     JackLog("JackClientSocket::Close\n");
00113     //shutdown(fSocket, SHUT_RDWR);
00114     if (fSocket > 0) {
00115         close(fSocket);
00116         fSocket = -1;
00117         return 0;
00118     } else {
00119         return -1;
00120     }
00121 }
00122 
00123 int JackClientSocket::Read(void* data, int len)
00124 {
00125     int len1;
00126     JackLog("JackClientSocket::Read len = %ld\n", len);
00127 
00128     if ((len1 = read(fSocket, data, len)) != len) {
00129         jack_error("Cannot read socket %d %d (%s)", len, len1, strerror(errno));
00130         if (errno == EWOULDBLOCK) {
00131             JackLog("JackClientSocket::Read time out\n");
00132             return 0;
00133         } else {
00134             return -1;
00135         }
00136     } else {
00137         return 0;
00138     }
00139 }
00140 
00141 int JackClientSocket::Write(void* data, int len)
00142 {
00143     if (write(fSocket, data, len) != len) {
00144         jack_error("Cannot write socket fd %ld (%s)", fSocket, strerror(errno));
00145         return -1;
00146     } else {
00147         return 0;
00148     }
00149 }
00150 
00151 /*
00152 void
00153 jack_cleanup_files ()
00154 {
00155         DIR *dir;
00156         struct dirent *dirent;
00157  
00158         // its important that we remove all files that jackd creates
00159         //   because otherwise subsequent attempts to start jackd will
00160         //   believe that an instance is already running.
00161         
00162  
00163         if ((dir = opendir (jack_server_dir)) == NULL) {
00164                 fprintf (stderr, "jack(%d): cannot open jack FIFO directory "
00165                          "(%s)\n", getpid(), strerror (errno));
00166                 return;
00167         }
00168  
00169         while ((dirent = readdir (dir)) != NULL) {
00170                 if (strncmp (dirent->d_name, "jack-", 5) == 0 ||
00171                     strncmp (dirent->d_name, "jack_", 5) == 0) {
00172                         char fullpath[PATH_MAX+1];
00173                         snprintf (fullpath, sizeof (fullpath), "%s/%s",
00174                                   jack_server_dir, dirent->d_name);
00175                         unlink (fullpath);
00176                 } 
00177         }
00178  
00179         closedir (dir);
00180 }
00181 */
00182 
00183 int JackServerSocket::Bind(const char* dir, const char* name, int which) // A revoir : utilisation de "which"
00184 {
00185     struct sockaddr_un addr;
00186 
00187     if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00188         jack_error("Cannot create server socket (%s)", strerror(errno));
00189         return -1;
00190     }
00191 
00192     addr.sun_family = AF_UNIX;
00193 
00194     // TO CORRECT: always reuse the same name for now...
00195     snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%s", dir, name);
00196     snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%s", dir, name);
00197     /*
00198     if (access(addr.sun_path, F_OK) == 0) {
00199         goto error;
00200     }
00201     */
00202 
00203     JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
00204     unlink(fName); // Security...
00205 
00206     JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
00207     unlink(fName); // Security...
00208 
00209     if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00210         jack_error("Cannot bind server to socket (%s)", strerror(errno));
00211         goto error;
00212     }
00213 
00214     if (listen(fSocket, 1) < 0) {
00215         jack_error("Cannot enable listen on server socket (%s)", strerror(errno));
00216         goto error;
00217     }
00218 
00219     return 0;
00220 
00221 error:
00222     unlink(fName);
00223     close(fSocket);
00224     return -1;
00225 }
00226 
00227 int JackServerSocket::Bind(const char* dir, int which) // A revoir : utilisation de "which"
00228 {
00229     struct sockaddr_un addr;
00230 
00231     if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
00232         jack_error ("Cannot create server socket (%s)", strerror(errno));
00233         return -1;
00234     }
00235 
00236     addr.sun_family = AF_UNIX;
00237 
00238     /*
00239     for (int i = 0; i < 999; i++) {
00240         snprintf(addr.sun_path, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
00241         snprintf(fName, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
00242         if (access(addr.sun_path, F_OK) != 0) {
00243                 break;
00244         }
00245     }
00246     */
00247 
00248     // TO CORRECT: always reuse the same name for now...
00249     snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
00250     snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
00251     /*
00252     if (access(addr.sun_path, F_OK) == 0) {
00253         goto error;
00254     }
00255     */
00256 
00257     JackLog("Bind: addr.sun_path %s\n", 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 (%s)", strerror(errno));
00262         goto error;
00263     }
00264 
00265     if (listen(fSocket, 1) < 0) {
00266         jack_error("Cannot enable listen on server socket (%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 (%s)", strerror(errno));
00289         return 0;
00290     } else {
00291         return new JackClientSocket(fd);
00292     }
00293 }
00294 
00295 int JackServerSocket::Close()
00296 {
00297     JackLog("JackServerSocket::Close %s\n", fName);
00298     //shutdown(fSocket, SHUT_RDWR);
00299     if (fSocket > 0) {
00300         //shutdown(fSocket, SHUT_RDWR);
00301         close(fSocket);
00302         unlink(fName);
00303         fSocket = -1;
00304         return 0;
00305     } else {
00306         return -1;
00307     }
00308 }
00309 
00310 } // end of namespace
00311 
00312 

Generated on Wed Jan 10 11:42:46 2007 for Jackdmp by  doxygen 1.4.5