diff options
author | Mattias Andrée <maandree@operamail.com> | 2015-11-29 10:43:58 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@operamail.com> | 2015-11-29 10:43:58 +0100 |
commit | 7f14931def91afb3c6533df4e6ff1b6fa17d713c (patch) | |
tree | bcf15d8773f98d1e7ad48b4d4c3c61fa7668c6fb /doc/examples/daemon-dependencies | |
parent | add almost all examples to info (diff) | |
download | bus-7f14931def91afb3c6533df4e6ff1b6fa17d713c.tar.gz bus-7f14931def91afb3c6533df4e6ff1b6fa17d713c.tar.bz2 bus-7f14931def91afb3c6533df4e6ff1b6fa17d713c.tar.xz |
typo
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'doc/examples/daemon-dependencies')
-rw-r--r-- | doc/examples/daemon-dependencies/.gitignore | 10 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/Makefile | 14 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/README | 19 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/announce.c | 28 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/await-ready.c | 122 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/await-started.c | 127 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/cleanup.c | 25 | ||||
-rwxr-xr-x | doc/examples/daemon-dependencies/d-network | 9 | ||||
-rwxr-xr-x | doc/examples/daemon-dependencies/d-ntp | 11 | ||||
-rwxr-xr-x | doc/examples/daemon-dependencies/d-ssh | 13 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/init.c | 127 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/require.c | 38 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/start-daemon.c | 32 | ||||
-rw-r--r-- | doc/examples/daemon-dependencies/test-daemon.c | 35 |
14 files changed, 610 insertions, 0 deletions
diff --git a/doc/examples/daemon-dependencies/.gitignore b/doc/examples/daemon-dependencies/.gitignore new file mode 100644 index 0000000..0dac119 --- /dev/null +++ b/doc/examples/daemon-dependencies/.gitignore @@ -0,0 +1,10 @@ +run/ +announce +await-ready +await-started +cleanup +init +require +start-daemon +test-daemon + diff --git a/doc/examples/daemon-dependencies/Makefile b/doc/examples/daemon-dependencies/Makefile new file mode 100644 index 0000000..bf6fe88 --- /dev/null +++ b/doc/examples/daemon-dependencies/Makefile @@ -0,0 +1,14 @@ +COMMANDS = announce await-ready await-started cleanup init require start-daemon test-daemon + +all: ${COMMANDS} + +%: %.c + ${CC} -Wall -Wextra -pedantic -std=c99 -lbus -o $@ $< + +clean: + -rm ${COMMANDS} + -rm -r run + + +.PHONY: all clean + diff --git a/doc/examples/daemon-dependencies/README b/doc/examples/daemon-dependencies/README new file mode 100644 index 0000000..a9f5783 --- /dev/null +++ b/doc/examples/daemon-dependencies/README @@ -0,0 +1,19 @@ +Use-case example. + +This example shows how bus can be used in a init +system to provide "aggressivly" parallel startup +of daemons. + + +First of, run make to build this example. + +To start the example run ./init. It will print in +red export-statement you may want to run i other +terminals. You will need to select at least one +daemon, for example you can run `./init d-ntp`. +The available pretend daemons are: d-network, +d-ntp and d-ssh. + +When you are done run ./cleanup with BUS_INIT +exported with the value printed by ./init. + diff --git a/doc/examples/daemon-dependencies/announce.c b/doc/examples/daemon-dependencies/announce.c new file mode 100644 index 0000000..d928adb --- /dev/null +++ b/doc/examples/daemon-dependencies/announce.c @@ -0,0 +1,28 @@ +#include <bus.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> + +#define t(stmt) if (stmt) goto fail + + +static char arg[4098]; + + +int +main(int argc, char *argv[]) +{ + bus_t bus; + if (argc < 3) + return fprintf(stderr, "USAGE: %s state daemon", *argv), 2; + t(bus_open(&bus, getenv("BUS_INIT"), BUS_WRONLY)); + sprintf(arg, "%ji %s %s", (intmax_t)getppid(), argv[1], argv[2]); + t(bus_write(&bus, arg, 0)); + t(bus_close(&bus)); + return 0; + +fail: + perror("announce"); + return 1; +} diff --git a/doc/examples/daemon-dependencies/await-ready.c b/doc/examples/daemon-dependencies/await-ready.c new file mode 100644 index 0000000..fea2382 --- /dev/null +++ b/doc/examples/daemon-dependencies/await-ready.c @@ -0,0 +1,122 @@ +#include <bus.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <string.h> +#include <sys/wait.h> + +#define t(stmt) if (stmt) goto fail + + +static char arg[4098]; +static int argc; +static char **argv; +static int remaining = 0; +static char *started = NULL; +static char msg[BUS_MEMORY_SIZE]; + + +static void +announce_wait(pid_t pid) +{ + bus_t bus; + int i; + t(bus_open(&bus, getenv("BUS_INIT"), BUS_WRONLY)); + for (i = 1; i < argc; i++) { + if (!started[i]) { + sprintf(arg, "%ji awaiting-ready %s", (intmax_t)pid, argv[i]); + t(bus_write(&bus, arg, 0)); + } + } + t(bus_close(&bus)); + return; + +fail: + perror("await-ready"); +} + + +static int +callback(const char *message, void *user_data) +{ + int i; + char *arg2; + char *arg3; + pid_t pid; + pid_t ppid; + + if (!message) { + ppid = getppid(); + pid = fork(); + if (pid == 0) { + if (fork() == 0) + announce_wait(ppid); + exit(0); + } else { + (void) waitpid(pid, NULL, 0); /* Let's pretend everything will go swimmingly. */ + } + return 1; + } + + strncpy(msg, message, BUS_MEMORY_SIZE - 1); + msg[BUS_MEMORY_SIZE - 1] = 0; + + arg2 = strchr(msg, ' '); + if (!arg2) + return 1; + arg3 = strchr(++arg2, ' '); + if (!arg3) + return 1; + *arg3++ = 0; + + if (strcmp(arg2, "ready")) + return 1; + + for (i = 1; i < argc; i++) + if (!started[i] && !strcmp(argv[i], arg3)) + started[i] = 1, remaining--; + + return !!remaining; + (void) user_data; +} + + +int +main(int argc_, char *argv_[]) +{ + bus_t bus; + int i; + + argc = argc_; + argv = argv_; + + if (argc < 2) + return fprintf(stderr, "USAGE: %s daemon...", *argv), 2; + t(bus_open(&bus, getenv("BUS_INIT"), BUS_RDONLY)); + started = calloc(argc, sizeof(char)); + t(started == NULL); + + started[0] = 1; + for (i = 1; i < argc; i++) { + sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/ready-daemons\" >/dev/null", argv[i]); + if (!WEXITSTATUS(system(arg))) + started[i] = 1; + else + remaining++; + } + + if (remaining) + bus_read(&bus, callback, NULL); + + bus_close(&bus); + free(started); + return 0; + +fail: + perror("await-ready"); + bus_close(&bus); + free(started); + return 1; +} + diff --git a/doc/examples/daemon-dependencies/await-started.c b/doc/examples/daemon-dependencies/await-started.c new file mode 100644 index 0000000..99ba14f --- /dev/null +++ b/doc/examples/daemon-dependencies/await-started.c @@ -0,0 +1,127 @@ +#include <bus.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <string.h> +#include <sys/wait.h> + +#define t(stmt) if (stmt) goto fail + + +static char arg[4098]; +static int argc; +static char **argv; +static int remaining = 0; +static char *started = NULL; +static char msg[BUS_MEMORY_SIZE]; + + +static void +announce_wait(pid_t pid) +{ + bus_t bus; + int i; + t(bus_open(&bus, getenv("BUS_INIT"), BUS_WRONLY)); + for (i = 1; i < argc; i++) { + if (!started[i]) { + sprintf(arg, "%ji awaiting-started %s", (intmax_t)pid, argv[i]); + t(bus_write(&bus, arg, 0)); + } + } + t(bus_close(&bus)); + return; + +fail: + perror("await-started"); +} + + +static int +callback(const char *message, void *user_data) +{ + int i; + char *arg2; + char *arg3; + pid_t pid; + pid_t ppid; + + if (!message) { + ppid = getppid(); + pid = fork(); + if (pid == 0) { + if (fork() == 0) + announce_wait(ppid); + exit(0); + } else { + (void) waitpid(pid, NULL, 0); /* Let's pretend everything will go swimmingly. */ + } + return 1; + } + + strncpy(msg, message, BUS_MEMORY_SIZE - 1); + msg[BUS_MEMORY_SIZE - 1] = 0; + + arg2 = strchr(msg, ' '); + if (!arg2) + return 1; + arg3 = strchr(++arg2, ' '); + if (!arg3) + return 1; + *arg3++ = 0; + + if (strcmp(arg2, "started") && strcmp(arg2, "ready")) + return 1; + + for (i = 1; i < argc; i++) + if (!started[i] && !strcmp(argv[i], arg3)) + started[i] = 1, remaining--; + + return !!remaining; + (void) user_data; +} + + +int +main(int argc_, char *argv_[]) +{ + bus_t bus; + int i; + + argc = argc_; + argv = argv_; + + if (argc < 2) + return fprintf(stderr, "USAGE: %s daemon...", *argv), 2; + t(bus_open(&bus, getenv("BUS_INIT"), BUS_RDONLY)); + started = calloc(argc, sizeof(char)); + t(started == NULL); + + started[0] = 1; + for (i = 1; i < argc; i++) { + sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/started-daemons\" >/dev/null", argv[i]); + if (!WEXITSTATUS(system(arg))) { + started[i] = 1; + } else { + sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/ready-daemons\" >/dev/null", argv[i]); + if (!WEXITSTATUS(system(arg))) + started[i] = 1; + else + remaining++; + } + } + + if (remaining) + bus_read(&bus, callback, NULL); + + bus_close(&bus); + free(started); + return 0; + +fail: + perror("await-started"); + bus_close(&bus); + free(started); + return 1; +} + diff --git a/doc/examples/daemon-dependencies/cleanup.c b/doc/examples/daemon-dependencies/cleanup.c new file mode 100644 index 0000000..f9ead6d --- /dev/null +++ b/doc/examples/daemon-dependencies/cleanup.c @@ -0,0 +1,25 @@ +#include <bus.h> +#include <stdio.h> +#include <stdlib.h> + +#define t(stmt) if (stmt) goto fail + + + +int +main() +{ + char *bus_address = getenv("BUS_INIT"); + if (!bus_address || !*bus_address) { + fprintf(stderr, "$BUS_INIT has not been set, its export statement " + "should have been printed in bold red by ./init\n"); + return 1; + } + t(bus_unlink(bus_address)); + return 0; + +fail: + perror("cleanup"); + return 1; +} + diff --git a/doc/examples/daemon-dependencies/d-network b/doc/examples/daemon-dependencies/d-network new file mode 100755 index 0000000..1b8c7dd --- /dev/null +++ b/doc/examples/daemon-dependencies/d-network @@ -0,0 +1,9 @@ +#!/bin/sh +PATH=.:$PATH +d=d-network + +echo $d: starting +sleep 2 +echo $d: ready +announce ready $d + diff --git a/doc/examples/daemon-dependencies/d-ntp b/doc/examples/daemon-dependencies/d-ntp new file mode 100755 index 0000000..0f29c7c --- /dev/null +++ b/doc/examples/daemon-dependencies/d-ntp @@ -0,0 +1,11 @@ +#!/bin/sh +PATH=.:$PATH +d=d-ntp + +require d-network +echo $d: started +announce started $d +await-ready d-network +echo $d: ready +announce ready $d + diff --git a/doc/examples/daemon-dependencies/d-ssh b/doc/examples/daemon-dependencies/d-ssh new file mode 100755 index 0000000..487354e --- /dev/null +++ b/doc/examples/daemon-dependencies/d-ssh @@ -0,0 +1,13 @@ +#!/bin/sh +PATH=.:$PATH +d=d-ssh + +require d-network +echo $d: starting +sleep 1 +echo $d: started +announce started $d +sleep 1 +echo $d: ready +announce ready $d + diff --git a/doc/examples/daemon-dependencies/init.c b/doc/examples/daemon-dependencies/init.c new file mode 100644 index 0000000..b7182c6 --- /dev/null +++ b/doc/examples/daemon-dependencies/init.c @@ -0,0 +1,127 @@ +#include <bus.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/wait.h> + +#define t(stmt) if (stmt) goto fail + + +static char msg[BUS_MEMORY_SIZE]; +static int argc; +static char **argv; +static char arg[4098]; + + +static void +start_daemons() +{ + int i; + for (i = 1; i < argc; i++) + if (fork() == 0) + execl("./start-daemon", "./start-daemon", argv[i], NULL); +} + + +static int +callback(const char *message, void *user_data) +{ + pid_t pid; + char *arg2; + char *arg3; + if (!message) { + pid = fork(); + t(pid == -1); + if (pid == 0) { + if (fork() == 0) { + start_daemons(); + } + exit(0); + } else { + (void) waitpid(pid, NULL, 0); /* Let's pretend everything will go swimmingly. */ + } + return 1; + } + + strncpy(msg, message, BUS_MEMORY_SIZE - 1); + msg[BUS_MEMORY_SIZE - 1] = 0; + + pid = fork(); + t(pid == -1); + + if (pid == 0) { + if (fork() == 0) { + arg2 = strchr(msg, ' '); + if (arg2 == NULL) + exit(0); + arg3 = strchr(++arg2, ' '); + if (arg3 == NULL) + exit(0); + *arg3++ = 0; + if (!strcmp(arg2, "require")) { + execl("./start-daemon", "./start-daemon", arg3, NULL); + } else if (!strcmp(arg2, "awaiting-started")) { + execl("./test-daemon", "./test-daemon", arg3, "started", NULL); + } else if (!strcmp(arg2, "awaiting-ready") || !strcmp(arg2, "awaiting")) { + execl("./test-daemon", "./test-daemon", arg3, "ready", NULL); + } else if (!strcmp(arg2, "started")) { + sprintf(arg, + "grep '^%s\\$' < \"${XDG_RUNTIME_DIR}/started-daemons\" >/dev/null || " + "echo %s >> \"${XDG_RUNTIME_DIR}/started-daemons\"", + arg3, arg3); + execlp("sh", "sh", "-c", arg, NULL); + } else if (!strcmp(arg2, "ready")) { + sprintf(arg, + "grep '^%s\\$' < \"${XDG_RUNTIME_DIR}/ready-daemons\" >/dev/null || " + "echo %s >> \"${XDG_RUNTIME_DIR}/ready-daemons\"", + arg3, arg3); + execlp("sh", "sh", "-c", arg, NULL); + } + } + exit(0); + } else { + (void) waitpid(pid, NULL, 0); /* Let's pretend everything will go swimmingly. */ + } + + return 1; + (void) user_data; + +fail: + perror("init"); + return -1; +} + + +int +main(int argc_, char *argv_[]) +{ + char *bus_address = NULL; + bus_t bus; + argv = argv_; + argc = argc_; + if (argc < 2) { + fprintf(stderr, "USAGE: %s daemon...\n", *argv); + return 1; + } + t(setenv("XDG_RUNTIME_DIR", "./run", 1)); /* Real init systems with not have the period. */ + system("mkdir -p -- \"${XDG_RUNTIME_DIR}\""); + system("truncate -s 0 -- \"${XDG_RUNTIME_DIR}/started-daemons\""); + system("truncate -s 0 -- \"${XDG_RUNTIME_DIR}/ready-daemons\""); + t(bus_create(NULL, 1, &bus_address)); + fprintf(stderr, "\033[00;01;31mexport BUS_INIT=%s\033[00m\n", bus_address); + fprintf(stderr, "\033[00;31mexport XDG_RUNTIME_DIR=./run\033[00m\n"); + t(setenv("BUS_INIT", bus_address, 1)); + t(bus_open(&bus, bus_address, BUS_RDONLY)); + t(bus_read(&bus, callback, NULL)); + bus_close(&bus); + free(bus_address); + return 0; + +fail: + perror("init"); + bus_close(&bus); + free(bus_address); + return 1; +} + diff --git a/doc/examples/daemon-dependencies/require.c b/doc/examples/daemon-dependencies/require.c new file mode 100644 index 0000000..e378431 --- /dev/null +++ b/doc/examples/daemon-dependencies/require.c @@ -0,0 +1,38 @@ +#include <bus.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> + +#define t(stmt) if (stmt) goto fail + + +static char arg[4098]; + + +int +main(int argc, char *argv[]) +{ + bus_t bus; + int i; + if (argc < 2) + return fprintf(stderr, "USAGE: %s daemon...", *argv), 2; + t(bus_open(&bus, getenv("BUS_INIT"), BUS_WRONLY)); + + for (i = 1; i < argc; i++) { + sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/started-daemons\" >/dev/null", argv[i]); + if (WEXITSTATUS(system(arg))) { + sprintf(arg, "%ji require %s", (intmax_t)getppid(), argv[i]); + t(bus_write(&bus, arg, 0)); + } + } + + bus_close(&bus); + return 0; + +fail: + perror("require"); + bus_close(&bus); + return 1; +} + diff --git a/doc/examples/daemon-dependencies/start-daemon.c b/doc/examples/daemon-dependencies/start-daemon.c new file mode 100644 index 0000000..7c224d5 --- /dev/null +++ b/doc/examples/daemon-dependencies/start-daemon.c @@ -0,0 +1,32 @@ +#include <bus.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define t(stmt) if (stmt) goto fail + + +static char arg[4098]; + + +int +main(int argc, char *argv[]) +{ + if (argc != 2) + return fprintf(stderr, "This program should be called from ./init\n"), 2; + + sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/started-daemons\" >/dev/null", argv[1]); + if (!WEXITSTATUS(system(arg))) + return 0; + sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/ready-daemons\" >/dev/null", argv[1]); + if (!WEXITSTATUS(system(arg))) + return 0; + + sprintf(arg, "./%s", argv[1]); + execlp(arg, arg, NULL); + perror("start-daemon"); + return 1; +} + diff --git a/doc/examples/daemon-dependencies/test-daemon.c b/doc/examples/daemon-dependencies/test-daemon.c new file mode 100644 index 0000000..32ee545 --- /dev/null +++ b/doc/examples/daemon-dependencies/test-daemon.c @@ -0,0 +1,35 @@ +#include <bus.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define t(stmt) if (stmt) goto fail + + +static char arg[4098]; + + +int +main(int argc, char *argv[]) +{ + bus_t bus; + if (argc != 3) + return fprintf(stderr, "This program should be called from ./init\n"), 2; +retry: + sprintf(arg, "grep '^%s$' < \"${XDG_RUNTIME_DIR}/%s-daemons\" >/dev/null", argv[1], argv[2]); + if (!WEXITSTATUS(system(arg))) { + t(bus_open(&bus, getenv("BUS_INIT"), BUS_WRONLY)); + sprintf(arg, "0 %s %s", argv[2], argv[1]); + t(bus_write(&bus, arg, 0)); + bus_close(&bus); + } else if (!strcmp(argv[2], "started")) { + argv[2] = "ready"; + goto retry; + } + return 0; + +fail: + perror("test-daemon"); + return 1; +} + |