diff --git a/server.c b/server.c index 0cc5e28..880ab3c 100644 --- a/server.c +++ b/server.c @@ -33,7 +33,8 @@ uint64_t hashmap_hash(const char *bytes, size_t bytes_n, size_t map_len) void bus_free(bus_t *s) { if (!s) return; - if (s->sock_fd) close(s->sock_fd); + if (s->sock_fd >= 0) close(s->sock_fd); + if (s->urandom_fd >= 0) close(s->urandom_fd); // freeing all clients will also free all matches and names for (int i = 0; i < BUS_MAX_CLIENTS; i++) { bus_client_remove(s, i); @@ -48,10 +49,17 @@ bus_t *bus_create(const char *socket_path) return NULL; } + s->urandom_fd = -1; + s->sock_fd = -1; + + s->urandom_fd = open("/dev/urandom", 0); + if (s->urandom_fd < 0) { + goto defer_fail; + } + s->sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (s->sock_fd == -1) { - free(s); - return NULL; + goto defer_fail; } struct sockaddr_un name; @@ -61,15 +69,19 @@ bus_t *bus_create(const char *socket_path) unlink(socket_path); + int flags = fcntl(s->sock_fd, F_GETFL, 0); + if (flags < 0) { + goto defer_fail; + } + if (fcntl(s->sock_fd, F_SETFL, flags | O_NONBLOCK) < 0) { + goto defer_fail; + } + if (bind(s->sock_fd, (const struct sockaddr *)&name, sizeof(name)) == -1) { - close(s->sock_fd); - free(s); - return NULL; + goto defer_fail; } if (listen(s->sock_fd, BUS_BACKLOG) == -1) { - close(s->sock_fd); - free(s); - return NULL; + goto defer_fail; } for (int i = 0; i < BUS_MAX_CLIENTS; i++) { @@ -100,6 +112,13 @@ bus_t *bus_create(const char *socket_path) s->fd_num = BUS_MAX_CLIENTS + 1; return s; +defer_fail: + if (s) { + if (s->urandom_fd >= 0) close(s->urandom_fd); + if (s->sock_fd >= 0) close(s->sock_fd); + free(s); + } + return NULL; } int bus_client_add(bus_t *s, int fd) @@ -198,14 +217,10 @@ int bus_client_assign_unique_name(bus_t *s, int i) return -1; } uint32_t id = 0; - FILE *urandom_file = fopen("/dev/urandom", "rb"); - if (!urandom_file) { + + if (read(s->urandom_fd, &id, sizeof(uint32_t)) != sizeof(uint32_t)) { return -1; } - if (fread(&id, 1, sizeof(uint32_t), urandom_file) != sizeof(uint32_t)) { - return -1; - } - fclose(urandom_file); char *name = malloc(sizeof(char) * 16); if (!name) { diff --git a/server.h b/server.h index 3d45b21..cae57f1 100644 --- a/server.h +++ b/server.h @@ -49,6 +49,7 @@ typedef struct bus { int fd_num; int names_count; int clients_count; + int urandom_fd; bus_client_t clients[BUS_MAX_CLIENTS]; bus_name_t names[BUS_MAX_NAMES]; struct pollfd fds[BUS_MAX_CLIENTS + 1];