From e970c174c262aff0debea9a246ebc8960090675d Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 15 Nov 2008 00:13:19 +0200 Subject: [PATCH] obexd: Add support for reinitializing a tty based server This patch adds support for retrying to open a tty when the daemon receives a SIGUSR1 signal. This is e.g. needed for USB Gadget Serial so that obexd can be notified that USB cable is plugged in and that a matching device node is available. --- obexd/src/main.c | 57 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/obexd/src/main.c b/obexd/src/main.c index 9cdb20fad..c7be4ad71 100644 --- a/obexd/src/main.c +++ b/obexd/src/main.c @@ -59,6 +59,10 @@ static GMainLoop *main_loop = NULL; +static int services = 0; +static gboolean tty_needs_reinit = FALSE; +static int signal_pipe[2]; + int tty_init(int services, const gchar *root_path, const gchar *capability, const gchar *devnode) { @@ -67,6 +71,8 @@ int tty_init(int services, const gchar *root_path, int fd, ret; glong flags; + tty_needs_reinit = TRUE; + fd = open(devnode, O_RDWR); if (fd < 0) return fd; @@ -89,7 +95,8 @@ int tty_init(int services, const gchar *root_path, if (ret < 0) { server_free(server); close(fd); - } + } else + tty_needs_reinit = FALSE; return ret; } @@ -134,12 +141,55 @@ static GOptionEntry options[] = { { NULL }, }; +static void sig_usr1(int sig) +{ + if (write(signal_pipe[1], &sig, sizeof(sig)) != sizeof(sig)) + error("unable to write to signal pipe"); +} + +static gboolean handle_signal(GIOChannel *io, GIOCondition cond, + void *user_data) +{ + int sig, fd = g_io_channel_unix_get_fd(io); + + if (read(fd, &sig, sizeof(sig)) != sizeof(sig)) { + error("handle_sigusr1: unable to read signal from pipe"); + return TRUE; + } + + if (sig == SIGUSR1 && tty_needs_reinit) + tty_init(services, option_root, option_capability, + option_devnode); + + return TRUE; +} + +static int devnode_setup(void) +{ + struct sigaction sa; + GIOChannel *pipe_io; + + if (pipe(signal_pipe) < 0) + return -errno; + + pipe_io = g_io_channel_unix_new(signal_pipe[0]); + g_io_add_watch(pipe_io, G_IO_IN, handle_signal, NULL); + g_io_channel_unref(pipe_io); + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sig_usr1; + sigaction(SIGUSR1, &sa, NULL); + + return tty_init(services, option_root, option_capability, + option_devnode); +} + int main(int argc, char *argv[]) { GOptionContext *context; GError *err = NULL; struct sigaction sa; - int log_option = LOG_NDELAY | LOG_PID, services = 0; + int log_option = LOG_NDELAY | LOG_PID; #ifdef NEED_THREADS if (g_thread_supported() == FALSE) @@ -224,8 +274,7 @@ int main(int argc, char *argv[]) } if (option_devnode) - tty_init(services, option_root, option_capability, - option_devnode); + devnode_setup(); memset(&sa, 0, sizeof(sa)); sa.sa_handler = sig_term; -- 2.47.3