XMMS2
socket_unix.c
Go to the documentation of this file.
1 /* XMMS2 - X Music Multiplexer System
2  * Copyright (C) 2003-2011 XMMS2 Team
3  *
4  * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  */
16 
17 
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <unistd.h>
22 #include <sys/un.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <signal.h>
29 #include <syslog.h>
30 
32 #include "xmmsc/xmmsc_util.h"
33 #include "url.h"
34 #include "socket_unix.h"
35 
36 static void
37 xmms_ipc_usocket_destroy (xmms_ipc_transport_t *ipct)
38 {
39  free (ipct->path);
40  close (ipct->fd);
41 }
42 
43 static int
44 xmms_ipc_usocket_read (xmms_ipc_transport_t *ipct, char *buffer, int len)
45 {
46  int fd;
47  int ret;
48  x_return_val_if_fail (ipct, -1);
49  x_return_val_if_fail (buffer, -1);
50 
51  fd = ipct->fd;
52 
53  ret = recv (fd, buffer, len, 0);
54 
55  return ret;
56 }
57 
58 static int
59 xmms_ipc_usocket_write (xmms_ipc_transport_t *ipct, char *buffer, int len)
60 {
61  int fd;
62  x_return_val_if_fail (ipct, -1);
63  x_return_val_if_fail (buffer, -1);
64 
65  fd = ipct->fd;
66 
67  return send (fd, buffer, len, 0);
68 
69 }
70 
73 {
74  int fd;
75  int flags;
77  struct sockaddr_un saddr;
78 
79 
80  fd = socket (AF_UNIX, SOCK_STREAM, 0);
81  if (fd == -1) {
82  return NULL;
83  }
84 
85  saddr.sun_family = AF_UNIX;
86  snprintf (saddr.sun_path, sizeof(saddr.sun_path), "/%s", url->path);
87 
88  if (connect (fd, (struct sockaddr *) &saddr, sizeof (saddr)) == -1) {
89  close (fd);
90  return NULL;
91  }
92 
93  flags = fcntl (fd, F_GETFL, 0);
94 
95  if (flags == -1) {
96  close (fd);
97  return NULL;
98  }
99 
100  flags |= O_NONBLOCK;
101 
102  flags = fcntl (fd, F_SETFL, flags);
103  if (flags == -1) {
104  close (fd);
105  return NULL;
106  }
107 
108  ipct = x_new0 (xmms_ipc_transport_t, 1);
109  ipct->fd = fd;
110  ipct->path = strdup (url->path);
111  ipct->read_func = xmms_ipc_usocket_read;
112  ipct->write_func = xmms_ipc_usocket_write;
113  ipct->destroy_func = xmms_ipc_usocket_destroy;
114 
115  return ipct;
116 }
117 
118 static xmms_ipc_transport_t *
119 xmms_ipc_usocket_accept (xmms_ipc_transport_t *transport)
120 {
121  int fd;
122  struct sockaddr_un sin;
123  socklen_t sin_len;
124 
125  x_return_val_if_fail (transport, NULL);
126 
127  sin_len = sizeof (sin);
128 
129  fd = accept (transport->fd, (struct sockaddr *)&sin, &sin_len);
130  if (fd >= 0) {
131  int flags;
133 
134  flags = fcntl (fd, F_GETFL, 0);
135 
136  if (flags == -1) {
137  close (fd);
138  return NULL;
139  }
140 
141  flags |= O_NONBLOCK;
142 
143  flags = fcntl (fd, F_SETFL, flags);
144  if (flags == -1) {
145  close (fd);
146  return NULL;
147  }
148 
149 
150  ret = x_new0 (xmms_ipc_transport_t, 1);
151  ret->fd = fd;
152  ret->read_func = xmms_ipc_usocket_read;
153  ret->write_func = xmms_ipc_usocket_write;
154  ret->destroy_func = xmms_ipc_usocket_destroy;
155 
156  return ret;
157  }
158 
159  return NULL;
160 }
161 
164 {
165  int fd;
166  int flags;
167  xmms_ipc_transport_t *ipct;
168  struct sockaddr_un saddr;
169 
170 
171  fd = socket (AF_UNIX, SOCK_STREAM, 0);
172  if (fd == -1) {
173  return NULL;
174  }
175 
176  saddr.sun_family = AF_UNIX;
177  snprintf (saddr.sun_path, sizeof (saddr.sun_path), "/%s", url->path);
178 
179  if (access (saddr.sun_path, F_OK) == 0) {
180  if (connect (fd, (struct sockaddr *) &saddr, sizeof (saddr)) != -1) {
181  /* active socket already exists! */
182  close (fd);
183  return NULL;
184  }
185  /* remove stale socket */
186  unlink (saddr.sun_path);
187  }
188 
189  if (bind (fd, (struct sockaddr *) &saddr, sizeof (saddr)) == -1) {
190  close (fd);
191  return NULL;
192  }
193 
194  listen (fd, 5);
195 
196  flags = fcntl (fd, F_GETFL, 0);
197 
198  if (flags == -1) {
199  close (fd);
200  return NULL;
201  }
202 
203  flags |= O_NONBLOCK;
204 
205  flags = fcntl (fd, F_SETFL, flags);
206  if (flags == -1) {
207  close (fd);
208  return NULL;
209  }
210 
211  ipct = x_new0 (xmms_ipc_transport_t, 1);
212  ipct->fd = fd;
213  ipct->path = strdup (url->path);
214  ipct->read_func = xmms_ipc_usocket_read;
215  ipct->write_func = xmms_ipc_usocket_write;
216  ipct->accept_func = xmms_ipc_usocket_accept;
217  ipct->destroy_func = xmms_ipc_usocket_destroy;
218 
219  return ipct;
220 }
221 
#define x_return_val_if_fail(expr, val)
Definition: xmmsc_util.h:13
char * path
Definition: url.h:11
xmms_ipc_transport_t * xmms_ipc_usocket_client_init(const xmms_url_t *url)
Definition: socket_unix.c:72
xmms_ipc_write_func write_func
xmms_ipc_destroy_func destroy_func
xmms_ipc_transport_t * xmms_ipc_usocket_server_init(const xmms_url_t *url)
Definition: socket_unix.c:163
xmms_ipc_accept_func accept_func
#define x_new0(type, num)
Definition: xmmsc_util.h:16
Definition: url.h:4
xmms_ipc_read_func read_func