diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2006-11-17 20:08:14 +0000 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2006-11-17 20:08:14 +0000 | 
| commit | 71094ca865f428f8ce699266c6d5037e60d525fb (patch) | |
| tree | ff95c9f2a1c4837acbd99b6506f63cdb8e271019 /sdpd/main.c | |
| parent | 0960d076f77e67d99592e76d83ecd36ea7182618 (diff) | |
Make use of generic mainloop
Diffstat (limited to 'sdpd/main.c')
| -rw-r--r-- | sdpd/main.c | 217 | 
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; | 
