1 #include "external-transaction.h"
10 #include <ccan/tdb/tdb.h>
12 static volatile sig_atomic_t alarmed;
13 static void do_alarm(int signum)
18 static int do_transaction(const char *name)
20 TDB_DATA k = { .dptr = (void *)"a", .dsize = 1 };
21 TDB_DATA d = { .dptr = (void *)"b", .dsize = 1 };
22 struct tdb_context *tdb = tdb_open(name, 0, 0, O_RDWR, 0);
28 tdb_setalarm_sigptr(tdb, &alarmed);
31 if (tdb_transaction_start(tdb) != 0)
34 if (tdb_store(tdb, k, d, 0) != 0) {
35 tdb_transaction_cancel(tdb);
40 if (tdb_transaction_commit(tdb) == 0) {
55 int cmdfd, responsefd;
58 /* Do this before doing any tdb stuff. Return handle, or NULL. */
59 struct agent *prepare_external_agent(void)
62 int command[2], response[2];
63 struct sigaction act = { .sa_handler = do_alarm };
66 if (pipe(command) != 0 || pipe(response) != 0)
74 struct agent *agent = malloc(sizeof(*agent));
78 agent->cmdfd = command[1];
79 agent->responsefd = response[0];
85 sigaction(SIGALRM, &act, NULL);
87 while (read(command[0], name, sizeof(name)) != 0) {
88 int result = do_transaction(name);
89 if (write(response[1], &result, sizeof(result))
91 err(1, "Writing response");
96 /* Ask the external agent to try to do a transaction. */
97 bool external_agent_transaction(struct agent *agent, const char *tdbname)
101 if (write(agent->cmdfd, tdbname, strlen(tdbname)+1)
102 != strlen(tdbname)+1)
103 err(1, "Writing to agent");
105 if (read(agent->responsefd, &res, sizeof(res)) != sizeof(res))
106 err(1, "Reading from agent");
109 errx(1, "Agent returned %u\n", res);