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
36static void
37xmms_ipc_usocket_destroy (xmms_ipc_transport_t *ipct)
38{
39 free (ipct->path);
40 close (ipct->fd);
41}
42
43static int
44xmms_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
58static int
59xmms_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
119xmms_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;
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
xmms_ipc_accept_func accept_func
xmms_ipc_read_func read_func
xmms_ipc_destroy_func destroy_func
xmms_ipc_write_func write_func
Definition: url.h:4
char * path
Definition: url.h:11
#define x_return_val_if_fail(expr, val)
Definition: xmmsc_util.h:13
#define x_new0(type, num)
Definition: xmmsc_util.h:16
xmms_ipc_transport_t * xmms_ipc_usocket_client_init(const xmms_url_t *url)
Definition: socket_unix.c:72
xmms_ipc_transport_t * xmms_ipc_usocket_server_init(const xmms_url_t *url)
Definition: socket_unix.c:163