]>
code.delx.au - pulseaudio/blob - src/socket-server.c
6 #include <sys/socket.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
13 #include "socket-server.h"
15 struct socket_server
{
19 void (*on_connection
)(struct socket_server
*s
, struct iochannel
*io
, void *userdata
);
22 struct mainloop_source
*mainloop_source
;
25 static void callback(struct mainloop_source
*src
, int fd
, enum mainloop_io_event event
, void *userdata
) {
26 struct socket_server
*s
= userdata
;
29 assert(src
&& fd
>= 0 && fd
== s
->fd
&& event
== MAINLOOP_IO_EVENT_IN
&& s
);
31 if ((nfd
= accept(fd
, NULL
, NULL
)) < 0) {
32 fprintf(stderr
, "accept(): %s\n", strerror(errno
));
36 if (!s
->on_connection
) {
41 io
= iochannel_new(mainloop_source_get_mainloop(src
), nfd
, nfd
);
43 s
->on_connection(s
, io
, s
->userdata
);
46 struct socket_server
* socket_server_new(struct mainloop
*m
, int fd
) {
47 struct socket_server
*s
;
50 s
= malloc(sizeof(struct socket_server
));
54 s
->on_connection
= NULL
;
57 s
->mainloop_source
= mainloop_source_new_io(m
, fd
, MAINLOOP_IO_EVENT_IN
, callback
, s
);
58 assert(s
->mainloop_source
);
63 struct socket_server
* socket_server_new_unix(struct mainloop
*m
, const char *filename
) {
65 struct sockaddr_un sa
;
66 struct socket_server
*s
;
68 assert(m
&& filename
);
70 if ((fd
= socket(PF_LOCAL
, SOCK_STREAM
, 0)) < 0) {
71 fprintf(stderr
, "socket(): %s\n", strerror(errno
));
75 sa
.sun_family
= AF_LOCAL
;
76 strncpy(sa
.sun_path
, filename
, sizeof(sa
.sun_path
)-1);
77 sa
.sun_path
[sizeof(sa
.sun_path
) - 1] = 0;
79 if (bind(fd
, (struct sockaddr
*) &sa
, SUN_LEN(&sa
)) < 0) {
80 fprintf(stderr
, "bind(): %s\n", strerror(errno
));
84 if (listen(fd
, 5) < 0) {
85 fprintf(stderr
, "listen(): %s\n", strerror(errno
));
89 s
= socket_server_new(m
, fd
);
92 s
->filename
= strdup(filename
);
104 struct socket_server
* socket_server_new_ipv4(struct mainloop
*m
, uint32_t address
, uint16_t port
) {
106 struct sockaddr_in sa
;
111 if ((fd
= socket(PF_INET
, SOCK_STREAM
, 0)) < 0) {
112 fprintf(stderr
, "socket(): %s\n", strerror(errno
));
116 if (setsockopt(fd
, SOL_SOCKET
, SO_REUSEADDR
, &on
, sizeof(on
)) < 0)
117 fprintf(stderr
, "setsockopt(): %s\n", strerror(errno
));
119 sa
.sin_family
= AF_INET
;
120 sa
.sin_port
= htons(port
);
121 sa
.sin_addr
.s_addr
= htonl(address
);
123 if (bind(fd
, (struct sockaddr
*) &sa
, sizeof(sa
)) < 0) {
124 fprintf(stderr
, "bind(): %s\n", strerror(errno
));
128 if (listen(fd
, 5) < 0) {
129 fprintf(stderr
, "listen(): %s\n", strerror(errno
));
133 return socket_server_new(m
, fd
);
142 void socket_server_free(struct socket_server
*s
) {
151 mainloop_source_free(s
->mainloop_source
);
156 void socket_server_set_callback(struct socket_server
*s
, void (*on_connection
)(struct socket_server
*s
, struct iochannel
*io
, void *userdata
), void *userdata
) {
159 s
->on_connection
= on_connection
;
160 s
->userdata
= userdata
;