diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2008-11-15 00:13:19 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2008-11-15 00:13:19 +0200 |
commit | 78ff0406fc39ed45e189a5ea9111019e53e41dcf (patch) | |
tree | b8d890e267b0ef4e86c80b29b57525c77ef8b1a4 | |
parent | 1249dfe12027fe7c1e6662458101d6e9c4180a4d (diff) | |
download | obexd-78ff0406fc39ed45e189a5ea9111019e53e41dcf.tar.gz |
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.
-rw-r--r-- | src/main.c | 57 |
1 files changed, 53 insertions, 4 deletions
@@ -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; |