jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

313 lines
8.2KB

  1. /*
  2. Copyright (C) 2004-2006 Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU Lesser General Public License as published by
  5. the Free Software Foundation; either version 2.1 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include "JackSocket.h"
  16. #include "JackError.h"
  17. #include <string.h>
  18. namespace Jack
  19. {
  20. JackClientSocket::JackClientSocket(int socket): fSocket(socket)
  21. {}
  22. void JackClientSocket::SetReadTimeOut(long sec)
  23. {
  24. struct timeval timout;
  25. timout.tv_sec = sec;
  26. timout.tv_usec = 0;
  27. if (setsockopt(fSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
  28. JackLog("setsockopt SO_RCVTIMEO fd = %ld err = (%s)\n", fSocket, strerror(errno));
  29. }
  30. }
  31. void JackClientSocket::SetWriteTimeOut(long sec)
  32. {
  33. struct timeval timout;
  34. timout.tv_sec = sec ;
  35. timout.tv_usec = 0;
  36. if (setsockopt(fSocket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timout, sizeof(timeval)) < 0) {
  37. JackLog("setsockopt SO_SNDTIMEO fd = %ld err = (%s)\n", fSocket, strerror(errno));
  38. }
  39. }
  40. int JackClientSocket::Connect(const char* dir, const char* name, int which) // A revoir : utilisation de "which"
  41. {
  42. struct sockaddr_un addr;
  43. if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
  44. jack_error("Cannot create socket (%s)", strerror(errno));
  45. return -1;
  46. }
  47. addr.sun_family = AF_UNIX;
  48. snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%s", dir, name);
  49. JackLog("Connect: addr.sun_path %s\n", addr.sun_path);
  50. if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
  51. jack_error("Cannot connect to server socket (%s)", strerror(errno));
  52. close(fSocket);
  53. return -1;
  54. }
  55. #ifdef __APPLE__
  56. int on = 1 ;
  57. if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
  58. JackLog("setsockopt SO_NOSIGPIPE fd = %ld err = %s\n", fSocket, strerror(errno));
  59. }
  60. #endif
  61. return 0;
  62. }
  63. int JackClientSocket::Connect(const char* dir, int which)
  64. {
  65. struct sockaddr_un addr;
  66. if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
  67. jack_error("Cannot create socket (%s)", strerror(errno));
  68. return -1;
  69. }
  70. addr.sun_family = AF_UNIX;
  71. snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
  72. JackLog("Connect: addr.sun_path %s\n", addr.sun_path);
  73. if (connect(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
  74. jack_error("Cannot connect to server socket (%s)", strerror(errno));
  75. close(fSocket);
  76. return -1;
  77. }
  78. #ifdef __APPLE__
  79. int on = 1 ;
  80. if (setsockopt(fSocket, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
  81. JackLog("setsockopt SO_NOSIGPIPE fd = %ld err = %s\n", fSocket, strerror(errno));
  82. }
  83. #endif
  84. return 0;
  85. }
  86. int JackClientSocket::Close()
  87. {
  88. JackLog("JackClientSocket::Close\n");
  89. //shutdown(fSocket, SHUT_RDWR);
  90. if (fSocket > 0) {
  91. close(fSocket);
  92. fSocket = -1;
  93. return 0;
  94. } else {
  95. return -1;
  96. }
  97. }
  98. int JackClientSocket::Read(void* data, int len)
  99. {
  100. int len1;
  101. JackLog("JackClientSocket::Read len = %ld\n", len);
  102. if ((len1 = read(fSocket, data, len)) != len) {
  103. jack_error("Cannot read socket %d %d (%s)", len, len1, strerror(errno));
  104. if (errno == EWOULDBLOCK) {
  105. JackLog("JackClientSocket::Read time out\n");
  106. return 0;
  107. } else {
  108. return -1;
  109. }
  110. } else {
  111. return 0;
  112. }
  113. }
  114. int JackClientSocket::Write(void* data, int len)
  115. {
  116. if (write(fSocket, data, len) != len) {
  117. jack_error("Cannot write socket fd %ld (%s)", fSocket, strerror(errno));
  118. return -1;
  119. } else {
  120. return 0;
  121. }
  122. }
  123. /*
  124. void
  125. jack_cleanup_files ()
  126. {
  127. DIR *dir;
  128. struct dirent *dirent;
  129. // its important that we remove all files that jackd creates
  130. // because otherwise subsequent attempts to start jackd will
  131. // believe that an instance is already running.
  132. if ((dir = opendir (jack_server_dir)) == NULL) {
  133. fprintf (stderr, "jack(%d): cannot open jack FIFO directory "
  134. "(%s)\n", getpid(), strerror (errno));
  135. return;
  136. }
  137. while ((dirent = readdir (dir)) != NULL) {
  138. if (strncmp (dirent->d_name, "jack-", 5) == 0 ||
  139. strncmp (dirent->d_name, "jack_", 5) == 0) {
  140. char fullpath[PATH_MAX+1];
  141. snprintf (fullpath, sizeof (fullpath), "%s/%s",
  142. jack_server_dir, dirent->d_name);
  143. unlink (fullpath);
  144. }
  145. }
  146. closedir (dir);
  147. }
  148. */
  149. int JackServerSocket::Bind(const char* dir, const char* name, int which) // A revoir : utilisation de "which"
  150. {
  151. struct sockaddr_un addr;
  152. if ((fSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
  153. jack_error("Cannot create server socket (%s)", strerror(errno));
  154. return -1;
  155. }
  156. addr.sun_family = AF_UNIX;
  157. // TO CORRECT: always reuse the same name for now...
  158. snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%s", dir, name);
  159. snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%s", dir, name);
  160. /*
  161. if (access(addr.sun_path, F_OK) == 0) {
  162. goto error;
  163. }
  164. */
  165. JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
  166. unlink(fName); // Security...
  167. JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
  168. unlink(fName); // Security...
  169. if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
  170. jack_error("Cannot bind server to socket (%s)", strerror(errno));
  171. goto error;
  172. }
  173. if (listen(fSocket, 1) < 0) {
  174. jack_error("Cannot enable listen on server socket (%s)", strerror(errno));
  175. goto error;
  176. }
  177. return 0;
  178. error:
  179. unlink(fName);
  180. close(fSocket);
  181. return -1;
  182. }
  183. int JackServerSocket::Bind(const char* dir, int which) // A revoir : utilisation de "which"
  184. {
  185. 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;
  189. }
  190. addr.sun_family = AF_UNIX;
  191. /*
  192. for (int i = 0; i < 999; i++) {
  193. snprintf(addr.sun_path, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
  194. snprintf(fName, sizeof(addr.sun_path) - 1,"%s/jack_%d", dir, i);
  195. if (access(addr.sun_path, F_OK) != 0) {
  196. break;
  197. }
  198. }
  199. */
  200. // TO CORRECT: always reuse the same name for now...
  201. snprintf(addr.sun_path, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
  202. snprintf(fName, sizeof(addr.sun_path) - 1, "%s/jack_%d", dir, which);
  203. /*
  204. if (access(addr.sun_path, F_OK) == 0) {
  205. goto error;
  206. }
  207. */
  208. JackLog("Bind: addr.sun_path %s\n", addr.sun_path);
  209. unlink(fName); // Security...
  210. if (bind(fSocket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
  211. jack_error("Cannot bind server to socket (%s)", strerror(errno));
  212. goto error;
  213. }
  214. if (listen(fSocket, 1) < 0) {
  215. jack_error("Cannot enable listen on server socket (%s)", strerror(errno));
  216. goto error;
  217. }
  218. return 0;
  219. error:
  220. unlink(fName);
  221. close(fSocket);
  222. return -1;
  223. }
  224. JackClientSocket* JackServerSocket::Accept()
  225. {
  226. struct sockaddr_un client_addr;
  227. socklen_t client_addrlen;
  228. memset(&client_addr, 0, sizeof(client_addr));
  229. client_addrlen = sizeof(client_addr);
  230. int fd = accept(fSocket, (struct sockaddr*) & client_addr, &client_addrlen);
  231. if (fd < 0) {
  232. jack_error("Cannot accept new connection (%s)", strerror(errno));
  233. return 0;
  234. } else {
  235. return new JackClientSocket(fd);
  236. }
  237. }
  238. int JackServerSocket::Close()
  239. {
  240. JackLog("JackServerSocket::Close %s\n", fName);
  241. //shutdown(fSocket, SHUT_RDWR);
  242. if (fSocket > 0) {
  243. //shutdown(fSocket, SHUT_RDWR);
  244. close(fSocket);
  245. unlink(fName);
  246. fSocket = -1;
  247. return 0;
  248. } else {
  249. return -1;
  250. }
  251. }
  252. } // end of namespace