From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> This adds handling of systemd NOTIFY_SOCKET so application using mainloop instance do properly notify systemd what is their state. --- Makefile.am | 8 +++- src/shared/mainloop-glib.c | 6 +++ src/shared/mainloop-notify.c | 93 ++++++++++++++++++++++++++++++++++++ src/shared/mainloop-notify.h | 25 ++++++++++ src/shared/mainloop.c | 10 ++++ src/shared/mainloop.h | 1 + 6 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 src/shared/mainloop-notify.c create mode 100644 src/shared/mainloop-notify.h diff --git a/Makefile.am b/Makefile.am index 0b26ccc3e..124c32482 100644 --- a/Makefile.am +++ b/Makefile.am @@ -130,12 +130,16 @@ endif src_libshared_glib_la_SOURCES = $(shared_sources) \ src/shared/io-glib.c \ src/shared/timeout-glib.c \ - src/shared/mainloop-glib.c + src/shared/mainloop-glib.c \ + src/shared/mainloop-notify.h \ + src/shared/mainloop-notify.c src_libshared_mainloop_la_SOURCES = $(shared_sources) \ src/shared/io-mainloop.c \ src/shared/timeout-mainloop.c \ - src/shared/mainloop.h src/shared/mainloop.c + src/shared/mainloop.h src/shared/mainloop.c \ + src/shared/mainloop-notify.h \ + src/shared/mainloop-notify.c if ELL src_libshared_ell_la_SOURCES = $(shared_sources) \ diff --git a/src/shared/mainloop-glib.c b/src/shared/mainloop-glib.c index 8436969bb..42abfddf8 100644 --- a/src/shared/mainloop-glib.c +++ b/src/shared/mainloop-glib.c @@ -36,6 +36,7 @@ #include <glib.h> #include "mainloop.h" +#include "mainloop-notify.h" static GMainLoop *main_loop; static int exit_status; @@ -43,6 +44,7 @@ static int exit_status; void mainloop_init(void) { main_loop = g_main_loop_new(NULL, FALSE); + mainloop_notify_init(); } void mainloop_quit(void) @@ -51,6 +53,8 @@ void mainloop_quit(void) return; g_main_loop_quit(main_loop); + + mainloop_sd_notify("STOPPING=1"); } void mainloop_exit_success(void) @@ -75,6 +79,8 @@ int mainloop_run(void) g_main_loop_unref(main_loop); main_loop = NULL; + mainloop_notify_exit(); + return exit_status; } diff --git a/src/shared/mainloop-notify.c b/src/shared/mainloop-notify.c new file mode 100644 index 000000000..fdc2f25ec --- /dev/null +++ b/src/shared/mainloop-notify.c @@ -0,0 +1,93 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> + +#include <sys/socket.h> +#include <sys/un.h> + +#include "mainloop.h" +#include "mainloop-notify.h" + +static int notify_fd = -1; + +void mainloop_notify_init(void) +{ + const char *sock; + struct sockaddr_un addr; + + sock = getenv("NOTIFY_SOCKET"); + if (!sock) + return; + + /* check for abstract socket or absolute path */ + if (sock[0] != '@' && sock[0] != '/') + return; + + notify_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (notify_fd < 0) + return; + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, sock, sizeof(addr.sun_path) - 1); + + if (addr.sun_path[0] == '@') + addr.sun_path[0] = '\0'; + + if (bind(notify_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + close(notify_fd); + notify_fd = -1; + } +} + +void mainloop_notify_exit(void) +{ + if (notify_fd > 0) { + close(notify_fd); + notify_fd = -1; + } +} + +int mainloop_sd_notify(const char *state) +{ + int err; + + if (notify_fd <= 0) + return -ENOTCONN; + + err = send(notify_fd, state, strlen(state), MSG_NOSIGNAL); + if (err < 0) + return -errno; + + return err; +} diff --git a/src/shared/mainloop-notify.h b/src/shared/mainloop-notify.h new file mode 100644 index 000000000..721b5fbed --- /dev/null +++ b/src/shared/mainloop-notify.h @@ -0,0 +1,25 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +void mainloop_notify_init(void); +void mainloop_notify_exit(void); diff --git a/src/shared/mainloop.c b/src/shared/mainloop.c index e6ab9c43d..e9ec6e8cd 100644 --- a/src/shared/mainloop.c +++ b/src/shared/mainloop.c @@ -30,13 +30,17 @@ #include <errno.h> #include <unistd.h> #include <stdlib.h> +#include <stddef.h> #include <string.h> #include <signal.h> #include <sys/signalfd.h> #include <sys/timerfd.h> #include <sys/epoll.h> +#include <sys/socket.h> +#include <sys/un.h> #include "mainloop.h" +#include "mainloop-notify.h" #define MAX_EPOLL_EVENTS 10 @@ -83,11 +87,15 @@ void mainloop_init(void) mainloop_list[i] = NULL; epoll_terminate = 0; + + mainloop_notify_init(); } void mainloop_quit(void) { epoll_terminate = 1; + + mainloop_sd_notify("STOPPING=1"); } void mainloop_exit_success(void) @@ -183,6 +191,8 @@ int mainloop_run(void) close(epoll_fd); epoll_fd = 0; + mainloop_notify_exit(); + return exit_status; } diff --git a/src/shared/mainloop.h b/src/shared/mainloop.h index b83caabc8..73ed81187 100644 --- a/src/shared/mainloop.h +++ b/src/shared/mainloop.h @@ -49,3 +49,4 @@ int mainloop_remove_timeout(int id); int mainloop_set_signal(sigset_t *mask, mainloop_signal_func callback, void *user_data, mainloop_destroy_func destroy); +int mainloop_sd_notify(const char *state); -- 2.17.2