Dmitry Baikov patch for JackGraphManager.cpp.
[jack2.git] / common / JackSocket.cpp
blob77d6c0e3d00d9e64e4db8c9db46371db91d4677a
1 /*
2 Copyright (C) 2004-2006 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "JackSocket.h"
21 #include "JackError.h"
22 #include <string.h>
24 namespace Jack
27 JackClientSocket::JackClientSocket(int socket): fSocket(socket)
30 void JackClientSocket::SetReadTimeOut(long sec)
32 struct timeval timout;
33 timout.tv_sec = sec;
34 timout.tv_usec = 0;
35 if (setsockopt(fSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
36 JackLog("setsockopt SO_RCVTIMEO fd = %ld err = (%s)\n", fSocket, strerror(errno));
40 void JackClientSocket::SetWriteTimeOut(long sec)
42 struct timeval timout;
43 timout.tv_sec = sec ;
44 timout.tv_usec = 0;
45 if (setsockopt(fSocket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
46 JackLog("setsockopt SO_SNDTIMEO fd = %ld err = (%s)\n", fSocket, strerror(errno));
50 int JackClientSocket::Connect(const char* dir, const char* name, int which) // A revoir : utilisation de "which"
52 struct sockaddr_un addr;
54 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
55 jack_error("Cannot create socket (%s)", strerror(errno));
56 return -1;
59 addr.sun_family = AF_UNIX;
60 snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%s", dir, name);
62 JackLog("Connect: addr.sun_path %s\n", addr.sun_path);
64 if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
65 jack_error("Cannot connect to server socket (%s)", strerror(errno));
66 close(fSocket);
67 return -1;
70 #ifdef __APPLE__
71 int on = 1 ;
72 if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
73 JackLog("setsockopt SO_NOSIGPIPE fd = %ld err = %s\n", fSocket, strerror(errno));
75 #endif
77 return 0;
80 int JackClientSocket::Connect(const char* dir, int which)
82 struct sockaddr_un addr;
84 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
85 jack_error("Cannot create socket (%s)", strerror(errno));
86 return -1;
89 addr.sun_family = AF_UNIX;
90 snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
92 JackLog("Connect: addr.sun_path %s\n", addr.sun_path);
94 if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
95 jack_error("Cannot connect to server socket (%s)", strerror(errno));
96 close(fSocket);
97 return -1;
100 #ifdef __APPLE__
101 int on = 1 ;
102 if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
103 JackLog("setsockopt SO_NOSIGPIPE fd = %ld err = %s\n", fSocket, strerror(errno));
105 #endif
107 return 0;
110 int JackClientSocket::Close()
112 JackLog("JackClientSocket::Close\n");
113 //shutdown(fSocket, SHUT_RDWR);
114 if (fSocket > 0) {
115 close(fSocket);
116 fSocket = -1;
117 return 0;
118 } else {
119 return -1;
123 int JackClientSocket::Read(void* data, int len)
125 int len1;
127 if ((len1 = read(fSocket, data, len)) != len) {
128 jack_error("Cannot read socket %d %d (%s)", len, len1, strerror(errno));
129 if (errno == EWOULDBLOCK) {
130 JackLog("JackClientSocket::Read time out\n");
131 return 0;
132 } else {
133 return -1;
135 } else {
136 return 0;
140 int JackClientSocket::Write(void* data, int len)
142 if (write(fSocket, data, len) != len) {
143 jack_error("Cannot write socket fd %ld (%s)", fSocket, strerror(errno));
144 return -1;
145 } else {
146 return 0;
151 void
152 jack_cleanup_files ()
154 DIR *dir;
155 struct dirent *dirent;
157 // its important that we remove all files that jackd creates
158 // because otherwise subsequent attempts to start jackd will
159 // believe that an instance is already running.
162 if ((dir = opendir (jack_server_dir)) == NULL) {
163 fprintf (stderr, "jack(%d): cannot open jack FIFO directory "
164 "(%s)\n", getpid(), strerror (errno));
165 return;
168 while ((dirent = readdir (dir)) != NULL) {
169 if (strncmp (dirent->d_name, "jack-", 5) == 0 ||
170 strncmp (dirent->d_name, "jack_", 5) == 0) {
171 char fullpath[PATH_MAX+1];
172 snprintf (fullpath, sizeof (fullpath), "%s/%s",
173 jack_server_dir, dirent->d_name);
174 unlink (fullpath);
178 closedir (dir);
182 int JackServerSocket::Bind(const char* dir, const char* name, int which) // A revoir : utilisation de "which"
184 struct sockaddr_un addr;
186 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
187 jack_error("Cannot create server socket (%s)", strerror(errno));
188 return -1;
191 addr.sun_family = AF_UNIX;
193 // TO CORRECT: always reuse the same name for now...
194 snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%s", dir, name);
195 snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%s", dir, name);
197 if (access(addr.sun_path, F_OK) == 0) {
198 goto error;
202 JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
203 unlink(fName); // Security...
205 JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
206 unlink(fName); // Security...
208 if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
209 jack_error("Cannot bind server to socket (%s)", strerror(errno));
210 goto error;
213 if (listen(fSocket, 1) < 0) {
214 jack_error("Cannot enable listen on server socket (%s)", strerror(errno));
215 goto error;
218 return 0;
220 error:
221 unlink(fName);
222 close(fSocket);
223 return -1;
226 int JackServerSocket::Bind(const char* dir, int which) // A revoir : utilisation de "which"
228 struct sockaddr_un addr;
230 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
231 jack_error ("Cannot create server socket (%s)", strerror(errno));
232 return -1;
235 addr.sun_family = AF_UNIX;
238 for (int i = 0; i < 999; i++) {
239 snprintf(addr.sun_path, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
240 snprintf(fName, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
241 if (access(addr.sun_path, F_OK) != 0) {
242 break;
247 // TO CORRECT: always reuse the same name for now...
248 snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
249 snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
251 if (access(addr.sun_path, F_OK) == 0) {
252 goto error;
256 JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
257 unlink(fName); // Security...
259 if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
260 jack_error("Cannot bind server to socket (%s)", strerror(errno));
261 goto error;
264 if (listen(fSocket, 1) < 0) {
265 jack_error("Cannot enable listen on server socket (%s)", strerror(errno));
266 goto error;
269 return 0;
271 error:
272 unlink(fName);
273 close(fSocket);
274 return -1;
277 JackClientSocket* JackServerSocket::Accept()
279 struct sockaddr_un client_addr;
280 socklen_t client_addrlen;
282 memset(&client_addr, 0, sizeof(client_addr));
283 client_addrlen = sizeof(client_addr);
285 int fd = accept(fSocket, (struct sockaddr*) & client_addr, &client_addrlen);
286 if (fd < 0) {
287 jack_error("Cannot accept new connection (%s)", strerror(errno));
288 return 0;
289 } else {
290 return new JackClientSocket(fd);
294 int JackServerSocket::Close()
296 JackLog("JackServerSocket::Close %s\n", fName);
297 //shutdown(fSocket, SHUT_RDWR);
298 if (fSocket > 0) {
299 //shutdown(fSocket, SHUT_RDWR);
300 close(fSocket);
301 unlink(fName);
302 fSocket = -1;
303 return 0;
304 } else {
305 return -1;
309 } // end of namespace