diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bus.c | 50 | ||||
-rw-r--r-- | src/cmdline.c | 86 |
2 files changed, 88 insertions, 48 deletions
@@ -180,8 +180,8 @@ create_semaphores(bus_t *bus) fail: saved_errno = errno; - if ((id != -1) && (semctl(id, 0, IPC_RMID) == -1)) - perror(argv0); + if (id != -1) + semctl(id, 0, IPC_RMID); free(values.array); errno = saved_errno; return -1; @@ -221,8 +221,8 @@ create_shared_memory(bus_t *bus) fail: saved_errno = errno; - if ((id != -1) && (shmctl(id, IPC_RMID, &_info) == -1)) - perror(argv0); + if (id != -1) + shmctl(id, IPC_RMID, &_info); errno = saved_errno; return -1; } @@ -253,7 +253,7 @@ remove_shared_memory(const bus_t *bus) { struct shmid_ds _info; int id = shmget(bus->key_shm, BUS_MEMORY_SIZE, 0600); - return ((id == -1) || (shmctl(sem_id, IPC_RMID, &_info) == -1)) ? -1 : 0; + return ((id == -1) || (shmctl(id, IPC_RMID, &_info) == -1)) ? -1 : 0; } @@ -302,7 +302,7 @@ write_semaphore(const bus_t *bus, unsigned short semaphore, int value) * @return 0 on success, -1 on error */ static int -open_shared_memory(const bus_t *bus, int flags) +open_shared_memory(bus_t *bus, int flags) { int id; void *address; @@ -310,7 +310,7 @@ open_shared_memory(const bus_t *bus, int flags) address = shmat(id, NULL, (flags & BUS_RDONLY) ? SHM_RDONLY : 0); if ((address == (void *)-1) || !address) goto fail; - this->message = (char *)address; + bus->message = (char *)address; return 0; fail: return -1; @@ -324,10 +324,10 @@ fail: * @return 0 on success, -1 on error */ static int -close_shared_memory(const bus_t *bus) +close_shared_memory(bus_t *bus) { - t(shmdt(this->message)); - this->message = NULL; + t(shmdt(bus->message)); + bus->message = NULL; return 0; fail: return -1; @@ -356,9 +356,11 @@ bus_create(const char *file, int flags) srand((unsigned int)time(NULL) + (unsigned int)rand()); + /* TODO */ (void) file; (void) flags; + t(create_semaphores(&bus)); t(create_shared_memory(&bus)); - return NULL; /* TODO */ + return NULL; fail: saved_errno = errno; @@ -417,12 +419,27 @@ fail: int bus_open(bus_t *bus, const char *file, int flags) { + int saved_errno; + char *line = NULL; + size_t len = 0; + FILE *f; + bus->sem_id = -1; bus->key_sem = -1; bus->key_shm = -1; bus->message = NULL; - /* TODO */ + f = fopen(file, "r"); + + t(getline(&line, &len, f)); + t(bus->key_sem = (key_t)atoll(line)); + free(line), line = NULL, len = 0; + + t(getline(&line, &len, f)); + t(bus->key_shm = (key_t)atoll(line)); + free(line), line = NULL; + + fclose(f); if (flags >= 0) { t(open_semaphores(bus)); @@ -430,6 +447,9 @@ bus_open(bus_t *bus, const char *file, int flags) } return 0; fail: + saved_errno = errno; + free(line); + errno = saved_errno; return -1; } @@ -444,9 +464,9 @@ int bus_close(bus_t *bus) { bus->sem_id = -1; - if (bus->address) + if (bus->message) t(close_shared_memory(bus)); - bus->address = NULL; + bus->message = NULL; return 0; fail: return -1; @@ -466,7 +486,7 @@ bus_write(const bus_t *bus, const char *message) { t(acquire_semaphore(bus, X, SEM_UNDO)); t(zero_semaphore(bus, W)); - t(write_shared_memory(bus, message)); + write_shared_memory(bus, message); t(write_semaphore(bus, Q, 0)); t(zero_semaphore(bus, S)); t(release_semaphore(bus, X, SEM_UNDO)); diff --git a/src/cmdline.c b/src/cmdline.c index d3b2a07..fbee2d6 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -21,48 +21,42 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + #include "bus.h" + /** * Statement wrapper that goes to `fail` on failure */ #define t(inst) if ((inst) == -1) goto fail -char *argv0; -static const char *command; - - -static int -get_keys(void) -{ - int saved_errno; - char *line; - size_t len; - line = NULL, len = 0; - t(getline(&line, &len, stdin)); - t(key_sem = (key_t)atoll(line)); - free(line); - - line = NULL, len = 0; - t(getline(&line, &len, stdin)); - t(key_shm = (key_t)atoll(line)); - free(line); +/** + * The name of the process + */ +char *argv0; - return 0; +/** + * The command to spawn when a message is received + */ +static const char *command; -fail: - saved_errno = errno; - free(line); - errno = saved_errno; - return -1; -} +/** + * Spawn a command because a message has been received + * + * @param message The received message + * @param user_data Not used + * @return 1 (continue listening) on success, -1 on error + */ static int -spawn_continue(const char *message) +spawn_continue(const char *message, void *user_data) { pid_t pid = fork(); if (pid) @@ -71,11 +65,19 @@ spawn_continue(const char *message) execlp("sh", "sh", "-c", command, NULL); perror(argv0); exit(1); + (void) user_data; } +/** + * Spawn a command because a message has been received + * + * @param message The received message + * @param user_data Not used + * @return 0 (stop listening) on success, -1 on error + */ static int -spawn_break(const char *message) +spawn_break(const char *message, void *user_data) { pid_t pid = fork(); if (pid) @@ -84,9 +86,24 @@ spawn_break(const char *message) execlp("sh", "sh", "-c", command, NULL); perror(argv0); exit(1); + (void) user_data; } + +/** + * Main function of the command line interface for the bus system + * + * @param argc The number of elements in `argv` + * @param argv The command. Valid commands: + * <argv0> create [<path>] # create a bus + * <argv0> remove <path> # remove a bus + * <argv0> listen <path> <command> # listen for new messages + * <argv0> wait <path> <command> # listen for one new message + * <argv0> broadcast <path> <message> # broadcast a message + * <command> will be spawned with $arg set to the message + * @return 0 on sucess, 1 on error, 2 on invalid command + */ int main(int argc, char *argv[]) { @@ -94,32 +111,38 @@ main(int argc, char *argv[]) argv0 = *argv; + /* Create a new bus with selected name. */ if ((argc == 3) && !strcmp(argv[1], "create")) { t(bus_create(argv[2], 0) ? 0 : -1); + /* Create a new bus with random name. */ } else if ((argc == 2) && !strcmp(argv[1], "create")) { - char *file = bus_create(NULL, 0); + const char *file = bus_create(NULL, 0); t(file ? 0 : -1); printf("%s\n", file); + /* Remove a bus. */ } else if ((argc == 3) && !strcmp(argv[1], "remove")) { t(bus_unlink(argv[2])); + /* Listen on a bus in a loop. */ } else if ((argc == 4) && !strcmp(argv[1], "listen")) { command = argv[3]; t(bus_open(&bus, argv[2], BUS_RDONLY)); t(bus_read(&bus, spawn_continue, NULL)); t(bus_close(&bus)); + /* Listen on a bus for one message. */ } else if ((argc == 4) && !strcmp(argv[1], "wait")) { command = argv[3]; t(bus_open(&bus, argv[2], BUS_RDONLY)); t(bus_read(&bus, spawn_break, NULL)); t(bus_close(&bus)); + /* Broadcast a message on a bus. */ } else if ((argc == 4) && !strcmp(argv[1], "broadcast")) { t(bus_open(&bus, argv[2], BUS_WRONLY)); - t(bus_write(&bus, argv[3])) + t(bus_write(&bus, argv[3])); t(bus_close(&bus)); } else @@ -132,6 +155,3 @@ fail: return 1; } - -#undef t - |