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)
24 #include "JackSocket.h"
25 #include "JackError.h"
33 JackClientSocket::JackClientSocket(int socket
): fSocket(socket
)
36 void JackClientSocket::SetReadTimeOut(long sec
)
38 struct timeval timout
;
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
;
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
));
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
));
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
));
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
));
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
));
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
));
122 int JackClientSocket::Close()
124 jack_log("JackClientSocket::Close");
126 shutdown(fSocket
, SHUT_RDWR
);
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
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
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
));
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) {
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
));
193 if (listen(fSocket
, 1) < 0) {
194 jack_error("Cannot enable listen on server socket err = %s", strerror(errno
));
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
));
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) {
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) {
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
));
244 if (listen(fSocket
, 1) < 0) {
245 jack_error("Cannot enable listen on server socket err = %s", strerror(errno
));
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
);
267 jack_error("Cannot accept new connection err = %s", strerror(errno
));
270 return new JackClientSocket(fd
);
274 int JackServerSocket::Close()
277 jack_log("JackServerSocket::Close %s", fName
);
278 shutdown(fSocket
, SHUT_RDWR
);
288 } // end of namespace