summaryrefslogtreecommitdiffstats
path: root/sdpd
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2006-11-17 20:08:14 +0000
committerMarcel Holtmann <marcel@holtmann.org>2006-11-17 20:08:14 +0000
commit71094ca865f428f8ce699266c6d5037e60d525fb (patch)
treeff95c9f2a1c4837acbd99b6506f63cdb8e271019 /sdpd
parent0960d076f77e67d99592e76d83ecd36ea7182618 (diff)
Make use of generic mainloop
Diffstat (limited to 'sdpd')
-rw-r--r--sdpd/main.c217
1 files changed, 112 insertions, 105 deletions
diff --git a/sdpd/main.c b/sdpd/main.c
index 9e3391a9..3a663218 100644
--- a/sdpd/main.c
+++ b/sdpd/main.c
@@ -34,9 +34,7 @@
#include <stdlib.h>
#include <signal.h>
#include <getopt.h>
-#define _XOPEN_SOURCE 600
#include <sys/stat.h>
-#include <sys/select.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
@@ -47,12 +45,14 @@
#include <sys/un.h>
#include <netinet/in.h>
+#include "glib-ectomy.h"
+
#include "sdpd.h"
#include "logging.h"
+static GMainLoop *event_loop;
+
static int l2cap_sock, unix_sock;
-static fd_set active_fdset;
-static int active_maxfd;
static sdp_record_t *server;
@@ -244,10 +244,12 @@ static int init_server(uint16_t mtu, int master, int public)
return -1;
}
- l2addr.l2_bdaddr = *BDADDR_ANY;
+ memset(&l2addr, 0, sizeof(l2addr));
l2addr.l2_family = AF_BLUETOOTH;
- l2addr.l2_psm = htobs(SDP_PSM);
- if (bind(l2cap_sock, (struct sockaddr *)&l2addr, sizeof(l2addr)) < 0) {
+ bacpy(&l2addr.l2_bdaddr, BDADDR_ANY);
+ l2addr.l2_psm = htobs(SDP_PSM);
+
+ if (bind(l2cap_sock, (struct sockaddr *) &l2addr, sizeof(l2addr)) < 0) {
error("binding L2CAP socket: %s", strerror(errno));
return -1;
}
@@ -278,8 +280,6 @@ static int init_server(uint16_t mtu, int master, int public)
}
listen(l2cap_sock, 5);
- FD_SET(l2cap_sock, &active_fdset);
- active_maxfd = l2cap_sock;
/* Create local Unix socket */
unix_sock = socket(PF_UNIX, SOCK_STREAM, 0);
@@ -288,31 +288,24 @@ static int init_server(uint16_t mtu, int master, int public)
return -1;
}
+ memset(&unaddr, 0, sizeof(unaddr));
unaddr.sun_family = AF_UNIX;
strcpy(unaddr.sun_path, SDP_UNIX_PATH);
+
unlink(unaddr.sun_path);
- if (bind(unix_sock, (struct sockaddr *)&unaddr, sizeof(unaddr)) < 0) {
+
+ if (bind(unix_sock, (struct sockaddr *) &unaddr, sizeof(unaddr)) < 0) {
error("binding UNIX socket: %s", strerror(errno));
return -1;
}
listen(unix_sock, 5);
- FD_SET(unix_sock, &active_fdset);
- active_maxfd = unix_sock;
+
chmod(SDP_UNIX_PATH, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
return 0;
}
-static void sig_term(int sig)
-{
- info("terminating...");
- sdp_svcdb_reset();
- close(l2cap_sock);
- close(unix_sock);
- exit(0);
-}
-
static inline void handle_request(int sk, uint8_t *data, int len)
{
struct sockaddr_l2 sa;
@@ -349,46 +342,74 @@ static inline void handle_request(int sk, uint8_t *data, int len)
process_request(&req);
}
-static void close_sock(int fd, int r)
-{
- if (r < 0)
- error("Read error: %s", strerror(errno));
- FD_CLR(fd, &active_fdset);
- close(fd);
- sdp_svcdb_collect_all(fd);
- if (fd == active_maxfd)
- active_maxfd--;
-}
-
-static void check_active(fd_set *mask, int num)
+static gboolean io_session_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
sdp_pdu_hdr_t hdr;
- int size, fd, count, r;
uint8_t *buf;
+ int sk, len, size;
- for (fd = 0, count = 0; fd <= active_maxfd && count < num; fd++) {
- if (fd == l2cap_sock || fd == unix_sock || !FD_ISSET(fd, mask))
- continue;
+ if (cond & (G_IO_HUP | G_IO_ERR)) {
+ g_io_channel_unref(chan);
+ return FALSE;
+ }
- count++;
+ sk = g_io_channel_unix_get_fd(chan);
- r = recv(fd, (void *)&hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK);
- if (r <= 0) {
- close_sock(fd, r);
- continue;
- }
+ len = recv(sk, &hdr, sizeof(sdp_pdu_hdr_t), MSG_PEEK);
+ if (len <= 0) {
+ sdp_svcdb_collect_all(sk);
+ return FALSE;
+ }
- size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen);
- buf = malloc(size);
- if (!buf)
- continue;
+ size = sizeof(sdp_pdu_hdr_t) + ntohs(hdr.plen);
+ buf = malloc(size);
+ if (!buf)
+ return TRUE;
- r = recv(fd, buf, size, 0);
- if (r <= 0)
- close_sock(fd, r);
- else
- handle_request(fd, buf, r);
+ len = recv(sk, buf, size, 0);
+ if (len <= 0) {
+ sdp_svcdb_collect_all(sk);
+ return FALSE;
}
+
+ handle_request(sk, buf, len);
+
+ return TRUE;
+}
+
+static gboolean io_accept_event(GIOChannel *chan, GIOCondition cond, gpointer data)
+{
+ GIOChannel *io;
+ int nsk;
+
+ if (data == &l2cap_sock) {
+ struct sockaddr_l2 addr;
+ socklen_t len = sizeof(addr);
+
+ nsk = accept(l2cap_sock, (struct sockaddr *) &addr, &len);
+ } else if (data == &unix_sock) {
+ struct sockaddr_un addr;
+ socklen_t len = sizeof(addr);
+
+ nsk = accept(unix_sock, (struct sockaddr *) &addr, &len);
+ } else
+ return FALSE;
+
+ io = g_io_channel_unix_new(nsk);
+ g_io_channel_set_close_on_unref(io, TRUE);
+
+ g_io_add_watch(io, G_IO_IN, io_session_event, data);
+
+ return TRUE;
+}
+
+static void sig_term(int sig)
+{
+ g_main_quit(event_loop);
+}
+
+static void sig_hup(int sig)
+{
}
static void usage(void)
@@ -409,10 +430,10 @@ static struct option main_options[] = {
int main(int argc, char *argv[])
{
- sigset_t sigs;
+ struct sigaction sa;
+ GIOChannel *l2cap_io, *unix_io;
uint16_t mtu = 0;
- int daemonize = 1, public = 0, master = 0;
- int opt;
+ int opt, daemonize = 1, public = 0, master = 0;
while ((opt = getopt_long(argc, argv, "nm:pM", main_options, NULL)) != -1) {
switch (opt) {
@@ -443,8 +464,22 @@ int main(int argc, char *argv[])
exit(1);
}
+ umask(0077);
+
start_logging("sdpd", "Bluetooth SDP daemon");
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_flags = SA_NOCLDSTOP;
+ sa.sa_handler = sig_term;
+ sigaction(SIGTERM, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sa.sa_handler = sig_hup;
+ sigaction(SIGHUP, &sa, NULL);
+
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGCHLD, &sa, NULL);
+ sigaction(SIGPIPE, &sa, NULL);
+
#ifdef SDP_DEBUG
enable_debug();
#endif
@@ -454,60 +489,32 @@ int main(int argc, char *argv[])
exit(1);
}
- signal(SIGINT, sig_term);
- signal(SIGTERM, sig_term);
- signal(SIGABRT, sig_term);
- signal(SIGQUIT, sig_term);
- signal(SIGPIPE, SIG_IGN);
-
- sigfillset(&sigs);
- sigdelset(&sigs, SIGINT);
- sigdelset(&sigs, SIGTERM);
- sigdelset(&sigs, SIGABRT);
- sigdelset(&sigs, SIGQUIT);
- sigdelset(&sigs, SIGPIPE);
-
- for (;;) {
- int num, nfd;
- fd_set mask;
-
- FD_ZERO(&mask);
- mask = active_fdset;
-
- num = pselect(active_maxfd + 1, &mask, NULL, NULL, NULL, &sigs);
- if (num <= 0) {
- debug("Select error:%s", strerror(errno));
- break;
- }
+ /* Create event loop */
+ event_loop = g_main_new(FALSE);
- if (FD_ISSET(l2cap_sock, &mask)) {
- /* New L2CAP connection */
- struct sockaddr_l2 caddr;
- socklen_t len = sizeof(caddr);
-
- nfd = accept(l2cap_sock, (struct sockaddr *)&caddr, &len);
- if (nfd >= 0) {
- if (nfd > active_maxfd)
- active_maxfd = nfd;
- FD_SET(nfd, &active_fdset);
- }
- } else if (FD_ISSET(unix_sock, &mask)) {
- /* New unix connection */
- struct sockaddr_un caddr;
- socklen_t len = sizeof(caddr);
-
- nfd = accept(unix_sock, (struct sockaddr *)&caddr, &len);
- if (nfd != -1) {
- if (nfd > active_maxfd)
- active_maxfd = nfd;
- FD_SET(nfd, &active_fdset);
- }
- } else
- check_active(&mask, num);
- }
+ l2cap_io = g_io_channel_unix_new(l2cap_sock);
+ g_io_channel_set_close_on_unref(l2cap_io, TRUE);
+
+ g_io_add_watch(l2cap_io, G_IO_IN, io_accept_event, &l2cap_sock);
+
+ unix_io = g_io_channel_unix_new(unix_sock);
+ g_io_channel_set_close_on_unref(unix_io, TRUE);
+
+ g_io_add_watch(unix_io, G_IO_IN, io_accept_event, &unix_sock);
+
+ /* Start event processor */
+ g_main_run(event_loop);
sdp_svcdb_reset();
+ g_main_unref(event_loop);
+
+ g_io_channel_unref(unix_io);
+
+ g_io_channel_unref(l2cap_io);
+
+ info("Exit");
+
stop_logging();
return 0;