diff options
| -rw-r--r-- | hcid/main.c | 46 | 
1 files changed, 44 insertions, 2 deletions
| diff --git a/hcid/main.c b/hcid/main.c index f7b1bfd0..7cbf679a 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -37,6 +37,8 @@  #include <sys/stat.h>  #include <sys/ioctl.h>  #include <sys/socket.h> +#include <sys/types.h> +#include <sys/wait.h>  #include <bluetooth/bluetooth.h>  #include <bluetooth/hci.h> @@ -57,6 +59,7 @@ struct hcid_opts hcid;  struct device_opts default_device;  struct device_opts *parser_device;  static struct device_list *device_list = NULL; +static int child_pipe[2];  static inline void init_device_defaults(struct device_opts *device_opts)  { @@ -275,6 +278,32 @@ static char *expand_name(char *dst, int size, char *str, int dev_id)  	return dst;  } +static gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data) +{ +	int status, fd = g_io_channel_unix_get_fd(io); +	pid_t child_pid; +	 +	if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) { +		error("child_exit: unable to read child pid from pipe"); +		return TRUE; +	} + +	if (waitpid(child_pid, &status, 0) != child_pid) +		error("waitpid(%d) failed", child_pid); +	else +		debug("child %d exited", child_pid); + +	return TRUE; +} + +static void at_child_exit(void) +{ +	pid_t pid = getpid(); + +	if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid)) +		error("unable to write to child pipe"); +} +  static void configure_device(int dev_id)  {  	struct device_opts *device_opts; @@ -313,6 +342,7 @@ static void configure_device(int dev_id)  	/* Do configuration in the separate process */  	switch (fork()) {  		case 0: +			atexit(at_child_exit);  			break;  		case -1:  			error("Fork failed. Can't init device hci%d: %s (%d)", @@ -437,6 +467,7 @@ static void init_device(int dev_id)  	/* Do initialization in the separate process */  	switch (fork()) {  		case 0: +			atexit(at_child_exit);  			break;  		case -1:  			error("Fork failed. Can't init device hci%d: %s (%d)", @@ -652,7 +683,7 @@ int main(int argc, char *argv[])  	struct sockaddr_hci addr;  	struct hci_filter flt;  	struct sigaction sa; -	GIOChannel *ctl_io; +	GIOChannel *ctl_io, *child_io;  	int opt, daemonize = 1, debug = 0, sdp = 0, experimental = 0;  	/* Default HCId settings */ @@ -720,7 +751,6 @@ int main(int argc, char *argv[])  	sigaction(SIGUSR2, &sa, NULL);  	sa.sa_handler = SIG_IGN; -	sigaction(SIGCHLD, &sa, NULL);  	sigaction(SIGPIPE, &sa, NULL);  	if (debug) { @@ -756,6 +786,18 @@ int main(int argc, char *argv[])  	if (read_config(hcid.config_file) < 0)  		error("Config load failed"); +	if (pipe(child_pipe) < 0) { +		error("pipe(): %s (%d)", strerror(errno), errno); +		exit(1); +	} + +	child_io = g_io_channel_unix_new(child_pipe[0]); +	g_io_channel_set_close_on_unref(child_io, TRUE); +	g_io_add_watch(child_io, +			G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, +			child_exit, NULL); +	g_io_channel_unref(child_io); +  	init_devices();  	if (hcid_dbus_init() < 0) { | 
