From: Bartosz Golaszewski Date: Tue, 17 Jan 2017 14:43:13 +0000 (+0100) Subject: gpioset: new option X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=16eef73475b14e185fba8c352bd3db3fdfd016a2;p=qemu-gpiodev%2Flibgpiod.git gpioset: new option Add an option allowing the program to detach from the controlling terminal after setting values. This is useful for pulled-down/up pins that we want to keep exported. Signed-off-by: Bartosz Golaszewski --- diff --git a/src/tools/gpioset.c b/src/tools/gpioset.c index 1fc1f4c..be98fe8 100644 --- a/src/tools/gpioset.c +++ b/src/tools/gpioset.c @@ -29,10 +29,11 @@ static const struct option longopts[] = { { "mode", required_argument, NULL, 'm' }, { "sec", required_argument, NULL, 's' }, { "usec", required_argument, NULL, 'u' }, + { "background", no_argument, NULL, 'b' }, { 0 }, }; -static const char *const shortopts = "+hvlm:s:u:"; +static const char *const shortopts = "+hvlm:s:u:b"; static void print_help(void) { @@ -47,6 +48,7 @@ static void print_help(void) printf(" tell the program what to do after setting values\n"); printf(" -s, --sec=SEC:\tspecify the number of seconds to wait (only valid for --mode=time)\n"); printf(" -u, --usec=USEC:\tspecify the number of microseconds to wait (only valid for --mode=time)\n"); + printf(" -b, --background:\tafter setting values: detach from the controlling terminal\n"); printf("\n"); printf("Modes:\n"); printf(" exit:\tset values and exit immediately\n"); @@ -58,8 +60,20 @@ static void print_help(void) struct callback_data { /* Replace with a union once we have more modes using callback data. */ struct timeval tv; + bool daemonize; }; +static void maybe_daemonize(bool daemonize) +{ + int status; + + if (daemonize) { + status = daemon(0, 0); + if (status < 0) + die("unable to daemonize: %s", strerror(errno)); + } +} + static void wait_enter(void *data UNUSED) { getchar(); @@ -69,11 +83,13 @@ static void wait_time(void *data) { struct callback_data *cbdata = data; + maybe_daemonize(cbdata->daemonize); select(0, NULL, NULL, NULL, &cbdata->tv); } -static void wait_signal(void *data UNUSED) +static void wait_signal(void *data) { + struct callback_data *cbdata = data; int sigfd, status; struct pollfd pfd; sigset_t sigmask; @@ -94,6 +110,8 @@ static void wait_signal(void *data UNUSED) pfd.fd = sigfd; pfd.events = POLLIN | POLLPRI; + maybe_daemonize(cbdata->daemonize); + for (;;) { status = poll(&pfd, 1, 1000 /* one second */); if (status < 0) @@ -204,6 +222,11 @@ int main(int argc, char **argv) die("invalid time value in microseconds: %s", optarg); break; + case 'b': + if (mode->id != MODE_SIGNAL && mode->id != MODE_TIME) + die("can't daemonize in this mode"); + cbdata.daemonize = true; + break; case '?': die("try %s --help", get_progname()); default: