From ce98d70d2b89347a4f6309f582ba03d898fee3fc Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Thu, 16 Apr 2015 05:47:40 +0200 Subject: misc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 6 ++--- src/bus.c | 50 +++++++++++++++++++++++----------- src/cmdline.c | 86 ++++++++++++++++++++++++++++++++++++----------------------- 3 files changed, 91 insertions(+), 51 deletions(-) diff --git a/Makefile b/Makefile index fa12410..94b203e 100644 --- a/Makefile +++ b/Makefile @@ -5,15 +5,15 @@ all: bus bus: bin/bus -bin/bus: obj/cmdline.o +bin/bus: obj/cmdline.o obj/bus.o @echo CC -o $@ @mkdir -p bin @${CC} -o $@ $^ ${LDFLAGS} -obj/%.o: src/%.c +obj/%.o: src/%.c src/*.h @echo CC -c $< @mkdir -p obj - @${CC} -c -o $@ ${CPPFLAGS} ${CFLAGS} $< + @${CC} -Wall -Wextra -pedantic -c -o $@ ${CPPFLAGS} ${CFLAGS} $< clean: @echo cleaning diff --git a/src/bus.c b/src/bus.c index 7f05560..5965a14 100644 --- a/src/bus.c +++ b/src/bus.c @@ -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 +#include +#include + #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: + * create [] # create a bus + * remove # remove a bus + * listen # listen for new messages + * wait # listen for one new message + * broadcast # broadcast a message + * 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 - -- cgit v1.2.3-70-g09d2