aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--doc/bus_read.32
-rw-r--r--src/bus.c11
-rw-r--r--src/bus.h6
-rw-r--r--src/cmdline.c14
5 files changed, 29 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index 70b7132..9c92e3a 100644
--- a/Makefile
+++ b/Makefile
@@ -24,10 +24,10 @@ MAN7 = libbus
FLAGS = -std=c99 -Wall -Wextra -pedantic -O2
-LIB_MAJOR = 1
+LIB_MAJOR = 2
LIB_MINOR = 0
LIB_VERSION = ${LIB_MAJOR}.${LIB_MINOR}
-VERSION = 1.0.1
+VERSION = 2.0
all: bus doc
diff --git a/doc/bus_read.3 b/doc/bus_read.3
index 18bedc0..8f6ce88 100644
--- a/doc/bus_read.3
+++ b/doc/bus_read.3
@@ -6,7 +6,7 @@ bus_read - Listen for new messages a bus
int bus_read(const bus_t *bus, int (*callback)(const char *message, void *user_data), void *user_data);
.SH DESCRIPTION
-The \fIbus_read\fP function shall continuously wait for new message to be sent on the bus whose information is stored in \fIbus\fP. Once a message is received, the \fIcallback\fP function shall be invoked. \fImessage\fP should be the recieved message, and \fIuser_data\fP for \fIcallback\fP should be \fIuser_data\fP from \fIbus_read\fP.
+The \fIbus_read\fP function shall continuously wait for new message to be sent on the bus whose information is stored in \fIbus\fP. Once a message is received, the \fIcallback\fP function shall be invoked. \fImessage\fP should be the received message, and \fIuser_data\fP for \fIcallback\fP should be \fIuser_data\fP from \fIbus_read\fP. However, once \fIbus_read\fP has ensured that it will receive any message sent on the bus, it shall invoke the \fIcallback\fP function with \fImessage\fP set to \fINULL\fP, to notify the process that it can perform any action that requires that it is listening on the bus.
After \fIcallback\fP returns, \fImessage\fP may be override. Therefore \fIcallback\fP should copy \fImessage\fP and start a new thread that uses the copy of \fImessage\fP. \fIcallback\fP shall return -1 on failure, 0 if \fIbus_read\fP should stop listening or 1 if \fIbus_read\fP should continue listening.
.SH RETURN VALUES
diff --git a/src/bus.c b/src/bus.c
index 5875b2b..f4f62c2 100644
--- a/src/bus.c
+++ b/src/bus.c
@@ -629,6 +629,12 @@ fail:
* * 0: stop listening
* * 1: continue listening
* * -1: an error has occurred
+ * However, the function [`bus_read`] will invoke
+ * `callback` with `message` one time directly after
+ * it has started listening on the bus. This is to
+ * the the program now it can safely continue with
+ * any action that requires that the programs is
+ * listening on the port.
* @return 0 on success, -1 on error
*/
int
@@ -636,6 +642,11 @@ bus_read(const bus_t *bus, int (*callback)(const char *message, void *user_data)
{
int r;
t(release_semaphore(bus, S, SEM_UNDO));
+ t(r = callback(NULL, user_data));
+ if (!r) {
+ t(acquire_semaphore(bus, S, SEM_UNDO));
+ return 0;
+ }
for (;;) {
t(release_semaphore(bus, Q, 0));
t(zero_semaphore(bus, Q));
diff --git a/src/bus.h b/src/bus.h
index 267cac9..abae46b 100644
--- a/src/bus.h
+++ b/src/bus.h
@@ -162,6 +162,12 @@ int bus_write(const bus_t *bus, const char *message);
* * 0: stop listening
* * 1: continue listening
* * -1: an error has occurred
+ * However, the function [`bus_read`] will invoke
+ * `callback` with `message` one time directly after
+ * it has started listening on the bus. This is to
+ * the the program now it can safely continue with
+ * any action that requires that the programs is
+ * listening on the port.
* @return 0 on success, -1 on error
*/
int bus_read(const bus_t *bus, int (*callback)(const char *message, void *user_data), void *user_data);
diff --git a/src/cmdline.c b/src/cmdline.c
index 40d0136..f9505cc 100644
--- a/src/cmdline.c
+++ b/src/cmdline.c
@@ -59,8 +59,10 @@ static const char *command;
static int
spawn_continue(const char *message, void *user_data)
{
- pid_t pid = fork();
- if (pid)
+ pid_t pid;
+ if (!message)
+ return 1;
+ if ((pid = fork()))
return pid == -1 ? -1 : 1;
setenv("arg", message, 1);
execlp("sh", "sh", "-c", command, NULL);
@@ -75,13 +77,15 @@ spawn_continue(const char *message, void *user_data)
*
* @param message The received message
* @param user_data Not used
- * @return 0 (stop listening) on success, -1 on error
+ * @return 0 (stop listening) on success, -1 on error, or 1 if `message` is `NULL`
*/
static int
spawn_break(const char *message, void *user_data)
{
- pid_t pid = fork();
- if (pid)
+ pid_t pid;
+ if (!message)
+ return 1;
+ if (pid = fork())
return pid == -1 ? -1 : 0;
setenv("arg", message, 1);
execlp("sh", "sh", "-c", command, NULL);