Correct inprocess example link step.
[jack2.git] / posix / JackSocket.cpp
blobdb700f08784c70c8bfe3caf39593065d685932df
1 /*
2 Copyright (C) 2004-2008 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 #if defined(HAVE_CONFIG_H)
21 #include "config.h"
22 #endif
24 #include "JackSocket.h"
25 #include "JackError.h"
26 #include <string.h>
27 #include <stdio.h>
28 #include <pthread.h>
30 namespace Jack
33 JackClientSocket::JackClientSocket(int socket): fSocket(socket)
36 void JackClientSocket::SetReadTimeOut(long sec)
38 struct timeval timout;
39 timout.tv_sec = sec;
40 timout.tv_usec = 0;
41 if (setsockopt(fSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
42 jack_error("SetReadTimeOut fd = %ld err = %s", fSocket, strerror(errno));
46 void JackClientSocket::SetWriteTimeOut(long sec)
48 struct timeval timout;
49 timout.tv_sec = sec ;
50 timout.tv_usec = 0;
51 if (setsockopt(fSocket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
52 jack_error("SetWriteTimeOut fd = %ld err = %s", fSocket, strerror(errno));
56 void JackClientSocket::SetNonBlocking(bool onoff)
58 int flag = (onoff) ? 1 : 0;
59 if (ioctl(fSocket, FIONBIO, &flag) < 0) {
60 jack_error("SetNonBlocking fd = %ld err = %s", fSocket, strerror(errno));
64 int JackClientSocket::Connect(const char* dir, const char* name, int which) // A revoir : utilisation de "which"
66 struct sockaddr_un addr;
68 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
69 jack_error("Cannot create socket err = %s", strerror(errno));
70 return -1;
73 addr.sun_family = AF_UNIX;
74 snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%s_%d", dir, name, which);
75 jack_log("Connect: addr.sun_path %s", addr.sun_path);
77 if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
78 jack_error("Cannot connect to server socket err = %s", strerror(errno));
79 close(fSocket);
80 return -1;
83 #ifdef __APPLE__
84 int on = 1 ;
85 if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
86 jack_log("setsockopt SO_NOSIGPIPE fd = %ld err = %s", fSocket, strerror(errno));
88 #endif
90 return 0;
93 int JackClientSocket::Connect(const char* dir, int which)
95 struct sockaddr_un addr;
97 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
98 jack_error("Cannot create socket err = %s", strerror(errno));
99 return -1;
102 addr.sun_family = AF_UNIX;
103 snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
104 jack_log("Connect: addr.sun_path %s", addr.sun_path);
106 if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
107 jack_error("Cannot connect to server socket err = %s", strerror(errno));
108 close(fSocket);
109 return -1;
112 #ifdef __APPLE__
113 int on = 1 ;
114 if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
115 jack_log("setsockopt SO_NOSIGPIPE fd = %ld err = %s", fSocket, strerror(errno));
117 #endif
119 return 0;
122 int JackClientSocket::Close()
124 jack_log("JackClientSocket::Close");
125 if (fSocket > 0) {
126 shutdown(fSocket, SHUT_RDWR);
127 close(fSocket);
128 fSocket = -1;
129 return 0;
130 } else {
131 return -1;
135 int JackClientSocket::Read(void* data, int len)
137 if (read(fSocket, data, len) != len) {
138 jack_error("Cannot read socket fd = %d err = %s", fSocket, strerror(errno));
139 if (errno == EWOULDBLOCK) {
140 jack_error("JackClientSocket::Read time out");
141 return 0; // For a non blocking socket, a read failure is not considered as an error
142 } else {
143 return -1;
145 } else {
146 return 0;
150 int JackClientSocket::Write(void* data, int len)
152 if (write(fSocket, data, len) != len) {
153 jack_error("Cannot write socket fd = %ld err = %s", fSocket, strerror(errno));
154 if (errno == EWOULDBLOCK) {
155 jack_log("JackClientSocket::Write time out");
156 return 0; // For a non blocking socket, a write failure is not considered as an error
157 } else {
158 return -1;
160 } else {
161 return 0;
165 int JackServerSocket::Bind(const char* dir, const char* name, int which) // A revoir : utilisation de "which"
167 struct sockaddr_un addr;
169 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
170 jack_error("Cannot create server socket err = %s", strerror(errno));
171 return -1;
174 addr.sun_family = AF_UNIX;
176 // TO CORRECT: always reuse the same name for now...
177 snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%s_%d", dir, name, which);
178 strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1);
180 if (access(addr.sun_path, F_OK) == 0) {
181 goto error;
185 jack_log("Bind: addr.sun_path %s", addr.sun_path);
186 unlink(fName); // Security...
188 if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
189 jack_error("Cannot bind server to socket err = %s", strerror(errno));
190 goto error;
193 if (listen(fSocket, 1) < 0) {
194 jack_error("Cannot enable listen on server socket err = %s", strerror(errno));
195 goto error;
198 return 0;
200 error:
201 unlink(fName);
202 close(fSocket);
203 return -1;
206 int JackServerSocket::Bind(const char* dir, int which) // A revoir : utilisation de "which"
208 struct sockaddr_un addr;
210 if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
211 jack_error("Cannot create server socket err = %s", strerror(errno));
212 return -1;
215 addr.sun_family = AF_UNIX;
218 for (int i = 0; i < 999; i++) {
219 snprintf(addr.sun_path, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
220 snprintf(fName, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
221 if (access(addr.sun_path, F_OK) != 0) {
222 break;
227 // TO CORRECT: always reuse the same name for now...
228 snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
229 strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1);
231 if (access(addr.sun_path, F_OK) == 0) {
232 goto error;
236 jack_log("Bind: addr.sun_path %s", addr.sun_path);
237 unlink(fName); // Security...
239 if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
240 jack_error("Cannot bind server to socket err = %s", strerror(errno));
241 goto error;
244 if (listen(fSocket, 1) < 0) {
245 jack_error("Cannot enable listen on server socket err = %s", strerror(errno));
246 goto error;
249 return 0;
251 error:
252 unlink(fName);
253 close(fSocket);
254 return -1;
257 JackClientSocket* JackServerSocket::Accept()
259 struct sockaddr_un client_addr;
260 socklen_t client_addrlen;
262 memset(&client_addr, 0, sizeof(client_addr));
263 client_addrlen = sizeof(client_addr);
265 int fd = accept(fSocket, (struct sockaddr*) & client_addr, &client_addrlen);
266 if (fd < 0) {
267 jack_error("Cannot accept new connection err = %s", strerror(errno));
268 return 0;
269 } else {
270 return new JackClientSocket(fd);
274 int JackServerSocket::Close()
276 if (fSocket > 0) {
277 jack_log("JackServerSocket::Close %s", fName);
278 shutdown(fSocket, SHUT_RDWR);
279 close(fSocket);
280 unlink(fName);
281 fSocket = -1;
282 return 0;
283 } else {
284 return -1;
288 } // end of namespace