diff options
Diffstat (limited to 'src')
47 files changed, 1104 insertions, 995 deletions
diff --git a/src/libmdsserver/client-list.c b/src/libmdsserver/client-list.c index 66fc2ae..24403cb 100644 --- a/src/libmdsserver/client-list.c +++ b/src/libmdsserver/client-list.c @@ -70,10 +70,11 @@ int client_list_create(client_list_t* restrict this, size_t capacity) this->capacity = capacity = to_power_of_two(capacity); this->size = 0; this->clients = NULL; - if (xmalloc(this->clients, capacity, uint64_t)) - return -1; + fail_if (xmalloc(this->clients, capacity, uint64_t)); return 0; + fail: + return -1; } @@ -101,11 +102,11 @@ int client_list_clone(const client_list_t* restrict this, client_list_t* restric { size_t n = this->capacity * sizeof(uint64_t); uint64_t* restrict new_clients = NULL; + int saved_errno; out->clients = NULL; - if ((new_clients = malloc(n)) == NULL) - goto fail; + fail_if ((new_clients = malloc(n)) == NULL); out->clients = new_clients; @@ -117,8 +118,9 @@ int client_list_clone(const client_list_t* restrict this, client_list_t* restric return 0; fail: + saved_errno = errno; free(new_clients); - return -1; + return errno = saved_errno, -1; } @@ -138,12 +140,14 @@ int client_list_add(client_list_t* restrict this, uint64_t client) { this->capacity >>= 1; this->clients = old; - return -1; + fail_if (1); } } this->clients[this->size++] = client; return 0; + fail: + return -1; } @@ -229,13 +233,14 @@ int client_list_unmarshal(client_list_t* restrict this, char* restrict data) n = this->capacity * sizeof(uint64_t); - if ((this->clients = malloc(n)) == NULL) - return -1; + fail_if ((this->clients = malloc(n)) == NULL); n = this->size * sizeof(uint64_t); memcpy(this->clients, data, n); return 0; + fail: + return -1; } diff --git a/src/libmdsserver/fd-table.c b/src/libmdsserver/fd-table.c index 960b3e4..4623825 100644 --- a/src/libmdsserver/fd-table.c +++ b/src/libmdsserver/fd-table.c @@ -48,10 +48,12 @@ int fd_table_create_tuned(fd_table_t* restrict this, size_t initial_capacity) the time overhead of `fd_table_contains_value`. */ bitcap = (this->capacity + 63) / 64; - if (xcalloc(this->used, bitcap, size_t)) return -1; - if (xcalloc(this->values, this->capacity, size_t)) return -1; + fail_if (xcalloc(this->used, bitcap, size_t)); + fail_if (xcalloc(this->values, this->capacity, size_t)); return 0; + fail: + return -1; } @@ -164,7 +166,7 @@ size_t fd_table_put(fd_table_t* restrict this, int key, size_t value) if (xrealloc(this->values, this->capacity << 1, size_t)) { this->values = old_values; - return 0; + fail_if (1); } memset(this->values + this->capacity, 0, this->capacity * sizeof(size_t)); @@ -180,7 +182,7 @@ size_t fd_table_put(fd_table_t* restrict this, int key, size_t value) { this->used = old_used; this->capacity >>= 1; - return 0; + fail_if (1); } memset(this->used + old_bitcap, 0, (new_bitcap - old_bitcap) * sizeof(uint64_t)); @@ -192,6 +194,8 @@ size_t fd_table_put(fd_table_t* restrict this, int key, size_t value) this->values[key] = value; this->size++; return 0; + fail: + return 0; } @@ -285,12 +289,10 @@ int fd_table_unmarshal(fd_table_t* restrict this, char* restrict data, remap_fun this->used = NULL; this->value_comparator = NULL; - if (xmalloc(this->values, this->capacity, size_t)) - return -1; + fail_if (xmalloc(this->values, this->capacity, size_t)); bitcap = (this->capacity + 63) / 64; - if (xmalloc(this->used, bitcap, size_t)) - return -1; + fail_if (xmalloc(this->used, bitcap, size_t)); memcpy(this->values, data, this->capacity * sizeof(size_t)); buf_next(data, size_t, this->capacity); @@ -306,5 +308,7 @@ int fd_table_unmarshal(fd_table_t* restrict this, char* restrict data, remap_fun } return 0; + fail: + return -1; } diff --git a/src/libmdsserver/hash-table.c b/src/libmdsserver/hash-table.c index c0de355..c9b2f4d 100644 --- a/src/libmdsserver/hash-table.c +++ b/src/libmdsserver/hash-table.c @@ -65,7 +65,7 @@ static inline size_t __attribute__((pure)) truncate_hash(const hash_table_t* res * Grow the table * * @param this The hash table - * @return Non zero on error, `errno` will be set accordingly + * @return Non-zero on error, `errno` will be set accordingly */ static int rehash(hash_table_t* restrict this) { @@ -76,8 +76,7 @@ static int rehash(hash_table_t* restrict this) hash_entry_t* destination; hash_entry_t* next; - if (xcalloc(this->buckets, old_capacity * 2 + 1, hash_entry_t*)) - return -1; + fail_if (xcalloc(this->buckets, old_capacity * 2 + 1, hash_entry_t*)); this->capacity = old_capacity * 2 + 1; this->threshold = (size_t)((float)(this->capacity) * this->load_factor); @@ -108,6 +107,8 @@ static int rehash(hash_table_t* restrict this) free(old_buckets); return 0; + fail: + return -1; } @@ -124,8 +125,7 @@ int hash_table_create_fine_tuned(hash_table_t* restrict this, size_t initial_cap this->buckets = NULL; this->capacity = initial_capacity ? initial_capacity : 1; - if (xcalloc(this->buckets, this->capacity, hash_entry_t*)) - return -1; + fail_if (xcalloc(this->buckets, this->capacity, hash_entry_t*)); this->load_factor = load_factor; this->threshold = (size_t)((float)(this->capacity) * load_factor); this->size = 0; @@ -134,6 +134,8 @@ int hash_table_create_fine_tuned(hash_table_t* restrict this, size_t initial_cap this->hasher = NULL; return 0; + fail: + return -1; } @@ -299,14 +301,12 @@ size_t hash_table_put(hash_table_t* restrict this, size_t key, size_t value) if (++(this->size) > this->threshold) { errno = 0; - if (rehash(this)) - return 0; + fail_if (rehash(this)); index = truncate_hash(this, key_hash); } errno = 0; - if (xmalloc(bucket, 1, hash_entry_t)) - return 0; + fail_if (xmalloc(bucket, 1, hash_entry_t)); bucket->value = value; bucket->key = key; bucket->hash = key_hash; @@ -314,6 +314,8 @@ size_t hash_table_put(hash_table_t* restrict this, size_t key, size_t value) this->buckets[index] = bucket; return 0; + fail: + return 0; } @@ -472,8 +474,7 @@ int hash_table_unmarshal(hash_table_t* restrict this, char* restrict data, remap buf_get_next(data, size_t, this->threshold); buf_get_next(data, size_t, this->size); - if (xcalloc(this->buckets, this->capacity, hash_entry_t*)) - return -1; + fail_if (xcalloc(this->buckets, this->capacity, hash_entry_t*)); for (i = 0; i < n; i++) { @@ -481,16 +482,14 @@ int hash_table_unmarshal(hash_table_t* restrict this, char* restrict data, remap hash_entry_t* restrict bucket; buf_get_next(data, size_t, m); - if (xmalloc(this->buckets[i] = bucket, 1, hash_entry_t)) - return -1; + fail_if (xmalloc(this->buckets[i] = bucket, 1, hash_entry_t)); while (m--) { if (m == 0) bucket->next = NULL; else - if (xmalloc(bucket->next, 1, hash_entry_t)) - return -1; + fail_if (xmalloc(bucket->next, 1, hash_entry_t)); buf_get_next(data, size_t, bucket->key); buf_get_next(data, size_t, bucket->value); if (remapper != NULL) @@ -500,5 +499,7 @@ int hash_table_unmarshal(hash_table_t* restrict this, char* restrict data, remap } return 0; + fail: + return -1; } diff --git a/src/libmdsserver/linked-list.c b/src/libmdsserver/linked-list.c index 6c8e185..f00daf3 100644 --- a/src/libmdsserver/linked-list.c +++ b/src/libmdsserver/linked-list.c @@ -75,15 +75,17 @@ int linked_list_create(linked_list_t* restrict this, size_t capacity) this->values = NULL; this->next = NULL; this->previous = NULL; - if (xmalloc(this->reusable, capacity, ssize_t)) return -1; - if (xmalloc(this->values, capacity, size_t)) return -1; - if (xmalloc(this->next, capacity, ssize_t)) return -1; - if (xmalloc(this->previous, capacity, ssize_t)) return -1; + fail_if (xmalloc(this->reusable, capacity, ssize_t)); + fail_if (xmalloc(this->values, capacity, size_t)); + fail_if (xmalloc(this->next, capacity, ssize_t)); + fail_if (xmalloc(this->previous, capacity, ssize_t)); this->values[this->edge] = 0; this->next[this->edge] = this->edge; this->previous[this->edge] = this->edge; return 0; + fail: + return -1; } @@ -95,10 +97,10 @@ int linked_list_create(linked_list_t* restrict this, size_t capacity) */ void linked_list_destroy(linked_list_t* restrict this) { - free(this->reusable); this->reusable = NULL; - free(this->values); this->values = NULL; - free(this->next); this->next = NULL; - free(this->previous); this->previous = NULL; + free(this->reusable), this->reusable = NULL; + free(this->values), this->values = NULL; + free(this->next), this->next = NULL; + free(this->previous), this->previous = NULL; } @@ -116,16 +118,17 @@ int linked_list_clone(const linked_list_t* restrict this, linked_list_t* restric ssize_t* restrict new_next = NULL; ssize_t* restrict new_previous = NULL; ssize_t* restrict new_reusable; + int saved_errno; out->values = NULL; out->next = NULL; out->previous = NULL; out->reusable = NULL; - if ((new_values = malloc(n)) == NULL) goto fail; - if ((new_next = malloc(n)) == NULL) goto fail; - if ((new_previous = malloc(n)) == NULL) goto fail; - if ((new_reusable = malloc(n)) == NULL) goto fail; + fail_if ((new_values = malloc(n)) == NULL); + fail_if ((new_next = malloc(n)) == NULL); + fail_if ((new_previous = malloc(n)) == NULL); + fail_if ((new_reusable = malloc(n)) == NULL); out->values = new_values; out->next = new_next; @@ -145,10 +148,11 @@ int linked_list_clone(const linked_list_t* restrict this, linked_list_t* restric return 0; fail: + saved_errno = errno; free(new_values); free(new_next); free(new_previous); - return -1; + return errno = saved_errno, -1; } @@ -177,9 +181,9 @@ int linked_list_pack(linked_list_t* restrict this) size_t i = 0; ssize_t node; size_t* restrict vals; + int saved_errno; - if (xmalloc(vals, cap, size_t)) - return -1; + fail_if (xmalloc(vals, cap, size_t)); while (((size_t)head != this->end) && (this->next[head] == LINKED_LIST_UNUSED)) head++; if ((size_t)head != this->end) @@ -191,9 +195,9 @@ int linked_list_pack(linked_list_t* restrict this) if (cap != this->capacity) { - if (xmalloc(new_next, cap, ssize_t)) goto fail; - if (xmalloc(new_previous, cap, ssize_t)) goto fail; - if (xmalloc(new_reusable, cap, ssize_t)) goto fail; + fail_if (xmalloc(new_next, cap, ssize_t)); + fail_if (xmalloc(new_previous, cap, ssize_t)); + fail_if (xmalloc(new_reusable, cap, ssize_t)); free(this->next); free(this->previous); @@ -219,10 +223,11 @@ int linked_list_pack(linked_list_t* restrict this) return 0; fail: + saved_errno = errno; free(vals); free(new_next); free(new_previous); - return -1; + return errno = saved_errno, -1; } @@ -245,10 +250,7 @@ static ssize_t linked_list_get_next(linked_list_t* restrict this) ssize_t* old; if ((ssize_t)(this->end) < 0) - { - errno = ENOMEM; - return LINKED_LIST_UNUSED; - } + fail_if ((errno = ENOMEM)); this->capacity <<= 1; @@ -256,7 +258,7 @@ static ssize_t linked_list_get_next(linked_list_t* restrict this) if ((new_var = realloc(old_var = new_var, this->capacity * sizeof(type))) == NULL) \ { \ new_var = old_var; \ - return LINKED_LIST_UNUSED; \ + fail_if (1); \ } __realloc(this->values, old_values, size_t) @@ -267,6 +269,8 @@ static ssize_t linked_list_get_next(linked_list_t* restrict this) #undef __realloc } return (ssize_t)(this->end++); + fail: + return LINKED_LIST_UNUSED; } @@ -300,14 +304,15 @@ static ssize_t linked_list_unuse(linked_list_t* restrict this, ssize_t node) ssize_t linked_list_insert_after(linked_list_t* this, size_t value, ssize_t predecessor) { ssize_t node = linked_list_get_next(this); - if (node == LINKED_LIST_UNUSED) - return LINKED_LIST_UNUSED; + fail_if (node == LINKED_LIST_UNUSED); this->values[node] = value; this->next[node] = this->next[predecessor]; this->next[predecessor] = node; this->previous[node] = predecessor; this->previous[this->next[node]] = node; return node; + fail: + return LINKED_LIST_UNUSED; } @@ -339,14 +344,15 @@ ssize_t linked_list_remove_after(linked_list_t* restrict this, ssize_t predecess ssize_t linked_list_insert_before(linked_list_t* restrict this, size_t value, ssize_t successor) { ssize_t node = linked_list_get_next(this); - if (node == LINKED_LIST_UNUSED) - return LINKED_LIST_UNUSED; + fail_if (node == LINKED_LIST_UNUSED); this->values[node] = value; this->previous[node] = this->previous[successor]; this->previous[successor] = node; this->next[node] = successor; this->next[this->previous[node]] = node; return node; + fail: + return LINKED_LIST_UNUSED; } @@ -450,10 +456,10 @@ int linked_list_unmarshal(linked_list_t* restrict this, char* restrict data) n = this->capacity * sizeof(size_t); - if ((this->reusable = malloc(n)) == NULL) return -1; - if ((this->values = malloc(n)) == NULL) return -1; - if ((this->next = malloc(n)) == NULL) return -1; - if ((this->previous = malloc(n)) == NULL) return -1; + fail_if ((this->reusable = malloc(n)) == NULL); + fail_if ((this->values = malloc(n)) == NULL); + fail_if ((this->next = malloc(n)) == NULL); + fail_if ((this->previous = malloc(n)) == NULL); memcpy(this->reusable, data, this->reuse_head * sizeof(ssize_t)); buf_next(data, ssize_t, this->reuse_head); @@ -467,6 +473,8 @@ int linked_list_unmarshal(linked_list_t* restrict this, char* restrict data) memcpy(this->previous, data, this->end * sizeof(ssize_t)); return 0; + fail: + return -1; } diff --git a/src/libmdsserver/macros.h b/src/libmdsserver/macros.h index 6c8f944..b72fd0a 100644 --- a/src/libmdsserver/macros.h +++ b/src/libmdsserver/macros.h @@ -399,11 +399,21 @@ /** - * Go to the label `pfail` if a condition is met + * Go to the label `fail` if a condition is met * * @param ... The condition */ -#define fail_if(...) if (__VA_ARGS__) goto pfail +#define fail_if(...) \ + do \ + if (__VA_ARGS__) \ + { \ + int _fail_if_saved_errno = errno; \ + if ((errno != EMSGSIZE) && (errno != ECONNRESET) && (errno != EINTR)) \ + fprintf(stderr, "failure at %s:%i\n", __FILE__, __LINE__); \ + errno = _fail_if_saved_errno; \ + goto fail; \ + } \ + while (0) /** @@ -412,7 +422,7 @@ * @param condition The condition * @param instructions The instruction (semicolon-terminated) */ -#define exit_if(condition, instructions) if (condition) { instructions return 1; } +#define exit_if(condition, instructions) do { if (condition) { instructions return 1; } } while (0) /** diff --git a/src/libmdsserver/mds-message.c b/src/libmdsserver/mds-message.c index 37ebf85..5007f23 100644 --- a/src/libmdsserver/mds-message.c +++ b/src/libmdsserver/mds-message.c @@ -48,9 +48,10 @@ int mds_message_initialise(mds_message_t* restrict this) this->buffer_size = 128; this->buffer_ptr = 0; this->stage = 0; - if (xmalloc(this->buffer, this->buffer_size, char)) - return -1; + fail_if (xmalloc(this->buffer, this->buffer_size, char)); return 0; + fail: + return -1; } @@ -100,10 +101,11 @@ void mds_message_destroy(mds_message_t* restrict this) int mds_message_extend_headers(mds_message_t* restrict this, size_t extent) { char** new_headers = this->headers; - if (xrealloc(new_headers, this->header_count + extent, char*)) - return -1; + fail_if (xrealloc(new_headers, this->header_count + extent, char*)); this->headers = new_headers; return 0; + fail: + return -1; } @@ -116,11 +118,12 @@ int mds_message_extend_headers(mds_message_t* restrict this, size_t extent) static int mds_message_extend_buffer(mds_message_t* restrict this) { char* new_buf = this->buffer; - if (xrealloc(new_buf, this->buffer_size << 1, char)) - return -1; + fail_if (xrealloc(new_buf, this->buffer_size << 1, char)); this->buffer = new_buf; this->buffer_size <<= 1; return 0; + fail: + return -1; } @@ -231,10 +234,11 @@ static int initialise_payload(mds_message_t* restrict this) /* Allocate the payload buffer. */ if (this->payload_size > 0) - if (xmalloc(this->payload, this->payload_size, char)) - return -1; + fail_if (xmalloc(this->payload, this->payload_size, char)); return 0; + fail: + return -1; } @@ -250,8 +254,7 @@ static int store_header(mds_message_t* restrict this, size_t length) char* header; /* Allocate the header. */ - if (xmalloc(header, length, char)) - return -1; + fail_if (xmalloc(header, length, char)); /* Copy the header data into the allocated header, */ memcpy(header, this->buffer, length * sizeof(char)); /* and NUL-terminate it. */ @@ -272,6 +275,8 @@ static int store_header(mds_message_t* restrict this, size_t length) this->headers[this->header_count++] = header; return 0; + fail: + return -1; } @@ -305,15 +310,13 @@ static int continue_read(mds_message_t* restrict this, int fd) errno = 0; got = recv(fd, this->buffer + this->buffer_ptr, n, 0); this->buffer_ptr += (size_t)(got < 0 ? 0 : got); - if (errno) - return -1; + fail_if (errno); if (got == 0) - { - errno = ECONNRESET; - return -1; - } + fail_if ((errno = ECONNRESET)); return 0; + fail: + return -1; } @@ -540,7 +543,7 @@ int mds_message_unmarshal(mds_message_t* restrict this, char* restrict data) return 0; - pfail: + fail: return -1; } diff --git a/src/libmdsserver/util.c b/src/libmdsserver/util.c index b1dff3c..123463c 100644 --- a/src/libmdsserver/util.c +++ b/src/libmdsserver/util.c @@ -103,11 +103,12 @@ int prepare_reexec(void) { ssize_t len; len = readlink(SELF_EXE, self_exe, (sizeof(self_exe) / sizeof(char)) - 1); - if (len < 0) - return -1; + fail_if (len < 0); /* ‘readlink() does not append a null byte to buf.’ */ self_exe[len] = '\0'; return 0; + fail: + return -1; } @@ -135,8 +136,7 @@ void reexec_server(int argc, char** argv, int reexeced) { *reexec_args_++ = *argv; *reexec_args_ = strdup("--re-exec"); - if (*reexec_args_ == NULL) - return; + fail_if (*reexec_args_ == NULL); for (i = 1; i < argc; i++) reexec_args_[i] = argv[i]; } @@ -146,6 +146,8 @@ void reexec_server(int argc, char** argv, int reexeced) reexec_args_[i] = argv[i]; reexec_args_[argc] = NULL; execv(self_exe[0] ? self_exe : argv[0], reexec_args); + fail: + return; } @@ -253,12 +255,13 @@ int full_write(int fd, const char* buffer, size_t length) { errno = 0; wrote = write(fd, buffer, length); - if (errno && (errno != EINTR)) - return -1; + fail_if (errno && (errno != EINTR)); length -= (size_t)max(wrote, 0); buffer += (size_t)max(wrote, 0); } return 0; + fail: + return -1; } @@ -271,38 +274,29 @@ int full_write(int fd, const char* buffer, size_t length) */ char* full_read(int fd, size_t* length) { + char* old_buf = NULL; size_t buffer_size = 8 << 10; size_t buffer_ptr = 0; char* buffer; ssize_t got; + int saved_errno; + if (length != NULL) *length = 0; /* Allocate buffer for data. */ - if (xmalloc(buffer, buffer_size, char)) - return NULL; + fail_if (xmalloc(buffer, buffer_size, char)); /* Read the file. */ for (;;) { /* Grow buffer if it is too small. */ if (buffer_size == buffer_ptr) - { - char* old_buf = buffer; - if (xrealloc(buffer, buffer_size <<= 1, char)) - { - free(old_buf); - return NULL; - } - } + fail_if (xxrealloc(old_buf, buffer, buffer_size <<= 1, char)); /* Read from the file into the buffer. */ got = read(fd, buffer + buffer_ptr, buffer_size - buffer_ptr); - if ((got < 0) && (errno != EINTR)) - { - free(buffer); - return NULL; - } + fail_if ((got < 0) && (errno != EINTR)); if (got == 0) break; buffer_ptr += (size_t)got; @@ -311,6 +305,11 @@ char* full_read(int fd, size_t* length) if (length != NULL) *length = buffer_ptr; return buffer; + fail: + saved_errno = errno; + free(old_buf); + free(buffer); + return errno = saved_errno, NULL; } @@ -360,8 +359,7 @@ pid_t uninterruptable_waitpid(pid_t pid, int* restrict status, int options) rc = waitpid(pid, status, options); if (rc == (pid_t)-1) { - if (errno != EINTR) - goto fail; + fail_if (errno != EINTR); if (have_time && (monotone(&time_intr) >= 0)) if (time_start.tv_sec != time_intr.tv_sec) intr_count = 0; diff --git a/src/mds-base.c b/src/mds-base.c index 5bce448..a9a942b 100644 --- a/src/mds-base.c +++ b/src/mds-base.c @@ -36,9 +36,6 @@ #include <fcntl.h> -#define try(INSTRUCTION) if ((r = INSTRUCTION)) goto fail - - /** * Number of elements in `argv` */ @@ -156,11 +153,9 @@ int __attribute__((weak)) parse_cmdline(void) /* Check that mandatory arguments have been specified. */ if (server_characteristics.require_respawn_info) - { - exit_if (is_respawn < 0, - eprintf("missing state argument, require either %s or %s.", - "--initial-spawn", "--respawn");); - } + exit_if (is_respawn < 0, + eprintf("missing state argument, require either %s or %s.", + "--initial-spawn", "--respawn");); return 0; } @@ -189,7 +184,7 @@ int __attribute__((weak)) connect_to_display(void) return 0; - pfail: + fail: xperror(*argv); if (socket_fd >= 0) close(socket_fd); @@ -210,13 +205,8 @@ static int server_initialised_fork_for_safety(void) pid_t pid = fork(); int status; - if (pid == (pid_t)-1) - { - xperror(*argv); - eprint("while forking for safety."); - return -1; - } - else if (pid == 0) + fail_if (pid == (pid_t)-1); + if (pid == 0) /* Reinstate the alarm for the child. */ alarm(pending_alarm); else @@ -246,6 +236,10 @@ static int server_initialised_fork_for_safety(void) } return 0; + fail: + xperror(*argv); + eprint("while forking for safety."); + return -1; } @@ -261,14 +255,8 @@ int __attribute__((weak)) server_initialised(void) pid_t r; if (on_init_fork && (r = fork())) { - if (r == (pid_t)-1) - { - xperror(*argv); - eprint("while forking at completed initialisation."); - return -1; - } - else - exit(0); + fail_if (r == (pid_t)-1); + exit(0); } if (on_init_sh != NULL) @@ -276,7 +264,12 @@ int __attribute__((weak)) server_initialised(void) if (server_characteristics.fork_for_safety) return server_initialised_fork_for_safety(); + return 0; + fail: + xperror(*argv); + eprint("while forking at completed initialisation."); + return -1; } @@ -413,11 +406,10 @@ static int base_unmarshal(void) free(state_buf); /* Recover after failure. */ - if (r) - fail_if (reexec_failure_recover()); + fail_if (r && reexec_failure_recover()); return 0; - pfail: + fail: xperror(*argv); return 1; } @@ -460,7 +452,7 @@ static int base_marshal(int reexec_fd) free(state_buf); return 0; - pfail: + fail: xperror(*argv); free(state_buf); return 1; @@ -482,24 +474,21 @@ static void perform_reexec(void) /* Marshal the state of the server. */ xsnprintf(shm_path, SHM_PATH_PATTERN, (unsigned long int)pid); reexec_fd = shm_open(shm_path, O_RDWR | O_CREAT | O_EXCL, S_IRWXU); - if (reexec_fd < 0) - { - xperror(*argv); - return; - } - if (base_marshal(reexec_fd) < 0) - goto fail; + fail_if (reexec_fd < 0); + fail_if (base_marshal(reexec_fd) < 0); close(reexec_fd); reexec_fd = -1; /* Re-exec the server. */ reexec_server(argc, argv, is_reexec); - xperror(*argv); fail: + xperror(*argv); if (reexec_fd >= 0) - close(reexec_fd); - shm_unlink(shm_path); + { + close(reexec_fd); + shm_unlink(shm_path); + } } @@ -512,15 +501,14 @@ static void perform_reexec(void) */ int main(int argc_, char** argv_) { - int r = 1; - argc = argc_; argv = argv_; if (server_characteristics.require_privileges == 0) /* Drop privileges like it's hot. */ - fail_if (drop_privileges()); + if (drop_privileges()) + fail_if (1); /* Use /proc/self/exe when re:exec-ing */ @@ -533,7 +521,7 @@ int main(int argc_, char** argv_) eprint("that number of arguments is ridiculous, I will not allow it.");); /* Parse command line arguments. */ - try (parse_cmdline()); + fail_if (parse_cmdline()); /* Store the current thread so it can be killed from elsewhere. */ @@ -544,49 +532,47 @@ int main(int argc_, char** argv_) /* Initialise the server. */ - try (preinitialise_server()); + fail_if (preinitialise_server()); if (is_reexec == 0) { if (server_characteristics.require_display) /* Connect to the display. */ - try (connect_to_display()); + fail_if (connect_to_display()); /* Initialise the server. */ - try (initialise_server()); + fail_if (initialise_server()); } else { /* Unmarshal the server's saved state. */ - try (base_unmarshal()); + fail_if (base_unmarshal()); } /* Initialise the server. */ - try (postinitialise_server()); + fail_if (postinitialise_server()); /* Run the server. */ - try (master_loop()); + fail_if (master_loop()); /* Re-exec server if signal to re-exec. */ if (reexecing) { perform_reexec(); - goto fail; + fail_if (1); } close(socket_fd); return 0; - pfail: - xperror(*argv); - r = 1; fail: + xperror(*argv); if (socket_fd >= 0) close(socket_fd); - return r; + return 1; } @@ -637,12 +623,12 @@ int trap_signals(void) /* Implement death on SIGDANGER or ignoral of SIGDANGER. */ if (server_characteristics.danger_is_deadly && !is_immortal) - { fail_if (xsigaction(SIGDANGER, commit_suicide) < 0); } + fail_if (xsigaction(SIGDANGER, commit_suicide) < 0); else - { fail_if (xsigaction(SIGDANGER, received_danger) < 0); } + fail_if (xsigaction(SIGDANGER, received_danger) < 0); return 0; - pfail: + fail: xperror(*argv); return 1; } @@ -665,6 +651,3 @@ void __attribute__((weak)) fork_cleanup(int status) fprintf(stderr, "Something is wrong, `fork_cleanup` has been called but not reimplemented."); } - -#undef try - diff --git a/src/mds-clipboard.c b/src/mds-clipboard.c index 1d4de37..50ee6a3 100644 --- a/src/mds-clipboard.c +++ b/src/mds-clipboard.c @@ -105,6 +105,7 @@ int __attribute__((const)) preinitialise_server(void) int initialise_server(void) { ssize_t i = 0; + int stage = 0; const char* const message = "Command: intercept\n" "Message ID: 0\n" @@ -113,8 +114,7 @@ int initialise_server(void) "Command: clipboard\n" "Client closed\n"; - if (full_send(message, strlen(message))) - return 1; + fail_if (full_send(message, strlen(message))); if (is_respawn) { @@ -124,13 +124,13 @@ int initialise_server(void) "Message ID: 1\n" "\n"; - if (full_send(crash_message, strlen(crash_message))) - return 1; - + fail_if (full_send(crash_message, strlen(crash_message))); message_id++; } + stage++; fail_if (server_initialised() < 0); + stage++; fail_if (mds_message_initialise(&received)); for (i = 0; i < CLIPBOARD_LEVELS; i++) @@ -138,10 +138,12 @@ int initialise_server(void) return 0; - pfail: + fail: xperror(*argv); + if (stage == 0) return 1; mds_message_destroy(&received); - while (--i >= 0) + if (stage == 1) return 1; + while (i--) free(clipboard[i]); return 1; } @@ -158,13 +160,12 @@ int postinitialise_server(void) if (connected) return 0; - if (reconnect_to_display()) - { - mds_message_destroy(&received); - return 1; - } + fail_if (reconnect_to_display()); connected = 1; return 0; + fail: + mds_message_destroy(&received); + return 1; } @@ -305,7 +306,7 @@ int unmarshal_server(char* state_buf) } return 0; - pfail: + fail: xperror(*argv); mds_message_destroy(&received); for (i = 0; i < CLIPBOARD_LEVELS; i++) @@ -357,27 +358,26 @@ int master_loop(void) if (r == -2) { eprint("corrupt message received, aborting."); - goto fail; + goto done; } else if (errno == EINTR) continue; - else if (errno != ECONNRESET) - goto pfail; + else + fail_if (errno != ECONNRESET); eprint("lost connection to server."); mds_message_destroy(&received); mds_message_initialise(&received); connected = 0; - if (reconnect_to_display()) - goto fail; + fail_if (reconnect_to_display()); connected = 1; } rc = 0; - goto fail; - pfail: - xperror(*argv); + goto done; fail: + xperror(*argv); + done: if (!rc && reexecing) return 0; mds_message_destroy(&received); @@ -411,15 +411,15 @@ int full_send(const char* message, size_t length) eprint("Sent more of a message than exists in the message, aborting."); return -1; } - else if ((sent < length) && (errno != EINTR)) - { - xperror(*argv); - return -1; - } + else + fail_if ((sent < length) && (errno != EINTR)); message += sent; length -= sent; } return 0; + fail: + xperror(*argv); + return -1; } @@ -576,8 +576,7 @@ static int clipboard_notify_pop(int level, size_t index) "Used: %zu\n" "\n"); - if (xmalloc(message, n, char)) - return -1; + fail_if (xmalloc(message, n, char)); sprintf(message, "Command: clipboard-info\n" @@ -592,6 +591,8 @@ static int clipboard_notify_pop(int level, size_t index) message_id = message_id == UINT32_MAX ? 0 : (message_id + 1); return full_send(message, strlen(message)) ? -1 : 0; + fail: + return -1; } @@ -637,7 +638,7 @@ static int clipboard_purge(int level, const char* client_id) } return 0; - pfail: + fail: xperror(*argv); return -1; } @@ -652,9 +653,10 @@ int clipboard_danger(void) { int i; for (i = 0; i < CLIPBOARD_LEVELS; i++) - if (clipboard_purge(i, NULL)) - return -1; + fail_if (clipboard_purge(i, NULL)); return 0; + fail: + return -1; } @@ -668,9 +670,10 @@ int clipboard_death(const char* recv_client_id) { int i; for (i = 0; i < CLIPBOARD_LEVELS; i++) - if (clipboard_purge(i, recv_client_id)) - return -1; + fail_if (clipboard_purge(i, recv_client_id)); return 0; + fail: + return -1; } @@ -688,8 +691,7 @@ int clipboard_add(int level, const char* time_to_live, const char* recv_client_i uint64_t client = recv_client_id ? parse_client_id(recv_client_id) : 0; clipitem_t new_clip; - if (clipboard_purge(level, NULL)) - return -1; + fail_if (clipboard_purge(level, NULL)); if (strequals(time_to_live, "forever")) autopurge = CLIPITEM_AUTOPURGE_NEVER; @@ -728,7 +730,7 @@ int clipboard_add(int level, const char* time_to_live, const char* recv_client_i clipboard[level][0] = new_clip; return 0; - pfail: + fail: xperror(*argv); return -1; } @@ -749,8 +751,7 @@ int clipboard_read(int level, size_t index, const char* recv_client_id, const ch clipitem_t* clip = NULL; size_t n; - if (clipboard_purge(level, NULL)) - return -1; + fail_if (clipboard_purge(level, NULL)); if (clipboard_used[level] == 0) { @@ -802,7 +803,7 @@ int clipboard_read(int level, size_t index, const char* recv_client_id, const ch free(message); return 0; - pfail: + fail: xperror(*argv); return -1; } @@ -834,8 +835,7 @@ int clipboard_clear(int level) int clipboard_set_size(int level, size_t size) { size_t i; - if (clipboard_purge(level, NULL)) - return -1; + fail_if (clipboard_purge(level, NULL)); if (size < clipboard_size[level]) { @@ -854,13 +854,13 @@ int clipboard_set_size(int level, size_t size) if (xrealloc(clipboard[level], size, clipitem_t)) { clipboard[level] = old; - goto pfail; + fail_if (1); } clipboard_size[level] = size; } return 0; - pfail: + fail: xperror(*argv); return -1; } @@ -878,8 +878,8 @@ int clipboard_get_size(int level, const char* recv_client_id, const char* recv_m { char* message = NULL; size_t n; - if (clipboard_purge(level, NULL)) - return -1; + + fail_if (clipboard_purge(level, NULL)); n = strlen("To: %s\n" "In response to: %s\n" @@ -905,7 +905,7 @@ int clipboard_get_size(int level, const char* recv_client_id, const char* recv_m free(message); return 0; - pfail: + fail: xperror(*argv); free(message); return -1; diff --git a/src/mds-echo.c b/src/mds-echo.c index 31e8b86..ab85c31 100644 --- a/src/mds-echo.c +++ b/src/mds-echo.c @@ -99,6 +99,7 @@ int __attribute__((const)) preinitialise_server(void) */ int initialise_server(void) { + int stage = 0; const char* const message = "Command: intercept\n" "Message ID: 0\n" @@ -106,15 +107,15 @@ int initialise_server(void) "\n" "Command: echo\n"; - if (full_send(message, strlen(message))) - return 1; - fail_if (server_initialised() < 0); + fail_if (full_send(message, strlen(message))); + fail_if (server_initialised() < 0); stage++; fail_if (mds_message_initialise(&received)); return 0; - pfail: + fail: xperror(*argv); - mds_message_destroy(&received); + if (stage == 1) + mds_message_destroy(&received); return 1; } @@ -130,13 +131,12 @@ int postinitialise_server(void) if (connected) return 0; - if (reconnect_to_display()) - { - mds_message_destroy(&received); - return 1; - } + fail_if (reconnect_to_display()); connected = 1; return 0; + fail: + mds_message_destroy(&received); + return 1; } @@ -184,18 +184,16 @@ int marshal_server(char* state_buf) */ int unmarshal_server(char* state_buf) { - int r; /* buf_get_next(state_buf, int, MDS_ECHO_VARS_VERSION); */ buf_next(state_buf, int, 1); buf_get_next(state_buf, int, connected); buf_get_next(state_buf, uint32_t, message_id); - r = mds_message_unmarshal(&received, state_buf); - if (r) - { - xperror(*argv); - mds_message_destroy(&received); - } - return r; + fail_if (mds_message_unmarshal(&received, state_buf)); + return 0; + fail: + xperror(*argv); + mds_message_destroy(&received); + return -1; } @@ -229,27 +227,26 @@ int master_loop(void) if (r == -2) { eprint("corrupt message received, aborting."); - goto fail; + goto done; } else if (errno == EINTR) continue; - else if (errno != ECONNRESET) - goto pfail; + else + fail_if (errno != ECONNRESET); eprint("lost connection to server."); mds_message_destroy(&received); mds_message_initialise(&received); connected = 0; - if (reconnect_to_display()) - goto fail; + fail_if (reconnect_to_display()); connected = 1; } rc = 0; - goto fail; - pfail: - xperror(*argv); + goto done; fail: + xperror(*argv); + done: if (rc || !reexecing) mds_message_destroy(&received); free(echo_buffer); @@ -265,10 +262,12 @@ int master_loop(void) */ int echo_message(void) { + char* old_buffer = NULL; const char* recv_client_id = NULL; const char* recv_message_id = NULL; const char* recv_length = NULL; size_t i, n; + int saved_errno; /* Fetch headers. */ @@ -312,14 +311,7 @@ int echo_message(void) n += strlen(recv_length) + 1; if ((echo_buffer_size < n) || (echo_buffer_size * 4 > n)) - { - char* old_buffer = echo_buffer; - if (xrealloc(echo_buffer, echo_buffer_size = n, char)) - { - free(old_buffer); - return -1; - } - } + fail_if (xxrealloc(old_buffer, echo_buffer, echo_buffer_size = n, char)); sprintf(echo_buffer, "To: %s\nIn response to: %s\nMessage ID: %" PRIu32 "\n%s%s\n", recv_client_id, recv_message_id, message_id, @@ -330,9 +322,12 @@ int echo_message(void) message_id = message_id == UINT32_MAX ? 0 : (message_id + 1); /* Send echo. */ - if (full_send(echo_buffer, strlen(echo_buffer))) - return 1; + fail_if (full_send(echo_buffer, strlen(echo_buffer))); return full_send(received.payload, received.payload_size); + fail: + saved_errno = errno; + free(old_buffer); + return errno = saved_errno, -1; } @@ -355,14 +350,14 @@ int full_send(const char* message, size_t length) eprint("Sent more of a message than exists in the message, aborting."); return -1; } - else if ((sent < length) && (errno != EINTR)) - { - xperror(*argv); - return -1; - } + else + fail_if ((sent < length) && (errno != EINTR)); message += sent; length -= sent; } return 0; + fail: + xperror(*argv); + return -1; } diff --git a/src/mds-kbdc/builtin-functions.c b/src/mds-kbdc/builtin-functions.c index fca6496..4ccc31f 100644 --- a/src/mds-kbdc/builtin-functions.c +++ b/src/mds-kbdc/builtin-functions.c @@ -19,6 +19,8 @@ #include "variables.h" +#include <libmdsserver/macros.h> + #include <stdlib.h> #include <string.h> @@ -34,8 +36,7 @@ size_t bn = string_length(b); \ size_t i, n = an > bn ? an : bn; \ char32_t* restrict rc = malloc((n + 1) * sizeof(char32_t)); \ - if (rc == NULL) \ - return NULL; \ + fail_if (rc == NULL); \ rc[n] = -1 /** @@ -45,10 +46,19 @@ const char32_t* restrict a = *args++; \ size_t i, n = string_length(a); \ char32_t* restrict rc = malloc((n + 1) * sizeof(char32_t)); \ - if (rc == NULL) \ - return NULL; \ + fail_if (rc == NULL); \ rc[n] = -1 +/** + * Return a value, or if there was a failure somewhere, return `NULL` + * + * @param v:void* The value to return on success + */ +#define return(v) \ + return v; \ + fail: \ + return NULL; + /** * Definition of the built-in function add/2 @@ -61,7 +71,7 @@ static char32_t* builtin_function_add_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] + b[i % bn]; - return rc; + return(rc); } @@ -76,7 +86,7 @@ static char32_t* builtin_function_sub_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] - b[i % bn]; - return rc; + return(rc); } @@ -91,7 +101,7 @@ static char32_t* builtin_function_mul_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] * b[i % bn]; - return rc; + return(rc); } @@ -106,7 +116,7 @@ static char32_t* builtin_function_div_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] / b[i % bn]; - return rc; + return(rc); } @@ -121,7 +131,7 @@ static char32_t* builtin_function_mod_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] % b[i % bn]; - return rc; + return(rc); } @@ -136,7 +146,7 @@ static char32_t* builtin_function_rsh_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] << b[i % bn]; - return rc; + return(rc); } @@ -151,7 +161,7 @@ static char32_t* builtin_function_lsh_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] >> b[i % bn]; - return rc; + return(rc); } @@ -166,7 +176,7 @@ static char32_t* builtin_function_or_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] | b[i % bn]; - return rc; + return(rc); } @@ -181,7 +191,7 @@ static char32_t* builtin_function_and_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] & b[i % bn]; - return rc; + return(rc); } @@ -196,7 +206,7 @@ static char32_t* builtin_function_xor_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] ^ b[i % bn]; - return rc; + return(rc); } @@ -211,7 +221,7 @@ static char32_t* builtin_function_not_1(const char32_t** restrict args) define_1; for (i = 0; i < n; i++) rc[i] = !a[i]; - return rc; + return(rc); } @@ -226,7 +236,7 @@ static char32_t* builtin_function_equals_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] == b[i % bn]; - return rc; + return(rc); } @@ -241,7 +251,7 @@ static char32_t* builtin_function_greater_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] > b[i % bn]; - return rc; + return(rc); } @@ -256,7 +266,7 @@ static char32_t* builtin_function_less_2(const char32_t** restrict args) define_2; for (i = 0; i < n; i++) rc[i] = a[i % an] < b[i % bn]; - return rc; + return(rc); } @@ -270,11 +280,13 @@ static char32_t* builtin_function_get_2(const char32_t** restrict args) { const char32_t* restrict a = *args++; const char32_t* restrict b = *args++; + char32_t* restrict rc; size_t n = (size_t)*b; mds_kbdc_tree_t* value = variables_get((size_t)*a); while (n--) value = value->next; - return string_dup(value->compiled_string.string); + fail_if (rc = string_dup(value->compiled_string.string), rc == NULL); + return(rc); } @@ -289,20 +301,22 @@ static char32_t* builtin_function_set_3(const char32_t** restrict args) const char32_t* restrict a = *args++; const char32_t* restrict b = *args++; const char32_t* restrict c = *args++; + char32_t* restrict rc; size_t n = (size_t)*b; mds_kbdc_tree_t* value = variables_get((size_t)*a); while (n--) value = value->next; free(value->compiled_string.string); value->compiled_string.string = string_dup(c); - if (value->compiled_string.string == NULL) - return NULL; - return string_dup(c); + fail_if (value->compiled_string.string == NULL); + fail_if (rc = string_dup(c), rc == NULL); + return(rc); } #undef define_1 #undef define_2 +#undef return /** @@ -350,32 +364,33 @@ int builtin_function_defined(const char* restrict name, size_t arg_count) */ char32_t* builtin_function_invoke(const char* restrict name, size_t arg_count, const char32_t** restrict args) { - if (arg_count == 3) - if (!strcmp(name, "set")) - return builtin_function_set_3(args); +#define t(f) do { fail_if (rc = builtin_function_##f(args), rc == NULL); return rc; } while (0) + char32_t* rc; - if (arg_count == 1) - if (!strcmp(name, "not")) - return builtin_function_not_1(args); + if ((arg_count == 3) && !strcmp(name, "set")) t (set_3); + if ((arg_count == 1) && !strcmp(name, "not")) t (not_1); if (arg_count != 2) abort(); - if (!strcmp(name, "add")) return builtin_function_add_2(args); - if (!strcmp(name, "sub")) return builtin_function_sub_2(args); - if (!strcmp(name, "mul")) return builtin_function_mul_2(args); - if (!strcmp(name, "div")) return builtin_function_div_2(args); - if (!strcmp(name, "mod")) return builtin_function_mod_2(args); - if (!strcmp(name, "rsh")) return builtin_function_rsh_2(args); - if (!strcmp(name, "lsh")) return builtin_function_lsh_2(args); - if (!strcmp(name, "or")) return builtin_function_or_2(args); - if (!strcmp(name, "and")) return builtin_function_and_2(args); - if (!strcmp(name, "xor")) return builtin_function_xor_2(args); - if (!strcmp(name, "equals")) return builtin_function_equals_2(args); - if (!strcmp(name, "greater")) return builtin_function_greater_2(args); - if (!strcmp(name, "less")) return builtin_function_less_2(args); - if (!strcmp(name, "get")) return builtin_function_get_2(args); + if (!strcmp(name, "add")) t (add_2); + if (!strcmp(name, "sub")) t (sub_2); + if (!strcmp(name, "mul")) t (mul_2); + if (!strcmp(name, "div")) t (div_2); + if (!strcmp(name, "mod")) t (mod_2); + if (!strcmp(name, "rsh")) t (rsh_2); + if (!strcmp(name, "lsh")) t (lsh_2); + if (!strcmp(name, "or")) t (or_2); + if (!strcmp(name, "and")) t (and_2); + if (!strcmp(name, "xor")) t (xor_2); + if (!strcmp(name, "equals")) t (equals_2); + if (!strcmp(name, "greater")) t (greater_2); + if (!strcmp(name, "less")) t (less_2); + if (!strcmp(name, "get")) t (get_2); abort(); + fail: + return NULL; +#undef t } diff --git a/src/mds-kbdc/callables.c b/src/mds-kbdc/callables.c index 10eddcc..4c984c1 100644 --- a/src/mds-kbdc/callables.c +++ b/src/mds-kbdc/callables.c @@ -142,7 +142,7 @@ int callables_set(const char* restrict name, size_t arg_count, mds_kbdc_tree_t* list_ptr++; return 0; - pfail: + fail: saved_errno = errno; free(dupname); free(new_names); diff --git a/src/mds-kbdc/compile-layout.c b/src/mds-kbdc/compile-layout.c index 0622d35..8e005c0 100644 --- a/src/mds-kbdc/compile-layout.c +++ b/src/mds-kbdc/compile-layout.c @@ -58,7 +58,7 @@ /** * Beginning of failure clause */ -#define FAIL_BEGIN pfail: saved_errno = errno +#define FAIL_BEGIN fail: saved_errno = errno /** * End of failure clause @@ -247,7 +247,7 @@ static int check_set_3_get_2_call(mds_kbdc_tree_t* restrict tree, int is_set, co FUN_ERROR(tree, ERROR, "‘\\%zu’ does not hold %zu elements", (size_t)*variable_arg, (size_t)*index_arg);/* TODO test */ return 0; - pfail: + fail: return -1; #undef FUN_ERROR #undef F @@ -470,7 +470,7 @@ static char32_t* parse_function_call(mds_kbdc_tree_t* restrict tree, const char* *rc = -1; goto done; - pfail: + fail: saved_errno = errno; free(rc); if (old_arguments) @@ -586,7 +586,7 @@ static void check_function_call(const mds_kbdc_tree_t* restrict tree, const char error->end = lineoff + (size_t)(*end - raw); return; - pfail: + fail: *rc |= -1; } @@ -604,6 +604,8 @@ static int check_function_calls_in_literal(const mds_kbdc_tree_t* restrict tree, { int rc = 0; (void) check_function_calls_in_literal_(tree, raw, lineoff, &raw, &rc); + fail_if (rc < 0); + fail: return rc; } @@ -669,7 +671,10 @@ static char32_t* parse_escape(mds_kbdc_tree_t* restrict tree, const char* restri /* Read escape. */ if (*escape == 100) /* Function call. */ - return parse_function_call(tree, raw_, lineoff, escape, end); + { + fail_if (rc = parse_function_call(tree, raw_, lineoff, escape, end), rc == NULL); + return rc; + } /* Octal or hexadecimal representation, or variable dereference. */ for (; (c = *raw); have = 1, raw++) if (CR( 8, '0', '7')) numbuf = 8 * numbuf + (c & 15); @@ -706,7 +711,7 @@ static char32_t* parse_escape(mds_kbdc_tree_t* restrict tree, const char* restri *escape = 0; *end = raw; return rc; - pfail: + fail: saved_errno = errno; free(rc); return errno = saved_errno, NULL; @@ -838,7 +843,7 @@ static char32_t* parse_quoted_string(mds_kbdc_tree_t* restrict tree, const char* free(buf); return rc; - pfail: + fail: saved_errno = errno; free(subrc); free(old_rc); @@ -890,7 +895,7 @@ static char32_t* parse_unquoted_string(mds_kbdc_tree_t* restrict tree, const cha fail_if (rc = malloc(2 * sizeof(char32_t)), rc == NULL); return rc[0] = buf, rc[1] = -1, rc; - pfail: + fail: return NULL; #undef CHAR_ERROR #undef R @@ -909,7 +914,11 @@ static char32_t* parse_string(mds_kbdc_tree_t* restrict tree, const char* restri { mds_kbdc_tree_t* old_last_value_statement = last_value_statement; char32_t* rc = (strchr("\"\\", *raw) ? parse_quoted_string : parse_unquoted_string)(tree, raw, lineoff); - return last_value_statement = old_last_value_statement, rc; + last_value_statement = old_last_value_statement; + fail_if (rc == NULL); + return rc; + fail: + return NULL; } @@ -1026,7 +1035,7 @@ static char32_t* parse_keys(mds_kbdc_tree_t* restrict tree, const char* restrict free(buf); return last_value_statement = old_last_value_statement, rc; - pfail: + fail: saved_errno = errno; free(subrc); free(old_rc); @@ -1077,9 +1086,18 @@ static size_t parse_variable(mds_kbdc_tree_t* restrict tree, const char* restric memcpy(dotless, raw_, n * sizeof(char)), dotless[n] = '\0'; var = (size_t)atoll(dotless + 1); if (strlen(dotless + 1) != (size_t)snprintf(NULL, 0, "%zu", var)) - return errno = ERANGE, (size_t)0; + fail_if ((errno = ERANGE)); + if (var == 0) + { + NEW_ERROR(tree, INTERNAL_ERROR, + "parsed a variable string to be 0, which should not be possible"); + error->start = lineoff; + error->end = lineoff + strlen(raw_); + tree->processed = PROCESS_LEVEL; + return 1; + } return var; - pfail: + fail: return 0; bad: @@ -1172,7 +1190,10 @@ static int parse_function_argument(mds_kbdc_tree_t* restrict tree, const char* r static int set_macro(mds_kbdc_tree_macro_t* restrict macro, mds_kbdc_include_stack_t* macro_include_stack) { - return callables_set(macro->name, 0, (mds_kbdc_tree_t*)macro, macro_include_stack); + fail_if (callables_set(macro->name, 0, (mds_kbdc_tree_t*)macro, macro_include_stack)); + return 0; + fail: + return -1; } @@ -1224,7 +1245,7 @@ static int get_macro(mds_kbdc_tree_macro_call_t* restrict macro_call, *macro = NULL; return 0; - pfail: + fail: return -1; } @@ -1246,7 +1267,10 @@ static int set_function(mds_kbdc_tree_function_t* restrict function, *suffix_start = '\0'; r = callables_set(suffixless, arg_count, (mds_kbdc_tree_t*)function, function_include_stack); - return *suffix_start = '/', r; + fail_if (*suffix_start = '/', r); + return 0; + fail: + return -1; } @@ -1304,8 +1328,7 @@ static int compile_include(mds_kbdc_tree_include_t* restrict tree) { void* data; int r; - if (mds_kbdc_include_stack_push(tree, &data)) - return -1; + fail_if (mds_kbdc_include_stack_push(tree, &data)); r = compile_subtree(tree->inner); mds_kbdc_include_stack_pop(data); @@ -1314,7 +1337,10 @@ static int compile_include(mds_kbdc_tree_include_t* restrict tree) * include-stack as its overriding statement. */ last_value_statement = NULL; - return r; + fail_if (r); + return 0; + fail: + return -1; } @@ -1650,7 +1676,7 @@ static int compile_have_range(mds_kbdc_tree_assumption_have_range_t* restrict tr */ static int check_marco_calls(mds_kbdc_tree_t* restrict tree) { -#define t(...) if (rc |= r = (__VA_ARGS__), r < 0) return r +#define t(...) fail_if (rc |= r = (__VA_ARGS__), r < 0) mds_kbdc_tree_macro_t* _macro; mds_kbdc_include_stack_t* _macro_include_stack; void* data; @@ -1685,6 +1711,8 @@ static int check_marco_calls(mds_kbdc_tree_t* restrict tree) tree = tree->next; goto again; + fail: + return -1; (void) _macro; (void) _macro_include_stack; #undef t @@ -1699,7 +1727,7 @@ static int check_marco_calls(mds_kbdc_tree_t* restrict tree) */ static int check_function_calls_in_for(const mds_kbdc_tree_for_t* restrict tree) { -#define t(...) if (rc |= r = check_function_calls_in_literal(__VA_ARGS__), r < 0) return r +#define t(...) fail_if (rc |= r = check_function_calls_in_literal(__VA_ARGS__), r < 0) size_t lineoff_first; size_t lineoff_last; char* restrict code = result->source_code->real_lines[tree->loc_line]; @@ -1713,6 +1741,8 @@ static int check_function_calls_in_for(const mds_kbdc_tree_for_t* restrict tree) t ((const mds_kbdc_tree_t*)tree, tree->last, lineoff_last); return rc; + fail: + return -1; #undef t } @@ -1727,9 +1757,13 @@ static int check_function_calls_in_if(const mds_kbdc_tree_if_t* restrict tree) { size_t lineoff; char* restrict code = result->source_code->real_lines[tree->loc_line]; + int r; for (lineoff = tree->loc_end; code[lineoff] == ' '; lineoff++); - return check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->condition, lineoff); + r = check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->condition, lineoff); + fail_if (r < 0); + fail: + return r; } @@ -1741,7 +1775,11 @@ static int check_function_calls_in_if(const mds_kbdc_tree_if_t* restrict tree) */ static int check_function_calls_in_keys(const mds_kbdc_tree_keys_t* restrict tree) { - return check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->keys, tree->loc_start); + int r; + r = check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->keys, tree->loc_start); + fail_if (r < 0); + fail: + return r; } @@ -1753,7 +1791,11 @@ static int check_function_calls_in_keys(const mds_kbdc_tree_keys_t* restrict tre */ static int check_function_calls_in_string(const mds_kbdc_tree_string_t* restrict tree) { - return check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->string, tree->loc_start); + int r; + r = check_function_calls_in_literal((const mds_kbdc_tree_t*)tree, tree->string, tree->loc_start); + fail_if (r < 0); + fail: + return r; } @@ -1765,7 +1807,7 @@ static int check_function_calls_in_string(const mds_kbdc_tree_string_t* restrict */ static int check_function_calls(const mds_kbdc_tree_t* restrict tree) { -#define t(...) if (rc |= r = (__VA_ARGS__), r < 0) return r +#define t(...) fail_if (rc |= r = (__VA_ARGS__), r < 0) void* data; int r, rc = 0; again: @@ -1801,6 +1843,8 @@ static int check_function_calls(const mds_kbdc_tree_t* restrict tree) tree = tree->next; goto again; + fail: + return -1; #undef t } @@ -1848,7 +1892,7 @@ static int check_name_suffix(struct mds_kbdc_tree_callable* restrict tree) } return 0; - pfail: + fail: return -1; name_error: error->start = tree->loc_end; @@ -2103,12 +2147,13 @@ static int compile_if(mds_kbdc_tree_if_t* restrict tree) /* Evaluate whether the evaluted value is true. */ for (ok = 1, i = 0; data[i] >= 0; i++) ok &= !!(data[i]); - free(data); + free(data), data = NULL;; /* Compile the appropriate clause. */ ok = compile_subtree(ok ? tree->inner : tree->otherwise); last_value_statement = NULL; - return ok; + fail_if (ok < 0); + return 0; FAIL_BEGIN; free(data); FAIL_END; @@ -2187,7 +2232,7 @@ static int evaluate_element(mds_kbdc_tree_t* restrict node) } return bad; - pfail: + fail: return -1; } @@ -2200,7 +2245,10 @@ static int evaluate_element(mds_kbdc_tree_t* restrict node) */ static int compile_keys(mds_kbdc_tree_keys_t* restrict tree) { - return evaluate_element((mds_kbdc_tree_t*)tree) < 0 ? -1 : 0; + fail_if (evaluate_element((mds_kbdc_tree_t*)tree)); + return 0; + fail: + return -1; } @@ -2212,7 +2260,10 @@ static int compile_keys(mds_kbdc_tree_keys_t* restrict tree) */ static int compile_string(mds_kbdc_tree_string_t* restrict tree) { - return evaluate_element((mds_kbdc_tree_t*)tree) < 0 ? -1 : 0; + fail_if (evaluate_element((mds_kbdc_tree_t*)tree)); + return 0; + fail: + return -1; } @@ -2225,11 +2276,12 @@ static int compile_string(mds_kbdc_tree_string_t* restrict tree) static int compile_array(mds_kbdc_tree_array_t* restrict tree) { int r = evaluate_element(tree->elements); - if (r < 0) - return -1; + fail_if (r < 0); if (r) tree->processed = PROCESS_LEVEL; return 0; + fail: + return -1; } @@ -2260,8 +2312,8 @@ static int check_nonnul(mds_kbdc_tree_t* restrict tree) tree = tree->next; goto again; - pfail: - return -1; + fail: + return -1; } @@ -2458,10 +2510,9 @@ static int compile_macro_call(mds_kbdc_tree_macro_call_t* restrict tree) */ static int compile_subtree(mds_kbdc_tree_t* restrict tree) { -#define t(expr) if (r = (expr), r < 0) return r +#define t(expr) fail_if ((expr) < 0) #define c(type) t (compile_##type(&(tree->type))) #define c_(type) t (compile_##type(&(tree->type##_))) - int r; again: if (tree == NULL) return 0; @@ -2512,6 +2563,8 @@ static int compile_subtree(mds_kbdc_tree_t* restrict tree) tree = tree->next; goto again; + fail: + return -1; #undef c_ #undef c #undef t @@ -2534,7 +2587,10 @@ int compile_layout(mds_kbdc_parsed_t* restrict result_) variables_terminate(); callables_terminate(); errno = saved_errno; - return r; + fail_if (r); + return 0; + fail: + return -1; } diff --git a/src/mds-kbdc/eliminate-dead-code.c b/src/mds-kbdc/eliminate-dead-code.c index 0881b20..5628a91 100644 --- a/src/mds-kbdc/eliminate-dead-code.c +++ b/src/mds-kbdc/eliminate-dead-code.c @@ -82,11 +82,13 @@ static int eliminate_include(mds_kbdc_tree_include_t* restrict tree) { void* data; int r; - if (mds_kbdc_include_stack_push(tree, &data)) - return -1; + fail_if (mds_kbdc_include_stack_push(tree, &data)); r = eliminate_subtree(tree->inner); mds_kbdc_include_stack_pop(data); - return r; + fail_if (r); + return 0; + fail: + return -1; } @@ -105,7 +107,7 @@ static int eliminate_if(mds_kbdc_tree_if_t* restrict tree) if (elimination > elimination_level) elimination = elimination_level; return 0; - pfail: + fail: return -1; } @@ -118,9 +120,8 @@ static int eliminate_if(mds_kbdc_tree_if_t* restrict tree) */ static int eliminate_subtree(mds_kbdc_tree_t* restrict tree) { -#define e(type) if ((r = eliminate_##type(&(tree->type)))) return r -#define E(type) if ((r = eliminate_##type(&(tree->type##_)))) return r - int r; +#define e(type) fail_if (eliminate_##type(&(tree->type))) +#define E(type) fail_if (eliminate_##type(&(tree->type##_))) again: if (tree == NULL) return 0; @@ -134,8 +135,7 @@ static int eliminate_subtree(mds_kbdc_tree_t* restrict tree) case C(MACRO): case C(ASSUMPTION): case C(FOR): - if ((r = eliminate_subtree(tree->information.inner))) - return r; + fail_if (eliminate_subtree(tree->information.inner)); if ((tree->type == C(FUNCTION)) || (tree->type == C(MACRO))) elimination_level = 0; else if ((tree->type == C(FOR)) && (elimination_level == 1)) elimination_level = 0; break; @@ -156,7 +156,7 @@ static int eliminate_subtree(mds_kbdc_tree_t* restrict tree) tree = tree->next; goto again; - pfail: + fail: return -1; #undef E #undef e @@ -174,7 +174,11 @@ int eliminate_dead_code(mds_kbdc_parsed_t* restrict result_) int r; mds_kbdc_include_stack_begin(result = result_); r = eliminate_subtree(result_->tree); - return mds_kbdc_include_stack_end(), r; + mds_kbdc_include_stack_end(); + fail_if (r); + return 0; + fail: + return -1; } diff --git a/src/mds-kbdc/include-stack.c b/src/mds-kbdc/include-stack.c index d86374e..d8c4547 100644 --- a/src/mds-kbdc/include-stack.c +++ b/src/mds-kbdc/include-stack.c @@ -85,7 +85,7 @@ int mds_kbdc_include_stack_dump(size_t ptr) result->pathname = old_pathname; result->source_code = old_source_code; return 0; - pfail: + fail: result->pathname = old_pathname; result->source_code = old_source_code; return -1; @@ -149,7 +149,7 @@ int mds_kbdc_include_stack_push(const mds_kbdc_tree_include_t* restrict tree, vo latest_save = NULL; return 0; - pfail: + fail: saved_errno = errno; free(old); return errno = saved_errno, -1; @@ -190,9 +190,7 @@ mds_kbdc_include_stack_t* mds_kbdc_include_stack_save(void) return latest_save; } - latest_save = malloc(sizeof(mds_kbdc_include_stack_t)); - if (latest_save == NULL) - return NULL; + fail_if (xmalloc(latest_save, 1, mds_kbdc_include_stack_t)); latest_save->stack = NULL; latest_save->ptr = includes_ptr; @@ -205,10 +203,10 @@ mds_kbdc_include_stack_t* mds_kbdc_include_stack_save(void) memcpy(latest_save->stack, includes, latest_save->ptr * sizeof(const mds_kbdc_tree_include_t*)); return latest_save; - pfail: + fail: saved_errno = errno; - free(latest_save->stack); - latest_save = NULL; + if (latest_save) + free(latest_save->stack), latest_save = NULL; errno = saved_errno; return NULL; } @@ -229,8 +227,7 @@ int mds_kbdc_include_stack_restore(mds_kbdc_include_stack_t* restrict stack) if (stack->ptr > includes_size) { new = realloc(includes, stack->ptr * sizeof(const mds_kbdc_tree_include_t*)); - if (new == NULL) - return -1; + fail_if (new == NULL); includes = new; includes_size = stack->ptr; } @@ -238,6 +235,8 @@ int mds_kbdc_include_stack_restore(mds_kbdc_include_stack_t* restrict stack) memcpy(includes, stack->stack, stack->ptr * sizeof(const mds_kbdc_tree_include_t*)); includes_ptr = stack->ptr; return 0; + fail: + return -1; } diff --git a/src/mds-kbdc/make-tree.c b/src/mds-kbdc/make-tree.c index bb9d59e..77155b2 100644 --- a/src/mds-kbdc/make-tree.c +++ b/src/mds-kbdc/make-tree.c @@ -425,7 +425,7 @@ static int too_few; * Get the pathname name of the parsed file * * @param filename The filename of the parsed file - * @return The value the caller should return, or 1 if the caller should not return + * @return The value the caller should return, or 1 if the caller should not return, -1 on error */ static int get_pathname(const char* restrict filename) { @@ -459,7 +459,7 @@ static int get_pathname(const char* restrict filename) } return 1; - pfail: + fail: saved_errno = errno; free(cwd); return errno = saved_errno, -1; @@ -488,7 +488,7 @@ static int allocate_stacks(void) fail_if (xmalloc(tree_stack, line_n + max_line_length + 1, mds_kbdc_tree_t**)); return 0; - pfail: + fail: return -1; } @@ -504,7 +504,7 @@ static int read_source_code(void) fail_if (read_source_lines(result->pathname, result->source_code) < 0); return 0; - pfail: + fail: return -1; } @@ -545,7 +545,7 @@ static int check_for_premature_end_of_file(void) } return 0; - pfail: + fail: return -1; } @@ -565,7 +565,7 @@ static int check_whether_file_is_empty(void) NEW_ERROR(0, WARNING, "file is empty"); return 0; - pfail: + fail: return -1; } @@ -592,7 +592,7 @@ static int no_parameters(const char* restrict keyword) } return 0; - pfail: + fail: return -1; } @@ -653,7 +653,7 @@ static int names_1(char** restrict var) } return 0; - pfail: + fail: return -1; } @@ -704,7 +704,7 @@ static int chars(char** restrict var) } return 0; - pfail: + fail: return -1; } @@ -731,7 +731,7 @@ static int quotes(void) line = line_; return 0; - pfail: + fail: return -1; } @@ -756,7 +756,7 @@ static int have_more_parameters(void) return 0; } return 1; - pfail: + fail: return -1; } @@ -769,9 +769,10 @@ static int have_more_parameters(void) */ static int test_for_keyword(const char* restrict keyword) { - int r, ok; - if (r = have_more_parameters(), r <= 0) - return r; + int ok, r = have_more_parameters(); + fail_if (r < 0); + if (r == 0) + return 0; ok = (strstr(line, keyword) == line); line += strlen(keyword); @@ -789,7 +790,7 @@ static int test_for_keyword(const char* restrict keyword) NEW_ERROR(1, ERROR, "expecting keyword ‘%s’", keyword); return 0; - pfail: + fail: return -1; } @@ -807,8 +808,10 @@ static int keys(mds_kbdc_tree_t** restrict var) char* arg_end; char* call_end; int r, escape = 0, quote = 0, triangle; - if (r = have_more_parameters(), r <= 0) - return r; + r = have_more_parameters(); + fail_if (r < 0); + if (r == 0) + return 0; arg_end = line; call_end = arg_end; @@ -844,7 +847,7 @@ static int keys(mds_kbdc_tree_t** restrict var) line = end; return 0; - pfail: + fail: return -1; } @@ -863,8 +866,10 @@ static int pure_keys(char** restrict var) char* arg_end; char* call_end; int r, escape = 0, quote = 0, triangle; - if (r = have_more_parameters(), r <= 0) - return r; + r = have_more_parameters(); + fail_if (r < 0); + if (r == 0) + return 0; arg_end = line; call_end = arg_end; @@ -889,7 +894,7 @@ static int pure_keys(char** restrict var) end = arg_end, line = end; return 0; - pfail: + fail: return -1; } @@ -959,7 +964,7 @@ static int sequence(int mapseq, size_t stack_orig) } return 0; - pfail: + fail: return -1; } @@ -984,7 +989,7 @@ static int sequence_fully_popped(size_t stack_orig) } return 0; - pfail: + fail: return -1; } @@ -1052,7 +1057,7 @@ static int parse_else(void) } return 0; - pfail: + fail: return -1; } @@ -1074,7 +1079,7 @@ static int parse_for(void) BRANCH("for"); return 0; - pfail: + fail: return -1; } @@ -1128,7 +1133,7 @@ static int parse_let(void) } return 0; - pfail: + fail: return -1; } @@ -1159,7 +1164,7 @@ static int parse_end(void) NEXT; return 0; - pfail: + fail: return -1; } @@ -1218,7 +1223,7 @@ static int parse_map(void) NEW_ERROR(1, ERROR, "too many parameters"); return 0; - pfail: + fail: return -1; } @@ -1283,7 +1288,7 @@ static int parse_macro_call(void) NEW_ERROR(1, ERROR, "invalid syntax ‘%s’", line); return 0; - pfail: + fail: return -1; } @@ -1323,7 +1328,7 @@ static int parse_array_elements(void) } } - pfail: + fail: return -1; } @@ -1375,7 +1380,7 @@ static int parse_line(void) *end = prev_end_char; return 0; - pfail: + fail: return -1; #undef p } @@ -1408,8 +1413,10 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict res fail_if (xmalloc(result->source_code, 1, mds_kbdc_source_code_t)); mds_kbdc_source_code_initialise(result->source_code); - if (r = get_pathname(filename), r <= 0) - return r; + r = get_pathname(filename); + fail_if (r < 0); + if (r == 0) + return 0; fail_if (read_source_code()); fail_if (allocate_stacks()); @@ -1442,7 +1449,7 @@ int parse_to_tree(const char* restrict filename, mds_kbdc_parsed_t* restrict res free(tree_stack); return 0; - pfail: + fail: saved_errno = errno; free(keyword_stack); free(tree_stack); diff --git a/src/mds-kbdc/mds-kbdc.c b/src/mds-kbdc/mds-kbdc.c index ed690a7..33b97b2 100644 --- a/src/mds-kbdc/mds-kbdc.c +++ b/src/mds-kbdc/mds-kbdc.c @@ -85,7 +85,7 @@ int main(int argc_, char** argv_) mds_kbdc_parsed_destroy(&result); return fatal; - pfail: + fail: xperror(*argv); mds_kbdc_parsed_destroy(&result); return 1; diff --git a/src/mds-kbdc/parsed.c b/src/mds-kbdc/parsed.c index a049b9c..8ab483b 100644 --- a/src/mds-kbdc/parsed.c +++ b/src/mds-kbdc/parsed.c @@ -150,7 +150,7 @@ mds_kbdc_parse_error_t* mds_kbdc_parsed_new_error(mds_kbdc_parsed_t* restrict th } return error; - pfail: + fail: saved_errno = errno; free(error); this->errors_ptr = old_errors_ptr; diff --git a/src/mds-kbdc/paths.c b/src/mds-kbdc/paths.c index 552aaae..e294020 100644 --- a/src/mds-kbdc/paths.c +++ b/src/mds-kbdc/paths.c @@ -50,7 +50,7 @@ char* curpath(void) } return cwd; - pfail: + fail: saved_errno = errno; free(old); free(cwd); @@ -73,7 +73,10 @@ char* abspath(const char* path) size_t size, p; if (*path == '/') - return strdup(path); + { + fail_if (buf = strdup(path), buf == NULL); + return buf; + } fail_if (cwd = curpath(), cwd == NULL); size = (p = strlen(cwd)) + strlen(path) + 2; @@ -104,7 +107,7 @@ char* abspath(const char* path) free(cwd); return buf; - pfail: + fail: saved_errno = errno; free(cwd); errno = saved_errno; @@ -154,7 +157,7 @@ char* relpath(const char* path, const char* base) free(abs); free(absbase); return buf; - pfail: + fail: saved_errno = errno; free(abs); free(absbase); diff --git a/src/mds-kbdc/process-includes.c b/src/mds-kbdc/process-includes.c index 18d995f..2faaf3f 100644 --- a/src/mds-kbdc/process-includes.c +++ b/src/mds-kbdc/process-includes.c @@ -135,7 +135,7 @@ static int transfer_errors(mds_kbdc_parsed_t* restrict subresult, mds_kbdc_tree_ free(errors); return 0; - pfail: + fail: saved_errno = errno; while (errors_ptr--) mds_kbdc_parse_error_free(errors[errors_ptr]); @@ -223,7 +223,7 @@ static int process_include(mds_kbdc_tree_include_t* restrict tree) mds_kbdc_parsed_destroy(&subresult); return 0; - pfail: + fail: saved_errno = errno; free(dirname); free(cwd); @@ -242,8 +242,7 @@ static int process_include(mds_kbdc_tree_include_t* restrict tree) */ static int process_includes_in_tree(mds_kbdc_tree_t* restrict tree) { -#define p(expr) if ((r = process_includes_in_tree(tree->expr))) return r - int r; +#define p(expr) fail_if (process_includes_in_tree(tree->expr)) again: if (tree == NULL) return 0; @@ -257,8 +256,7 @@ static int process_includes_in_tree(mds_kbdc_tree_t* restrict tree) case C(FOR): p (for_.inner); break; case C(IF): p (if_.inner); p (if_.otherwise); break; case C(INCLUDE): - if ((r = process_include(&(tree->include)))) - return r; + fail_if (process_include(&(tree->include))); break; default: break; @@ -266,6 +264,8 @@ static int process_includes_in_tree(mds_kbdc_tree_t* restrict tree) tree = tree->next; goto again; + fail: + return -1; #undef p } @@ -290,7 +290,7 @@ int process_includes(mds_kbdc_parsed_t* restrict result_) { struct stat* old; if (xxrealloc(old, included, included_size += 4, struct stat)) - return included = old, -1; + fail_if (included = old, 1); } for (i = 0; i < included_ptr; i++) @@ -309,7 +309,7 @@ int process_includes(mds_kbdc_parsed_t* restrict result_) free(included), included_size = 0; return errno = saved_errno, r; - pfail: + fail: return -1; } diff --git a/src/mds-kbdc/raw-data.c b/src/mds-kbdc/raw-data.c index 4a6a6ba..83e8b48 100644 --- a/src/mds-kbdc/raw-data.c +++ b/src/mds-kbdc/raw-data.c @@ -130,8 +130,8 @@ static char* read_file(const char* restrict pathname, size_t* restrict size) /* Read a chunk of the file. */ got = read(fd, content + buf_ptr, (buf_size - buf_ptr) * sizeof(char)); if ((got < 0) && (errno == EINTR)) continue; - else if (got < 0) goto pfail; - else if (got == 0) break; + if (got == 0) break; + fail_if (got < 0); buf_ptr += (size_t)got; } @@ -145,7 +145,7 @@ static char* read_file(const char* restrict pathname, size_t* restrict size) *size = buf_ptr; return content; - pfail: + fail: xperror(*argv); free(old); free(content); @@ -325,7 +325,7 @@ static char** line_split(char* content, size_t length) return lines; - pfail: + fail: xperror(*argv); return NULL; } @@ -370,7 +370,7 @@ static int expand(char** restrict content, size_t* restrict content_size) while (++col % 8); return 0; - pfail: + fail: return -1; } @@ -429,7 +429,7 @@ int read_source_lines(const char* restrict pathname, mds_kbdc_source_code_t* res source_code->line_count = line_count; return 0; - pfail: + fail: xperror(*argv); free(old); free(content); @@ -456,14 +456,15 @@ static char* encode_utf8(char* buffer, char32_t character) text[0] = character; text[1] = -1; - if (str_ = str = string_encode(text), str == NULL) - return NULL; + fail_if (str_ = str = string_encode(text), str == NULL); while (*str) *buffer++ = *str++; free(str_); return buffer; + fail: + return NULL; } @@ -489,8 +490,7 @@ char* parse_raw_string(const char* restrict string) * is not code point whose UTF-8 encoding is longer than its * hexadecimal representation. */ p = rc = malloc(strlen(string) * sizeof(char)); - if (rc == NULL) - return NULL; + fail_if (rc == NULL); while ((c = *string++)) if (r(escape == 8, '0', '7')) buf = (buf << 3) | (c & 15); @@ -519,7 +519,7 @@ char* parse_raw_string(const char* restrict string) *p = '\0'; return rc; - pfail: + fail: free(rc); return NULL; #undef r diff --git a/src/mds-kbdc/simplify-tree.c b/src/mds-kbdc/simplify-tree.c index 713a898..d24569d 100644 --- a/src/mds-kbdc/simplify-tree.c +++ b/src/mds-kbdc/simplify-tree.c @@ -161,6 +161,7 @@ static int eliminate_alternation(mds_kbdc_tree_t* tree, mds_kbdc_tree_t* argumen mds_kbdc_tree_t* next_alternative; mds_kbdc_tree_t* new_argument; size_t i; + int saved_errno; /* Detach next statement, we do not want to duplicate all following statements. */ next_statement = tree->next, tree->next = NULL; @@ -171,13 +172,7 @@ static int eliminate_alternation(mds_kbdc_tree_t* tree, mds_kbdc_tree_t* argumen for (first = last = NULL; alternative; alternative = next_alternative) { /* Duplicate statement. */ - if (new_tree = mds_kbdc_tree_dup(tree), new_tree == NULL) - { - int saved_errno = errno; - argument->alternation.inner = alternative; - tree->next = next_statement; - return errno = saved_errno, -1; - } + fail_if (new_tree = mds_kbdc_tree_dup(tree), new_tree == NULL); /* Join trees. */ if (last) last->next = new_tree; @@ -204,6 +199,11 @@ static int eliminate_alternation(mds_kbdc_tree_t* tree, mds_kbdc_tree_t* argumen /* Reattach the statement that followed to the last generated statement. */ last->next = next_statement; return 0; + fail: + saved_errno = errno; + argument->alternation.inner = alternative; + tree->next = next_statement; + return errno = saved_errno, -1; } @@ -321,7 +321,7 @@ static int simplify_macro_call(mds_kbdc_tree_macro_call_t* restrict tree) */ return 0; - pfail: + fail: saved_errno = errno; mds_kbdc_tree_free(dup_arguments); return errno = saved_errno, -1; @@ -352,7 +352,7 @@ static int check_value_statement_before_simplification(mds_kbdc_tree_map_t* rest fail_if (simplify(tree->sequence)); goto again; - pfail: + fail: return -1; } @@ -374,7 +374,7 @@ static int check_value_statement_after_simplification(mds_kbdc_tree_map_t* restr NEW_ERROR(tree->sequence, ERROR, "bad value type"); return 0; - pfail: + fail: return -1; } @@ -530,7 +530,7 @@ static int simplify_map(mds_kbdc_tree_map_t* restrict tree) */ return 0; - pfail: + fail: saved_errno = errno; mds_kbdc_tree_free(dup_sequence); return errno = saved_errno, -1; @@ -567,7 +567,8 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree) NEW_ERROR(tree, WARNING, "singleton alternation"); memcpy(tree, temp, sizeof(mds_kbdc_tree_t)); free(temp); - return simplify((mds_kbdc_tree_t*)tree); + fail_if (simplify((mds_kbdc_tree_t*)tree)); + return 0; } /* Simplify. */ @@ -603,7 +604,7 @@ static int simplify_alternation(mds_kbdc_tree_alternation_t* restrict tree) } return 0; - pfail: + fail: return -1; } @@ -625,11 +626,10 @@ static mds_kbdc_tree_t* create_permutations(mds_kbdc_tree_t* elements) mds_kbdc_tree_t* subperms = NULL; mds_kbdc_tree_t* perm; mds_kbdc_tree_t ordered; - int saved_errno, no_perms; + int saved_errno, no_perms, stage = 0; /* Error case. */ - if (elements == NULL) - return NULL; + fail_if (elements == NULL); /* Base case. */ if (elements->next == NULL) @@ -639,6 +639,7 @@ static mds_kbdc_tree_t* create_permutations(mds_kbdc_tree_t* elements) return first; } + stage++; for (previous_next = &elements; (argument = *previous_next); previous_next = &((*previous_next)->next)) { /* Created ordered alternative for a permutation prototype. */ @@ -678,11 +679,12 @@ static mds_kbdc_tree_t* create_permutations(mds_kbdc_tree_t* elements) return first; - pfail: + fail: saved_errno = errno; mds_kbdc_tree_free(first); mds_kbdc_tree_free(subperms); - mds_kbdc_tree_destroy(&ordered); + if (stage > 0) + mds_kbdc_tree_destroy(&ordered); errno = saved_errno; return NULL; } @@ -730,7 +732,8 @@ static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree) NEW_ERROR(tree, WARNING, "singleton unordered subsequence"); memcpy(tree, temp, sizeof(mds_kbdc_tree_t)); free(temp); - return simplify((mds_kbdc_tree_t*)tree); + fail_if (simplify((mds_kbdc_tree_t*)tree)); + return -1; } /* Remove ‘.’:s. */ @@ -783,14 +786,14 @@ static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree) * if it does not list any permutations. */ NEW_ERROR_(result, INTERNAL_ERROR, 0, 0, 0, 0, 1, "Fail to create permutations of an unordered sequence"); - errno = 0; + return 0; } - return tree->inner = arguments, -1; + fail_if (tree->inner = arguments, 1); } mds_kbdc_tree_free(arguments); return 0; - pfail: + fail: return -1; } @@ -803,9 +806,8 @@ static int simplify_unordered(mds_kbdc_tree_unordered_t* restrict tree) */ static int simplify(mds_kbdc_tree_t* restrict tree) { -#define s(expr) if ((r = simplify(tree->expr))) return r -#define S(type) if ((r = simplify_##type(&(tree->type)))) return r - int r; +#define s(expr) fail_if (simplify(tree->expr)) +#define S(type) fail_if (simplify_##type(&(tree->type))) again: if (tree == NULL) return 0; @@ -828,6 +830,8 @@ static int simplify(mds_kbdc_tree_t* restrict tree) tree = tree->next; goto again; + fail: + return -1; #undef s #undef S } diff --git a/src/mds-kbdc/string.c b/src/mds-kbdc/string.c index 062aed3..6ecf757 100644 --- a/src/mds-kbdc/string.c +++ b/src/mds-kbdc/string.c @@ -56,8 +56,7 @@ char32_t* string_decode(const char* restrict string) length++; /* Allocated UTF-32 string. */ - if (xmalloc(rc, length + 1, char32_t)) - return NULL; + fail_if (xmalloc(rc, length + 1, char32_t)); /* Convert to UTF-32. */ for (i = j = n = 0; string[i]; i++) @@ -81,6 +80,8 @@ char32_t* string_decode(const char* restrict string) /* -1-terminate and return. */ return rc[length] = -1, rc; + fail: + return NULL; } @@ -98,8 +99,7 @@ char* string_encode(const char32_t* restrict string) char* restrict rc; /* Allocated Modified UTF-8 string. */ - if (xmalloc(rc, 7 * n + 1, char)) - return NULL; + fail_if (xmalloc(rc, 7 * n + 1, char)); /* Convert to Modified UTF-8. */ for (i = j = 0; i < n; i++) @@ -127,6 +127,8 @@ char* string_encode(const char32_t* restrict string) /* NUL-terminate and return. */ return rc[j] = '\0', rc; + fail: + return NULL; } @@ -143,9 +145,10 @@ char32_t* string_dup(const char32_t* restrict string) if (string == NULL) return NULL; n = string_length(string) + 1; - if (xmalloc(rc, n, char32_t)) - return NULL; + fail_if (xmalloc(rc, n, char32_t)); memcpy(rc, string, n * sizeof(char32_t)); return rc; + fail: + return NULL; } diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c index ccd66d4..6ee98c1 100644 --- a/src/mds-kbdc/tree.c +++ b/src/mds-kbdc/tree.c @@ -60,11 +60,12 @@ void mds_kbdc_tree_initialise(mds_kbdc_tree_t* restrict this, int type) */ mds_kbdc_tree_t* mds_kbdc_tree_create(int type) { - mds_kbdc_tree_t* this = malloc(sizeof(mds_kbdc_tree_t)); - if (this == NULL) - return NULL; + mds_kbdc_tree_t* this; + fail_if (xmalloc(this, 1, mds_kbdc_tree_t)); mds_kbdc_tree_initialise(this, type); return this; + fail: + return NULL; } @@ -331,7 +332,7 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(const mds_kbdc_tree_t* restrict this) node = &(n->next); goto again; - pfail: + fail: saved_errno = errno; mds_kbdc_tree_free(rc); return errno = saved_errno, NULL; diff --git a/src/mds-kbdc/validate-tree.c b/src/mds-kbdc/validate-tree.c index ed96343..466f138 100644 --- a/src/mds-kbdc/validate-tree.c +++ b/src/mds-kbdc/validate-tree.c @@ -106,11 +106,13 @@ static int validate_include(mds_kbdc_tree_include_t* restrict tree) { void* data; int r; - if (mds_kbdc_include_stack_push(tree, &data)) - return -1; + fail_if (mds_kbdc_include_stack_push(tree, &data)); r = validate_subtree(tree->inner); mds_kbdc_include_stack_pop(data); - return r; + fail_if (r); + return 0; + fail: + return -1; } @@ -151,7 +153,7 @@ static int validate_function(mds_kbdc_tree_function_t* restrict tree) def_includes_ptr = includes_ptr; r = validate_subtree(tree->inner); return function = NULL, r; - pfail: + fail: return -1; } @@ -193,7 +195,7 @@ static int validate_macro(mds_kbdc_tree_macro_t* restrict tree) def_includes_ptr = includes_ptr; r = validate_subtree(tree->inner); return macro = NULL, r; - pfail: + fail: return -1; } @@ -235,7 +237,7 @@ static int validate_information(mds_kbdc_tree_information_t* restrict tree) def_includes_ptr = includes_ptr; r = validate_subtree(tree->inner); return information = NULL, r; - pfail: + fail: return -1; } @@ -277,7 +279,7 @@ static int validate_assumption(mds_kbdc_tree_assumption_t* restrict tree) def_includes_ptr = includes_ptr; r = validate_subtree(tree->inner); return assumption = NULL, r; - pfail: + fail: return -1; } @@ -305,7 +307,7 @@ static int validate_map(mds_kbdc_tree_map_t* restrict tree) else if (function) NEW_ERROR(tree, includes_ptr, ERROR, "mapping-statement inside function definition"); return 0; - pfail: + fail: return -1; } @@ -325,7 +327,7 @@ static int validate_macro_call(mds_kbdc_tree_macro_call_t* restrict tree) else if (function) NEW_ERROR(tree, includes_ptr, ERROR, "macro call inside function definition"); return 0; - pfail: + fail: return -1; } @@ -339,9 +341,11 @@ static int validate_macro_call(mds_kbdc_tree_macro_call_t* restrict tree) static int validate_for(mds_kbdc_tree_for_t* restrict tree) { int r; - fors++; - r = validate_subtree(tree->inner); - return fors--, r; + fors++, r = validate_subtree(tree->inner), fors--; + fail_if (r); + return 0; + fail: + return -1; } @@ -353,8 +357,10 @@ static int validate_for(mds_kbdc_tree_for_t* restrict tree) */ static int validate_if(mds_kbdc_tree_if_t* restrict tree) { - return -(validate_subtree(tree->inner) || - validate_subtree(tree->otherwise)); + fail_if ((validate_subtree(tree->inner) || validate_subtree(tree->otherwise))); + return 0; + fail: + return -1; } @@ -369,7 +375,7 @@ static int validate_return(mds_kbdc_tree_return_t* restrict tree) if ((function == NULL) && (macro == NULL)) NEW_ERROR(tree, includes_ptr, ERROR, "‘return’ outside function and macro definition"); return 0; - pfail: + fail: return -1; } @@ -385,7 +391,7 @@ static int validate_break(mds_kbdc_tree_break_t* restrict tree) if (fors == 0) NEW_ERROR(tree, includes_ptr, ERROR, "‘break’ outside ‘for’"); return 0; - pfail: + fail: return -1; } @@ -401,7 +407,7 @@ static int validate_continue(mds_kbdc_tree_continue_t* restrict tree) if (fors == 0) NEW_ERROR(tree, includes_ptr, ERROR, "‘continue’ outside ‘for’"); return 0; - pfail: + fail: return -1; } @@ -417,7 +423,7 @@ static int validate_assumption_data(mds_kbdc_tree_t* restrict tree) if (assumption == NULL) NEW_ERROR(tree, includes_ptr, ERROR, "assumption outside assumption clause"); return 0; - pfail: + fail: return -1; } @@ -433,7 +439,7 @@ static int validate_information_data(mds_kbdc_tree_t* restrict tree) if (information == NULL) NEW_ERROR(tree, includes_ptr, ERROR, "information outside information clause"); return 0; - pfail: + fail: return -1; } @@ -446,9 +452,8 @@ static int validate_information_data(mds_kbdc_tree_t* restrict tree) */ static int validate_subtree(mds_kbdc_tree_t* restrict tree) { -#define v(type) if ((r = validate_##type(&(tree->type)))) return r -#define V(type) if ((r = validate_##type(&(tree->type##_)))) return r - int r; +#define v(type) fail_if (validate_##type(&(tree->type))) +#define V(type) fail_if (validate_##type(&(tree->type##_))) again: if (tree == NULL) return 0; @@ -470,14 +475,12 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree) case C(INFORMATION_LANGUAGE): case C(INFORMATION_COUNTRY): case C(INFORMATION_VARIANT): - if ((r = validate_information_data(tree))) - return r; + fail_if (validate_information_data(tree)); break; case C(ASSUMPTION_HAVE): case C(ASSUMPTION_HAVE_CHARS): case C(ASSUMPTION_HAVE_RANGE): - if ((r = validate_assumption_data(tree))) - return r; + fail_if (validate_assumption_data(tree)); break; default: break; @@ -485,6 +488,8 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree) tree = tree->next; goto again; + fail: + return -1; #undef V #undef v } @@ -502,7 +507,11 @@ int validate_tree(mds_kbdc_parsed_t* restrict result_) mds_kbdc_include_stack_begin(result = result_); r = validate_subtree(result_->tree); fors = 0; - return mds_kbdc_include_stack_end(), r; + mds_kbdc_include_stack_end(); + fail_if (r); + return 0; + fail: + return -1; } diff --git a/src/mds-kbdc/variables.c b/src/mds-kbdc/variables.c index 55bae76..7431767 100644 --- a/src/mds-kbdc/variables.c +++ b/src/mds-kbdc/variables.c @@ -17,6 +17,8 @@ */ #include "variables.h" +#include <libmdsserver/macros.h> + #include <stdlib.h> #include <string.h> @@ -149,9 +151,8 @@ int variables_let(size_t variable, mds_kbdc_tree_t* restrict value) /* Grow the table if necessary to fit the variable. */ if (variable >= variable_count) { - new = realloc(variables, (variable + 1) * sizeof(variable_t*)); - if (new == NULL) - return -1; + new = variables; + fail_if (xrealloc(new, variable + 1, variable_t*)); variables = new; memset(variables + variable_count, 0, (variable + 1 - variable_count) * sizeof(variable_t*)); variable_count = variable + 1; @@ -169,13 +170,15 @@ int variables_let(size_t variable, mds_kbdc_tree_t* restrict value) previous = variables[variable]; variables[variable] = malloc(sizeof(variable_t)); if (variables[variable] == NULL) - return variables[variable] = previous, -1; + fail_if (variables[variable] = previous, 1); variables[variable]->value = value; variables[variable]->previous = previous; variables[variable]->scope = current_scope; } return 0; + fail: + return -1; } diff --git a/src/mds-kkbd.c b/src/mds-kkbd.c index 73dbc8a..1823f5c 100644 --- a/src/mds-kkbd.c +++ b/src/mds-kkbd.c @@ -232,36 +232,26 @@ int initialise_server(void) "\n" KEYBOARD_ID "\n"; - fail_if (open_leds() < 0); - stage = 1; - fail_if (open_input() < 0); - stage = 2; - fail_if (pthread_mutex_init(&send_mutex, NULL)); - stage = 3; - fail_if (pthread_mutex_init(&mapping_mutex, NULL)); - stage = 4; - - if (full_send(message, strlen(message))) - return 1; - - fail_if (server_initialised()); - stage = 5; + fail_if (open_leds() < 0); stage++; + fail_if (open_input() < 0); stage++; + fail_if (pthread_mutex_init(&send_mutex, NULL)); stage++; + fail_if (pthread_mutex_init(&mapping_mutex, NULL)); stage++; + fail_if (full_send(message, strlen(message))); + fail_if (server_initialised()); stage++; fail_if (mds_message_initialise(&received)); return 0; - pfail: + fail: xperror(*argv); if (stage < 5) { if (stage >= 2) close_input(); if (stage >= 1) close_leds(); } - if (stage >= 3) - pthread_mutex_destroy(&send_mutex); - if (stage >= 4) - pthread_mutex_destroy(&mapping_mutex); - mds_message_destroy(&received); + if (stage >= 3) pthread_mutex_destroy(&send_mutex); + if (stage >= 4) pthread_mutex_destroy(&mapping_mutex); + if (stage >= 5) mds_message_destroy(&received); return 1; } @@ -277,13 +267,12 @@ int postinitialise_server(void) if (connected) return 0; - if (reconnect_to_display()) - { - mds_message_destroy(&received); - return 1; - } + fail_if (reconnect_to_display()); connected = 1; return 0; + fail: + mds_message_destroy(&received); + return 1; } @@ -386,7 +375,7 @@ int unmarshal_server(char* state_buf) fail_if (mds_message_unmarshal(&received, state_buf)); return 0; - pfail: + fail: xperror(*argv); mds_message_destroy(&received); free(mapping); @@ -437,29 +426,28 @@ int master_loop(void) if (r == -2) { eprint("corrupt message received, aborting."); - goto fail; + goto done; } else if (errno == EINTR) continue; - else if (errno != ECONNRESET) - goto pfail; + else + fail_if (errno != ECONNRESET); eprint("lost connection to server."); mds_message_destroy(&received); mds_message_initialise(&received); connected = 0; - if (reconnect_to_display()) - goto fail; + fail_if (reconnect_to_display()); connected = 1; } joined = 1; fail_if ((errno = pthread_join(kbd_thread, &kbd_ret))); rc = kbd_ret == NULL ? 0 : 1; - goto fail; - pfail: - xperror(*argv); + goto done; fail: + xperror(*argv); + done: pthread_mutex_destroy(&send_mutex); pthread_mutex_destroy(&mapping_mutex); free(send_buffer); @@ -487,12 +475,11 @@ void* keyboard_loop(void* data) while (!reexecing && !terminating) if (fetch_keys() < 0) - if (errno != EINTR) - goto pfail; + fail_if (errno != EINTR); return NULL; - pfail: + fail: xperror(*argv); raise(SIGTERM); return (void*)1024; @@ -542,19 +529,23 @@ int handle_message(void) if (recv_command == NULL) return 0; /* How did that get here, not matter, just ignore it? */ - + +#define t(expr) do { fail_if (expr); return 0; } while (0) if (strequals(recv_command, "enumerate-keyboards")) - return handle_enumerate_keyboards(recv_client_id, recv_message_id, recv_modify_id); + t (handle_enumerate_keyboards(recv_client_id, recv_message_id, recv_modify_id)); if (strequals(recv_command, "keyboard-enumeration")) - return handle_keyboard_enumeration(recv_modify_id); + t (handle_keyboard_enumeration(recv_modify_id)); if (strequals(recv_command, "set-keyboard-leds")) - return handle_set_keyboard_leds(recv_active, recv_mask, recv_keyboard); + t (handle_set_keyboard_leds(recv_active, recv_mask, recv_keyboard)); if (strequals(recv_command, "get-keyboard-leds")) - return handle_get_keyboard_leds(recv_client_id, recv_message_id, recv_keyboard); + t (handle_get_keyboard_leds(recv_client_id, recv_message_id, recv_keyboard)); if (strequals(recv_command, "keycode-map")) - return handle_keycode_map(recv_client_id, recv_message_id, recv_action, recv_keyboard); + t (handle_keycode_map(recv_client_id, recv_message_id, recv_action, recv_keyboard)); +#undef t return 0; /* How did that get here, not matter, just ignore it? */ + fail: + return -1; } @@ -571,15 +562,13 @@ static int ensure_send_buffer_size(size_t size) if (send_buffer_size >= size) return 0; - if (xrealloc(send_buffer, size, char)) - { - send_buffer = old; - return -1; - } - else - send_buffer_size = size; + fail_if (xrealloc(send_buffer, size, char)); + send_buffer_size = size; return 0; + fail: + send_buffer = old; + return -1; } @@ -615,8 +604,7 @@ int handle_enumerate_keyboards(const char* recv_client_id, const char* recv_mess message_id = message_id == UINT32_MAX ? 0 : (message_id + 1); ); - if (ensure_send_buffer_size(48 + strlen(recv_modify_id) + 1) < 0) - return -1; + fail_if (ensure_send_buffer_size(48 + strlen(recv_modify_id) + 1) < 0); sprintf(send_buffer, "Modify: no\n" "Modify ID: %s\n" @@ -626,8 +614,10 @@ int handle_enumerate_keyboards(const char* recv_client_id, const char* recv_mess with_mutex (send_mutex, r = full_send(send_buffer, strlen(send_buffer)); + if (r) r = errno ? errno : -1; ); - return r; + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; } with_mutex (send_mutex, @@ -638,8 +628,7 @@ int handle_enumerate_keyboards(const char* recv_client_id, const char* recv_mess n = 176 + 3 * sizeof(size_t) + strlen(KEYBOARD_ID); n += strlen(recv_modify_id) + strlen(recv_message_id); - if (ensure_send_buffer_size(n + 1) < 0) - return -1; + fail_if (ensure_send_buffer_size(n + 1) < 0); sprintf(send_buffer, "Modify: yes\n" "Modify ID: %s\n" @@ -658,8 +647,12 @@ int handle_enumerate_keyboards(const char* recv_client_id, const char* recv_mess with_mutex (send_mutex, r = full_send(send_buffer, strlen(send_buffer)); + if (r) r = errno ? errno : -1; ); - return r; + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; + fail: + return -1; } @@ -689,8 +682,7 @@ int handle_keyboard_enumeration(const char* recv_modify_id) n += off = 64 + strlen(recv_modify_id) + 3 * sizeof(size_t); - if (ensure_send_buffer_size(n + 1) < 0) - return -1; + fail_if (ensure_send_buffer_size(n + 1) < 0); with_mutex (send_mutex, msgid = message_id; @@ -734,9 +726,13 @@ int handle_keyboard_enumeration(const char* recv_modify_id) with_mutex (send_mutex, r = full_send(send_buffer + off, n); + if (r) r = errno ? errno : -1; ); - return r; + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; + fail: + return -1; } @@ -856,7 +852,7 @@ int handle_get_keyboard_leds(const char* recv_client_id, const char* recv_messag int error = errno; xperror(*argv); send_errno(error, recv_client_id, recv_message_id); - return -1; + fail_if (errno = error, 1); } with_mutex (send_mutex, @@ -866,8 +862,7 @@ int handle_get_keyboard_leds(const char* recv_client_id, const char* recv_messag n = 95 + 3 * sizeof(size_t) + 2 * strlen(PRESENT_LEDS); n += strlen(recv_client_id) + strlen(recv_message_id); - if (ensure_send_buffer_size(n + 1) < 0) - return -1; + fail_if (ensure_send_buffer_size(n + 1) < 0); sprintf(send_buffer, "To: %s\n" "In response to: %s\n" @@ -888,9 +883,14 @@ int handle_get_keyboard_leds(const char* recv_client_id, const char* recv_messag with_mutex (send_mutex, r = full_send(send_buffer, strlen(send_buffer)); + if (r) r = errno ? errno : -1; ); - return r; + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; + fail: + xperror(*argv); + return -1; } @@ -915,10 +915,7 @@ static int parse_remap_line(char* begin, char* end, size_t n, int* restrict in, return 0; if (delimiter == NULL) - { - *in = -1, *out = -1; - return -1; - } + fail_if (*in = -1, *out = -1); *delimiter++ = '\0'; *in = atoi(begin); @@ -935,6 +932,8 @@ static int parse_remap_line(char* begin, char* end, size_t n, int* restrict in, } return 1; + fail: + return -1; } @@ -956,10 +955,7 @@ static int add_mapping(int in, int out) return 0; if (old = mapping, xrealloc(mapping, n, int)) - { - mapping = old; - return -1; - } + fail_if (mapping = old, 1); for (; mapping_size < n; mapping_size++) mapping[mapping_size] = (int)mapping_size; @@ -967,6 +963,8 @@ static int add_mapping(int in, int out) mapping[in] = out; return 0; + fail: + return -1; } @@ -999,8 +997,7 @@ static int remap(char* table, size_t n) if (in != out) greatest_remap = max(greatest_remap, in); else greatest_reset = max(greatest_reset, in); - if (add_mapping(in, out) < 0) - return -1; + fail_if (add_mapping(in, out) < 0); next: if (end == NULL) @@ -1014,6 +1011,8 @@ static int remap(char* table, size_t n) shrink_map(); return 0; + fail: + return -1; } @@ -1039,8 +1038,7 @@ static int mapping_query(const char* recv_client_id, const char* recv_message_id n *= 3 + (size_t)(greatest > 0x00FF ? 5 : 3); - if (ensure_send_buffer_size(top + n + 2) < 0) - return -1; + fail_if (ensure_send_buffer_size(top + n + 2) < 0); with_mutex (send_mutex, msgid = message_id; @@ -1071,9 +1069,13 @@ static int mapping_query(const char* recv_client_id, const char* recv_message_id with_mutex (send_mutex, r = full_send(send_buffer + off, top + n); + if (r) r = errno ? errno : -1; ); - return r; + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; + fail: + return -1; } @@ -1090,8 +1092,7 @@ static int mapping_query(const char* recv_client_id, const char* recv_message_id int handle_keycode_map(const char* recv_client_id, const char* recv_message_id, const char* recv_action, const char* recv_keyboard) { - int r = 0; - + int r; if ((recv_keyboard != NULL) && !strequals(recv_keyboard, KEYBOARD_ID)) return 0; @@ -1107,7 +1108,9 @@ int handle_keycode_map(const char* recv_client_id, const char* recv_message_id, with_mutex (mapping_mutex, r = remap(received.payload, received.payload_size); + if (r) r = errno ? errno : -1; ); + fail_if (errno = (r == -1 ? 0 : r), r); } else if (strequals(recv_action, "reset")) { @@ -1124,12 +1127,14 @@ int handle_keycode_map(const char* recv_client_id, const char* recv_message_id, return 0; } - r = mapping_query(recv_client_id, recv_message_id); + fail_if (mapping_query(recv_client_id, recv_message_id)); } else eprint("received keycode map request with invalid action, ignoring."); - return r; + return 0; + fail: + return -1; } @@ -1170,15 +1175,15 @@ int full_send(const char* message, size_t length) eprint("Sent more of a message than exists in the message, aborting."); return -1; } - else if ((sent < length) && (errno != EINTR)) - { - xperror(*argv); - return -1; - } + else + fail_if ((sent < length) && (errno != EINTR)); message += sent; length -= sent; } return 0; + fail: + xperror(*argv); + return -1; } @@ -1190,17 +1195,19 @@ int full_send(const char* message, size_t length) int open_leds(void) { #ifdef __sparc__ - if ((ledfd = open(SPARC_KBD, O_RDONLY)) < 0) - return -1; + fail_if ((ledfd = open(SPARC_KBD, O_RDONLY)) < 0); if (ioctl(ledfd, GET_LED, &saved_leds) < 0) { close(ledfd); - return -1; + fail_if (1); } return 0; #else - return ioctl(ledfd, GET_LED, &saved_leds); + fail_if (ioctl(ledfd, GET_LED, &saved_leds)); #endif + return 0; + fail: + return -1; } @@ -1225,12 +1232,13 @@ void close_leds(void) int get_leds(void) { int leds; - if (ioctl(ledfd, GET_LED, &leds) < 0) - return -1; + fail_if (ioctl(ledfd, GET_LED, &leds) < 0); #ifdef __sparc__ leds &= 15; #endif return leds; + fail: + return -1; } @@ -1242,7 +1250,10 @@ int get_leds(void) */ int set_leds(int leds) { - return ioctl(ledfd, SET_LED, leds); + fail_if (ioctl(ledfd, SET_LED, leds)); + return 0; + fail: + return -1; } @@ -1259,16 +1270,15 @@ int open_input(void) stty = saved_stty; stty.c_lflag &= (tcflag_t)~(ECHO | ICANON | ISIG); stty.c_iflag = 0; - if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty) < 0) - return -1; + fail_if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty) < 0); /* K_MEDIUMRAW: utilise keyboard drivers, but not layout */ if ((ioctl(STDIN_FILENO, KDGKBMODE, &saved_kbd_mode) < 0) || (ioctl(STDIN_FILENO, KDSKBMODE, K_MEDIUMRAW) < 0)) - { - xperror(*argv); - return tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty); - } + fail_if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty)); return 0; + fail: + xperror(*argv); + return -1; } @@ -1339,8 +1349,12 @@ int send_key(int* restrict scancode, int trio) with_mutex (send_mutex, r = full_send(key_send_buffer, strlen(key_send_buffer)); + if (r) r = errno ? errno : 0; ); - return r; + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; + fail: + return -1; } @@ -1414,7 +1428,10 @@ int fetch_keys(void) } } - return errno == 0 ? 0 : -1; + fail_if (errno); + return 0; + fail: + return -1; } @@ -1431,8 +1448,7 @@ int send_errno(int error, const char* recv_client_id, const char* recv_message_i size_t n = 79 + strlen(recv_client_id) + strlen(recv_message_id) + 3 * sizeof(int); int r; - if (ensure_send_buffer_size(n + 1) < 0) - return -1; + fail_if (ensure_send_buffer_size(n + 1) < 0); with_mutex (send_mutex, sprintf(send_buffer, @@ -1446,8 +1462,12 @@ int send_errno(int error, const char* recv_client_id, const char* recv_message_i message_id = message_id == INT32_MAX ? 0 : (message_id + 1); r = full_send(send_buffer, strlen(send_buffer)); + if (r) r = errno ? errno : -1; ); - return r; + fail_if (errno = (r == -1 ? 0 : r), r); + return 0; + fail: + return -1; } diff --git a/src/mds-registry/mds-registry.c b/src/mds-registry/mds-registry.c index 741423c..4b49525 100644 --- a/src/mds-registry/mds-registry.c +++ b/src/mds-registry/mds-registry.c @@ -66,7 +66,7 @@ int preinitialise_server(void) return 0; - pfail: + fail: xperror(*argv); if (stage >= 1) pthread_mutex_destroy(&slave_mutex); if (stage >= 2) pthread_cond_destroy(&slave_cond); @@ -82,6 +82,7 @@ int preinitialise_server(void) */ int initialise_server(void) { + int stage = 0; const char* const message = "Command: intercept\n" "Message ID: 0\n" @@ -103,23 +104,20 @@ int initialise_server(void) that happen between the crash and the recovery. */ - if (full_send(message, strlen(message))) - return 1; - if (hash_table_create_tuned(®_table, 32)) - { - xperror(*argv); - hash_table_destroy(®_table, NULL, NULL); - return 1; - } + fail_if (full_send(message, strlen(message))); stage++; + fail_if (hash_table_create_tuned(®_table, 32)); stage++; reg_table.key_comparator = (compare_func*)string_comparator; reg_table.hasher = (hash_func*)string_hash; fail_if (server_initialised() < 0); fail_if (mds_message_initialise(&received)); return 0; - pfail: + fail: xperror(*argv); - mds_message_destroy(&received); + if (stage == 1) + hash_table_destroy(®_table, NULL, NULL); + if (stage == 2) + mds_message_destroy(&received); return 1; } @@ -135,13 +133,12 @@ int postinitialise_server(void) if (connected) return 0; - if (reconnect_to_display()) - { - mds_message_destroy(&received); - return 1; - } + fail_if (reconnect_to_display()); connected = 1; return 0; + fail: + mds_message_destroy(&received); + return 1; } @@ -171,27 +168,26 @@ int master_loop(void) if (r == -2) { eprint("corrupt message received, aborting."); - goto fail; + goto done; } else if (errno == EINTR) continue; - else if (errno != ECONNRESET) - goto pfail; + else + fail_if (errno != ECONNRESET); eprint("lost connection to server."); mds_message_destroy(&received); mds_message_initialise(&received); connected = 0; - if (reconnect_to_display()) - goto fail; + fail_if (reconnect_to_display()); connected = 1; } rc = 0; - goto fail; - pfail: - xperror(*argv); + goto done; fail: + xperror(*argv); + done: /* Join with all slaves threads. */ with_mutex (slave_mutex, while (running_slaves > 0) diff --git a/src/mds-registry/reexec.c b/src/mds-registry/reexec.c index 6247e18..6f6510e 100644 --- a/src/mds-registry/reexec.c +++ b/src/mds-registry/reexec.c @@ -197,25 +197,15 @@ int unmarshal_server(char* state_buf) } return 0; - pfail: + fail: xperror(*argv); mds_message_destroy(&received); if (stage >= 1) hash_table_destroy(®_table, (free_func*)reg_table_free_key, (free_func*)reg_table_free_value); - if (stage >= 2) - free(command); - if (stage >= 3) - { - client_list_destroy(list); - free(list); - } - if (stage >= 5) - linked_list_destroy(&slave_list); - if (stage >= 6) - { - slave_destroy(slave); - free(slave); - } + if (stage >= 2) free(command); + if (stage >= 3) client_list_destroy(list), free(list); + if (stage >= 5) linked_list_destroy(&slave_list); + if (stage >= 6) slave_destroy(slave), free(slave); abort(); return -1; } diff --git a/src/mds-registry/registry.c b/src/mds-registry/registry.c index 2d0643f..f853f93 100644 --- a/src/mds-registry/registry.c +++ b/src/mds-registry/registry.c @@ -74,8 +74,7 @@ static int handle_close_message(void) /* If no servers support the protocol, list the protocol for removal. */ fail_if ((keys == NULL) && xmalloc(keys, size, size_t)); - if (ptr == size ? growalloc(old_keys, keys, size, size_t) : 0) - goto fail; + fail_if (ptr == size ? growalloc(old_keys, keys, size, size_t) : 0); keys[ptr++] = entry->key; } @@ -108,9 +107,8 @@ static int handle_close_message(void) free(keys); return 0; - pfail: - xperror(*argv); fail: + xperror(*argv); free(keys); return -1; } @@ -127,13 +125,14 @@ static int handle_close_message(void) */ static int registry_action_add(int has_key, char* command, size_t command_key, uint64_t client) { + int saved_errno; + if (has_key) { /* Add server to protocol if the protocol is already in the table. */ size_t address = hash_table_get(®_table, command_key); client_list_t* list = (client_list_t*)(void*)address; - if (client_list_add(list, client) < 0) - goto pfail; + fail_if (client_list_add(list, client) < 0); } else { @@ -142,13 +141,12 @@ static int registry_action_add(int has_key, char* command, size_t command_key, u /* Allocate list of servers for the protocol. */ client_list_t* list = malloc(sizeof(client_list_t)); void* address = list; - if (list == NULL) - goto pfail; + fail_if (list == NULL); /* Duplicate the protocol name so it can be accessed later. */ if ((command = strdup(command)) == NULL) { - free(list); - goto pfail; + saved_errno = errno, free(list), errno = saved_errno; + fail_if (1); } /* Create list of servers, add server to list and add the protocol to the table. */ command_key = (size_t)(void*)command; @@ -156,10 +154,12 @@ static int registry_action_add(int has_key, char* command, size_t command_key, u client_list_add(list, client) || (hash_table_put(®_table, command_key, (size_t)address) == 0)) { + saved_errno = errno; client_list_destroy(list); free(list); free(command); - goto pfail; + errno = saved_errno; + fail_if (1); } } @@ -167,7 +167,7 @@ static int registry_action_add(int has_key, char* command, size_t command_key, u fail_if (advance_slaves(command)); return 0; - pfail: + fail: xperror(*argv); return -1; } @@ -214,35 +214,34 @@ static int registry_action_act(char* command, int action, uint64_t client, hash_ { size_t command_key = (size_t)(void*)command; int has_key = hash_table_contains_key(®_table, command_key); + int saved_errno; if (action == 1) { /* Register server to protocol. */ - if (registry_action_add(has_key, command, command_key, client)) - return -1; + fail_if (registry_action_add(has_key, command, command_key, client)); } else if ((action == -1) && has_key) /* Unregister server from protocol. */ registry_action_remove(command_key, client); else if ((action == 0) && !has_key) { - /* Add protocl to wait set of not present in the protocol table. */ - if ((command = strdup(command)) == NULL) - goto pfail_wait; + /* Add protocol to wait set of not present in the protocol table. */ + fail_if ((command = strdup(command)) == NULL); command_key = (size_t)(void*)command; if (hash_table_put(wait_set, command_key, 1) == 0) if (errno) { - free(command); - goto pfail_wait; + saved_errno = errno, free(command), errno = saved_errno; + fail_if (1); } } return 0; - pfail_wait: + fail: xperror(*argv); - hash_table_destroy(wait_set, (free_func*)reg_table_free_key, NULL); - free(wait_set); + if (action != 1) + hash_table_destroy(wait_set, (free_func*)reg_table_free_key, NULL), free(wait_set); return -1; } @@ -264,21 +263,15 @@ static int registry_action(size_t length, int action, const char* recv_client_id uint64_t client = action ? parse_client_id(recv_client_id) : 0; hash_table_t* wait_set = NULL; size_t begin; + int saved_errno; /* If ‘Action: wait’, create a set for the protocols that are not already available. */ if (action == 0) { - wait_set = malloc(sizeof(hash_table_t)); - if (wait_set == NULL) - return -1; - if (hash_table_create(wait_set)) - { - hash_table_destroy(wait_set, NULL, NULL); - free(wait_set); - return -1; - } + fail_if (xmalloc(wait_set, 1, hash_table_t)); + fail_if (hash_table_create(wait_set)); wait_set->key_comparator = (compare_func*)string_comparator; wait_set->hasher = (hash_func*)string_hash; } @@ -288,14 +281,8 @@ static int registry_action(size_t length, int action, const char* recv_client_id if (received.payload_size == length) { - if (growalloc(old, received.payload, received.payload_size, char)) - { - if (wait_set != NULL) - hash_table_destroy(wait_set, NULL, NULL), free(wait_set); - return -1; - } - else - payload = received.payload; + fail_if (growalloc(old, received.payload, received.payload_size, char)); + payload = received.payload; } @@ -318,16 +305,22 @@ static int registry_action(size_t length, int action, const char* recv_client_id if (len > 0) if (registry_action_act(command, action, client, wait_set)) - return -1; + fail_if (wait_set = NULL, 1); } /* If ‘Action: wait’, start a new thread that waits for the protocols and the responds. */ if (action == 0) - return start_slave(wait_set, recv_client_id, recv_message_id); + if (start_slave(wait_set, recv_client_id, recv_message_id)) + fail_if (wait_set = NULL, 1); return 0; + fail: + saved_errno = errno; + if (wait_set != NULL) + hash_table_destroy(wait_set, NULL, NULL), free(wait_set); + return errno = saved_errno, -1; } @@ -336,7 +329,7 @@ static int registry_action(size_t length, int action, const char* recv_client_id * * @param recv_client_id The ID of the client * @param recv_message_id The ID of the received message - * @return Zero on success -1 on error or interruption, + * @return Zero on success, -1 on error or interruption, * `errno` will be set accordingly */ static int list_registry(const char* recv_client_id, const char* recv_message_id) @@ -349,8 +342,7 @@ static int list_registry(const char* recv_client_id, const char* recv_message_id if (send_buffer_size == 0) { - if (xmalloc(send_buffer, 256, char)) - return -1; + fail_if (xmalloc(send_buffer, 256, char)); send_buffer_size = 256; } @@ -365,8 +357,7 @@ static int list_registry(const char* recv_client_id, const char* recv_message_id /* Make sure the send buffer can fit all protocols. */ while (ptr + len + 1 >= send_buffer_size) - if (growalloc(old, send_buffer, send_buffer_size, char)) - return -1; + fail_if (growalloc(old, send_buffer, send_buffer_size, char)); memcpy(send_buffer + ptr, command, len * sizeof(char)); ptr += len; @@ -380,8 +371,7 @@ static int list_registry(const char* recv_client_id, const char* recv_message_id i += strlen("To: %s\nIn response to: %s\nMessage ID: %" PRIu32 "\nLength: %" PRIu64 "\n\n"); while (ptr + i >= send_buffer_size) - if (growalloc(old, send_buffer, send_buffer_size, char)) - return -1; + fail_if (growalloc(old, send_buffer, send_buffer_size, char)); /* Construct message headers. */ @@ -392,9 +382,10 @@ static int list_registry(const char* recv_client_id, const char* recv_message_id with_mutex (slave_mutex, message_id = message_id == UINT32_MAX ? 0 : (message_id + 1);); /* Send message. */ - if (full_send(send_buffer + ptr, strlen(send_buffer + ptr))) - return 1; + fail_if (full_send(send_buffer + ptr, strlen(send_buffer + ptr))); return full_send(send_buffer, ptr); + fail: + return -1; } @@ -488,7 +479,7 @@ static int handle_register_message(void) /** * Handle the received message * - * @return Zero on success -1 on error or interruption, + * @return Zero on success, -1 on error or interruption, * `errno` will be set accordingly */ int handle_message(void) @@ -496,7 +487,13 @@ int handle_message(void) size_t i; for (i = 0; i < received.header_count; i++) if (strequals(received.headers[i], "Command: register")) - return handle_register_message(); - return handle_close_message(); + { + fail_if (handle_register_message()); + return 0; + } + fail_if (handle_close_message()); + return 0; + fail: + return -1; } diff --git a/src/mds-registry/registry.h b/src/mds-registry/registry.h index 0de4d6f..f01b383 100644 --- a/src/mds-registry/registry.h +++ b/src/mds-registry/registry.h @@ -22,7 +22,7 @@ /** * Handle the received message * - * @return Zero on success -1 on error or interruption, + * @return Zero on success, -1 on error or interruption, * `errno` will be set accordingly */ int handle_message(void); diff --git a/src/mds-registry/slave.c b/src/mds-registry/slave.c index 3825472..ef46963 100644 --- a/src/mds-registry/slave.c +++ b/src/mds-registry/slave.c @@ -55,13 +55,14 @@ static int slave_notify_client(slave_t* slave) while (left > 0) { sent = send_message(socket_fd, buf + ptr, left); - if ((sent < left) && errno && (errno != EINTR)) - return -1; + fail_if ((sent < left) && errno && (errno != EINTR)); left -= sent; ptr += sent; } return 0; + fail: + return -1; } @@ -114,7 +115,7 @@ static void* slave_loop(void* data) goto done; - pfail: + fail: xperror(*argv); done: with_mutex (slave_mutex, @@ -136,14 +137,12 @@ static void* slave_loop(void* data) */ int start_created_slave(slave_t* restrict slave) { - if ((errno = pthread_mutex_lock(&slave_mutex))) - return -1; + int locked = 0; - if ((errno = pthread_create(&(slave->thread), NULL, slave_loop, (void*)(intptr_t)slave))) - { - pthread_mutex_unlock(&slave_mutex); - return -1; - } + fail_if ((errno = pthread_mutex_lock(&slave_mutex))); + locked = 1; + + fail_if ((errno = pthread_create(&(slave->thread), NULL, slave_loop, (void*)(intptr_t)slave))); if ((errno = pthread_detach(slave->thread))) xperror(*argv); @@ -152,6 +151,10 @@ int start_created_slave(slave_t* restrict slave) pthread_mutex_unlock(&slave_mutex); return 0; + fail: + if (locked) + pthread_mutex_unlock(&slave_mutex); + return -1; } @@ -168,29 +171,28 @@ int start_slave(hash_table_t* restrict wait_set, const char* restrict recv_clien slave_t* slave = slave_create(wait_set, recv_client_id, recv_message_id); size_t slave_address, i; ssize_t node = LINKED_LIST_UNUSED; + int locked = 0; fail_if (slave == NULL); fail_if ((errno = pthread_mutex_lock(&slave_mutex))); + locked = 1; slave_address = (size_t)(void*)slave; slave->node = node = linked_list_insert_end(&slave_list, slave_address); - if (slave->node == LINKED_LIST_UNUSED) - goto pfail_in_mutex; + fail_if (slave->node == LINKED_LIST_UNUSED); for (i = 0; i < received.header_count; i++) if (startswith(received.headers[i], "Time to live: ")) { const char* ttl = received.headers[i] + strlen("Time to live: "); slave->timed = 1; - if (monotone(&(slave->dethklok))) - goto pfail_in_mutex; + fail_if (monotone(&(slave->dethklok))); slave->dethklok.tv_sec += (time_t)atoll(ttl); - /* It should really be `atol`, but we want to be future proof. */ + /* It should really be `atol`, but we want to be future-proof. */ break; } - if ((errno = pthread_create(&(slave->thread), NULL, slave_loop, (void*)(intptr_t)slave))) - goto pfail_in_mutex; + fail_if ((errno = pthread_create(&(slave->thread), NULL, slave_loop, (void*)(intptr_t)slave))); if ((errno = pthread_detach(slave->thread))) xperror(*argv); @@ -199,13 +201,10 @@ int start_slave(hash_table_t* restrict wait_set, const char* restrict recv_clien pthread_mutex_unlock(&slave_mutex); return 0; - pfail: - xperror(*argv); - goto more_fail; - pfail_in_mutex: + fail: xperror(*argv); - pthread_mutex_unlock(&slave_mutex); - more_fail: + if (locked) + pthread_mutex_unlock(&slave_mutex); if (node != LINKED_LIST_UNUSED) linked_list_remove(&slave_list, node); return -1; @@ -243,8 +242,7 @@ int advance_slaves(char* command) int signal_slaves = 0; ssize_t node; - if ((errno = pthread_mutex_lock(&slave_mutex))) - return -1; + fail_if ((errno = pthread_mutex_lock(&slave_mutex))); foreach_linked_list_node (slave_list, node) { @@ -261,6 +259,8 @@ int advance_slaves(char* command) pthread_mutex_unlock(&slave_mutex); return 0; + fail: + return -1; } @@ -275,26 +275,23 @@ int advance_slaves(char* command) slave_t* slave_create(hash_table_t* restrict wait_set, const char* restrict recv_client_id, const char* restrict recv_message_id) { slave_t* restrict rc = NULL; + int saved_errno; - if (xmalloc(rc, 1, slave_t)) - return NULL; + fail_if (xmalloc(rc, 1, slave_t)); slave_initialise(rc); rc->wait_set = wait_set; rc->client = parse_client_id(recv_client_id); - if ((rc->client_id = strdup(recv_client_id)) == NULL) - goto fail; - - if ((rc->message_id = strdup(recv_message_id)) == NULL) - goto fail; + fail_if ((rc->client_id = strdup(recv_client_id)) == NULL); + fail_if ((rc->message_id = strdup(recv_message_id)) == NULL); return rc; fail: - slave_destroy(rc); - free(rc); - return NULL; + saved_errno = errno; + slave_destroy(rc), free(rc); + return errno = saved_errno, NULL; } @@ -322,6 +319,9 @@ void slave_initialise(slave_t* restrict this) */ void slave_destroy(slave_t* restrict this) { + if (this == NULL) + return; + if (this->wait_set != NULL) { hash_table_destroy(this->wait_set, (free_func*)reg_table_free_key, NULL); @@ -414,7 +414,8 @@ size_t slave_marshal(const slave_t* restrict this, char* restrict data) size_t slave_unmarshal(slave_t* restrict this, char* restrict data) { size_t key, n, m, rc = 2 * sizeof(int) + sizeof(ssize_t) + sizeof(size_t) + sizeof(uint64_t); - char* protocol; + char* protocol = NULL; + int saved_errno; this->wait_set = NULL; this->client_id = NULL; @@ -431,42 +432,37 @@ size_t slave_unmarshal(slave_t* restrict this, char* restrict data) buf_get_next(data, long, this->dethklok.tv_nsec); n = (strlen((char*)data) + 1) * sizeof(char); - if ((this->client_id = malloc(n)) == NULL) - return 0; + fail_if ((this->client_id = malloc(n)) == NULL); memcpy(this->client_id, data, n); data += n, rc += n; n = (strlen((char*)data) + 1) * sizeof(char); - if ((this->message_id = malloc(n)) == NULL) - return 0; + fail_if ((this->message_id = malloc(n)) == NULL); memcpy(this->message_id, data, n); data += n, rc += n; - if ((this->wait_set = malloc(sizeof(hash_table_t))) == NULL) - return 0; - if (hash_table_create(this->wait_set)) - return 0; + fail_if ((this->wait_set = malloc(sizeof(hash_table_t))) == NULL); + fail_if (hash_table_create(this->wait_set)); buf_get_next(data, size_t, m); while (m--) { n = (strlen((char*)data) + 1) * sizeof(char); - if ((protocol = malloc(n)) == NULL) - return 0; + fail_if ((protocol = malloc(n)) == NULL); memcpy(protocol, data, n); data += n, rc += n; key = (size_t)(void*)protocol; if (hash_table_put(this->wait_set, key, 1) == 0) - if (errno) - { - free(protocol); - return 0; - } + fail_if (errno); } return rc; + fail: + saved_errno = errno; + free(protocol); + return errno = saved_errno, (size_t)0; } diff --git a/src/mds-registry/util.c b/src/mds-registry/util.c index 1963eeb..6b383c2 100644 --- a/src/mds-registry/util.c +++ b/src/mds-registry/util.c @@ -76,14 +76,14 @@ int full_send(const char* message, size_t length) eprint("Sent more of a message than exists in the message, aborting."); return -1; } - else if ((sent < length) && (errno != EINTR)) - { - xperror(*argv); - return -1; - } + else + fail_if ((sent < length) && (errno != EINTR)); message += sent; length -= sent; } return 0; + fail: + xperror(*argv); + return -1; } diff --git a/src/mds-respawn.c b/src/mds-respawn.c index bcbb7fe..b95f40e 100644 --- a/src/mds-respawn.c +++ b/src/mds-respawn.c @@ -157,7 +157,7 @@ int parse_cmdline(void) return 0; - pfail: + fail: xperror(*argv); return 1; } @@ -243,7 +243,7 @@ int preinitialise_server(void) fail_if (xsigaction(SIGUSR2, received_revive) < 0); return 0; - pfail: + fail: xperror(*argv); return 1; } @@ -292,8 +292,7 @@ int postinitialise_server(void) if (commands_args[i] == NULL) j++; else if (strequals(commands_args[i], "--initial-spawn")) - if ((commands_args[i] = strdup("--respawn")) == NULL) - goto pfail; + fail_if ((commands_args[i] = strdup("--respawn")) == NULL); /* Respawn dead and dead and buried servers.*/ @@ -303,7 +302,7 @@ int postinitialise_server(void) spawn_server(i); return 0; - pfail: + fail: xperror(*argv); return 1; } diff --git a/src/mds-server/client.c b/src/mds-server/client.c index 99d561e..f72a2ce 100644 --- a/src/mds-server/client.c +++ b/src/mds-server/client.c @@ -82,16 +82,18 @@ int client_initialise_threading(client_t* restrict this) /* Create mutex to make sure two thread to not try to send messages concurrently, and other client local actions. */ - if ((errno = pthread_mutex_init(&(this->mutex), NULL))) return -1; + fail_if ((errno = pthread_mutex_init(&(this->mutex), NULL))); this->mutex_created = 1; /* Create mutex and codition for multicast interception replies. */ - if ((errno = pthread_mutex_init(&(this->modify_mutex), NULL))) return -1; + fail_if ((errno = pthread_mutex_init(&(this->modify_mutex), NULL))); this->modify_mutex_created = 1; - if ((errno = pthread_cond_init(&(this->modify_cond), NULL))) return -1; + fail_if ((errno = pthread_cond_init(&(this->modify_cond), NULL))); this->modify_cond_created = 1; return 0; + fail: + return -1; } @@ -203,6 +205,7 @@ size_t client_marshal(const client_t* restrict this, char* restrict data) size_t client_unmarshal(client_t* restrict this, char* restrict data) { size_t i, n, rc = sizeof(ssize_t) + 3 * sizeof(int) + sizeof(uint64_t) + 5 * sizeof(size_t); + int saved_errno, stage = 0; this->interception_conditions = NULL; this->multicasts = NULL; this->send_pending = NULL; @@ -218,40 +221,37 @@ size_t client_unmarshal(client_t* restrict this, char* restrict data) buf_get_next(data, uint64_t, this->id); buf_get_next(data, size_t, n); if (n > 0) - if (mds_message_unmarshal(&(this->message), data)) - return 0; + fail_if (mds_message_unmarshal(&(this->message), data)); + stage++; data += n / sizeof(char); rc += n; buf_get_next(data, size_t, this->interception_conditions_count); - if (xmalloc(this->interception_conditions, this->interception_conditions_count, interception_condition_t)) - goto fail; + fail_if (xmalloc(this->interception_conditions, + this->interception_conditions_count, interception_condition_t)); for (i = 0; i < this->interception_conditions_count; i++) { n = interception_condition_unmarshal(this->interception_conditions + i, data); if (n == 0) { this->interception_conditions_count = i - 1; - goto fail; + fail_if (1); } data += n / sizeof(char); rc += n; } buf_get_next(data, size_t, n); - if (xmalloc(this->multicasts, n, multicast_t)) - goto fail; + fail_if (xmalloc(this->multicasts, n, multicast_t)); for (i = 0; i < n; i++, this->multicasts_count++) { size_t m = multicast_unmarshal(this->multicasts + i, data); - if (m == 0) - goto fail; + fail_if (m == 0); data += m / sizeof(char); rc += m; } buf_get_next(data, size_t, this->send_pending_size); if (this->send_pending_size > 0) { - if (xmalloc(this->send_pending, this->send_pending_size, char)) - goto fail; + fail_if (xmalloc(this->send_pending, this->send_pending_size, char)); memcpy(this->send_pending, data, this->send_pending_size * sizeof(char)); data += this->send_pending_size; rc += this->send_pending_size * sizeof(char); @@ -265,6 +265,9 @@ size_t client_unmarshal(client_t* restrict this, char* restrict data) return rc; fail: + saved_errno = errno; + if (stage == 0) + goto done_failing; mds_message_destroy(&(this->message)); for (i = 0; i < this->interception_conditions_count; i++) free(this->interception_conditions[i].condition); @@ -278,7 +281,8 @@ size_t client_unmarshal(client_t* restrict this, char* restrict data) mds_message_destroy(this->modify_message); free(this->modify_message); } - return 0; + done_failing: + return errno = saved_errno, (size_t)0; } /** diff --git a/src/mds-server/interception-condition.c b/src/mds-server/interception-condition.c index 31905c9..cfe5d0c 100644 --- a/src/mds-server/interception-condition.c +++ b/src/mds-server/interception-condition.c @@ -71,10 +71,11 @@ size_t interception_condition_unmarshal(interception_condition_t* restrict this, buf_get_next(data, int64_t, this->priority); buf_get_next(data, int, this->modifying); n = (strlen(data) + 1) * sizeof(char); - if ((this->condition = malloc(n)) == NULL) - return 0; + fail_if ((this->condition = malloc(n)) == NULL); memcpy(this->condition, data, n); return sizeof(size_t) + sizeof(int64_t) + 2 * sizeof(int) + n; + fail: + return 0; } diff --git a/src/mds-server/interceptors.c b/src/mds-server/interceptors.c index 6d798d9..8a24e33 100644 --- a/src/mds-server/interceptors.c +++ b/src/mds-server/interceptors.c @@ -140,19 +140,10 @@ void add_intercept_condition(client_t* client, char* condition, int64_t priority else { /* Duplicate condition string. */ - if ((condition = strdup(condition)) == NULL) - { - xperror(*argv); - return; - } + fail_if ((condition = strdup(condition)) == NULL); /* Grow the interception condition list. */ - if (xrealloc(conds, n + 1, interception_condition_t)) - { - xperror(*argv); - free(condition); - return; - } + fail_if (xrealloc(conds, n + 1, interception_condition_t)); client->interception_conditions = conds; /* Store condition. */ client->interception_conditions_count++; @@ -174,6 +165,12 @@ void add_intercept_condition(client_t* client, char* condition, int64_t priority conds[n] = temp; } } + + return; + fail: + xperror(*argv); + free(condition); + return; } @@ -220,9 +217,7 @@ int find_matching_condition(client_t* client, size_t* hashes, char** keys, char* interception_condition_t* conds = client->interception_conditions; size_t n = 0, i; - errno = pthread_mutex_lock(&(mutex)); - if (errno) - return -1; + fail_if ((errno = pthread_mutex_lock(&(mutex)))); /* Look for a matching condition. */ if (client->open) @@ -240,6 +235,8 @@ int find_matching_condition(client_t* client, size_t* hashes, char** keys, char* pthread_mutex_unlock(&(mutex)); return i < n; + fail: + return -1; } @@ -252,23 +249,22 @@ int find_matching_condition(client_t* client, size_t* hashes, char** keys, char* * @param headers The header name–value pairs * @param count The number of accepted patterns * @param interceptions_count_out Slot at where to store the number of found interceptors - * @return The found interceptors, NULL on error + * @return The found interceptors, `NULL` on error */ queued_interception_t* get_interceptors(client_t* sender, size_t* hashes, char** keys, char** headers, size_t count, size_t* interceptions_count_out) { queued_interception_t* interceptions = NULL; - size_t interceptions_count = 0; - size_t n = 0; + size_t interceptions_count = 0, n = 0; ssize_t node; + int saved_errno; /* Count clients. */ foreach_linked_list_node (client_list, node) n++; /* Allocate interceptor list. */ - if (xmalloc(interceptions, n, queued_interception_t)) - return NULL; + fail_if (xmalloc(interceptions, n, queued_interception_t)); /* Search clients. */ foreach_linked_list_node (client_list, node) @@ -280,11 +276,7 @@ queued_interception_t* get_interceptors(client_t* sender, size_t* hashes, char** { int r = find_matching_condition(client, hashes, keys, headers, count, interceptions + interceptions_count); - if (r == -1) - { - free(interceptions); - return NULL; - } + fail_if (r == -1); if (r) /* List client of there was a matching condition. */ interceptions_count++; @@ -293,5 +285,10 @@ queued_interception_t* get_interceptors(client_t* sender, size_t* hashes, char** *interceptions_count_out = interceptions_count; return interceptions; + + fail: + saved_errno = errno; + free(interceptions); + return errno = saved_errno, NULL; } diff --git a/src/mds-server/interceptors.h b/src/mds-server/interceptors.h index 7bb60e5..e2e6041 100644 --- a/src/mds-server/interceptors.h +++ b/src/mds-server/interceptors.h @@ -77,7 +77,7 @@ int find_matching_condition(client_t* client, size_t* hashes, char** keys, char* * @param headers The header name–value pairs * @param count The number of accepted patterns * @param interceptions_count_out Slot at where to store the number of found interceptors - * @return The found interceptors, NULL on error + * @return The found interceptors, `NULL` on error */ queued_interception_t* get_interceptors(client_t* sender, size_t* hashes, char** keys, char** headers, size_t count, size_t* interceptions_count_out); diff --git a/src/mds-server/mds-server.c b/src/mds-server/mds-server.c index 58eec60..fabdffa 100644 --- a/src/mds-server/mds-server.c +++ b/src/mds-server/mds-server.c @@ -130,8 +130,7 @@ int preinitialise_server(void) close_files((fd > 2) || (fd == socket_fd)); /* Run mdsinitrc. */ - run_initrc(unparsed_args); - return 1; + run_initrc(unparsed_args); /* Does not return. */ } } @@ -148,7 +147,7 @@ int preinitialise_server(void) return 0; - pfail: + fail: xperror(*argv); return 1; } @@ -302,7 +301,7 @@ void* slave_loop(void* data) if ((r == 0) && message_received(information)) goto terminate; else if (r == -2) - goto fail; + goto done; else if (r && (errno == EINTR) && terminating) goto terminate; /* Stop the thread if we are re-exec:ing or terminating the server. */ } @@ -329,7 +328,7 @@ void* slave_loop(void* data) if (reexecing) goto reexec; - fail: /* This done on success as well. */ + done: /* Close socket and free resources. */ close(slave_fd); free(msgbuf); @@ -348,9 +347,9 @@ void* slave_loop(void* data) return NULL; - pfail: + fail: xperror(*argv); - goto fail; + goto done; reexec: @@ -403,15 +402,13 @@ void queue_message_multicast(char* message, size_t length, client_t* sender) uint64_t modify_id; char modify_id_header[13 + 3 * sizeof(uint64_t)]; void* new_buf; + int saved_errno; /* Count the number of headers. */ for (i = 0; i < n; i++) if (message[i] == '\n') - { - header_count++; - if (message[i + 1] == '\n') - break; - } + if (header_count++, message[i + 1] == '\n') + break; if (header_count == 0) return; /* Invalid message. */ @@ -435,14 +432,14 @@ void queue_message_multicast(char* message, size_t length, client_t* sender) if ((header_values[i] = strdup(msg)) == NULL) { header_count = i; - goto pfail; + fail_if (1); } *colon = '\0'; if ((headers[i] = strdup(msg)) == NULL) { - free(headers[i]); + saved_errno = errno, free(headers[i]), errno = saved_errno; header_count = i; - goto pfail; + fail_if (1); } *colon = ':'; *end = '\n'; @@ -482,22 +479,22 @@ void queue_message_multicast(char* message, size_t length, client_t* sender) multicast->message_prefix = n; message = NULL; +#define fail fail_in_mutex /* Queue message multicasting. */ with_mutex (sender->mutex, new_buf = sender->multicasts; - if (xrealloc(new_buf, sender->multicasts_count + 1, multicast_t)) - { - xperror(*argv); - goto fail_queue; - } + fail_if (xrealloc(new_buf, sender->multicasts_count + 1, multicast_t)); sender->multicasts = new_buf; sender->multicasts[sender->multicasts_count++] = *multicast; free(multicast); multicast = NULL; - fail_queue: + errno = 0; + fail_in_mutex: + xperror(*argv); ); +#undef fail - fail: /* This is done before this function returns even if there was no error. */ + done: /* Release resources. */ xfree(headers, header_count); xfree(header_values, header_count); @@ -508,9 +505,9 @@ void queue_message_multicast(char* message, size_t length, client_t* sender) free(multicast); return; - pfail: + fail: xperror(*argv); - goto fail; + goto done; } @@ -582,5 +579,7 @@ void run_initrc(char** args) /* Everything failed. */ eprintf("unable to run %s file, you might as well kill me.", INITRC_FILE); + /* (‘me’ actually refers to the parant, whence it will to be coming.) */ + exit(0); } diff --git a/src/mds-server/mds-server.h b/src/mds-server/mds-server.h index 4d6c5e7..4624761 100644 --- a/src/mds-server/mds-server.h +++ b/src/mds-server/mds-server.h @@ -53,7 +53,7 @@ void queue_message_multicast(char* message, size_t length, client_t* sender); * * @param args The arguments to the child process */ -void run_initrc(char** args); +void run_initrc(char** args) __attribute__((noreturn)); #endif diff --git a/src/mds-server/multicast.c b/src/mds-server/multicast.c index 7a0b309..c3d09bc 100644 --- a/src/mds-server/multicast.c +++ b/src/mds-server/multicast.c @@ -124,8 +124,7 @@ size_t multicast_unmarshal(multicast_t* restrict this, char* restrict data) buf_get_next(data, size_t, this->message_ptr); buf_get_next(data, size_t, this->message_prefix); if (this->interceptions_count > 0) - if (xmalloc(this->interceptions, this->interceptions_count, queued_interception_t)) - return 0; + fail_if (xmalloc(this->interceptions, this->interceptions_count, queued_interception_t)); for (i = 0; i < this->interceptions_count; i++) { n = queued_interception_unmarshal(this->interceptions + i, data); @@ -134,12 +133,13 @@ size_t multicast_unmarshal(multicast_t* restrict this, char* restrict data) } if (this->message_length > 0) { - if (xmalloc(this->message, this->message_length, char)) - return 0; + fail_if (xmalloc(this->message, this->message_length, char)); memcpy(this->message, data, this->message_length * sizeof(char)); rc += this->message_length * sizeof(char); } return rc; + fail: + return 0; } diff --git a/src/mds-server/receiving.c b/src/mds-server/receiving.c index 15ebb4d..8571944 100644 --- a/src/mds-server/receiving.c +++ b/src/mds-server/receiving.c @@ -93,7 +93,7 @@ static int modifying_notify(client_t* client, mds_message_t message, uint64_t mo return 0; - pfail: + fail: xperror(*argv); if (multicast != NULL) { @@ -116,14 +116,13 @@ static int modifying_notify(client_t* client, mds_message_t message, uint64_t mo */ static int add_intercept_conditions_from_message(client_t* client, int modifying, int64_t priority, int stop) { - int errno_ = 0; + int saved_errno; char* payload = client->message.payload; size_t payload_size = client->message.payload_size; size_t size = 64; char* buf; - if (xmalloc(buf, size + 1, char)) - return -1; + fail_if (xmalloc(buf, size + 1, char)); /* All messages */ if (client->message.payload_size == 0) @@ -149,10 +148,10 @@ static int add_intercept_conditions_from_message(client_t* client, int modifying char* old_buf = buf; if (xrealloc(buf, (size <<= 1) + 1, char)) { - errno_ = errno; + saved_errno = errno; free(old_buf); pthread_mutex_unlock(&(client->mutex)); - break; + fail_if (errno = saved_errno, 1); } } memcpy(buf, payload, len); @@ -166,8 +165,9 @@ static int add_intercept_conditions_from_message(client_t* client, int modifying done: free(buf); - errno = errno_; - return errno_ ? -1 : 0; + return 0; + fail: + return -1; } @@ -183,6 +183,7 @@ static int assign_and_send_id(client_t* client, const char* message_id) char* msgbuf = NULL; char* msgbuf_; size_t n; + int rc = -1; /* Construct response. */ n = 2 * 10 + strlen(message_id) + 1; @@ -204,6 +205,7 @@ static int assign_and_send_id(client_t* client, const char* message_id) /* Queue message to be sent when this function returns. This done to simplify `multicast_message` for re-exec and termination. */ +#define fail fail_in_mutex with_mutex (client->mutex, if (client->send_pending_size == 0) { @@ -216,20 +218,20 @@ static int assign_and_send_id(client_t* client, const char* message_id) /* Concatenate message to already pending messages. */ size_t new_len = client->send_pending_size + n; char* msg_new = client->send_pending; - if (xrealloc(msg_new, new_len, char)) - goto fail; + fail_if (xrealloc(msg_new, new_len, char)); memcpy(msg_new + client->send_pending_size, msgbuf, n * sizeof(char)); client->send_pending = msg_new; client->send_pending_size = new_len; } - fail: + (msgbuf = NULL, rc = 0, errno = 0); + fail_in_mutex: ); +#undef fail - return 0; - - pfail: + fail: /* Also success. */ + xperror(*argv); free(msgbuf); - return -1; + return rc; } @@ -327,7 +329,7 @@ int message_received(client_t* client) return 0; - pfail: + fail: xperror(*argv); free(msgbuf); return 0; diff --git a/src/mds-server/reexec.c b/src/mds-server/reexec.c index 981569e..fe8c196 100644 --- a/src/mds-server/reexec.c +++ b/src/mds-server/reexec.c @@ -179,15 +179,13 @@ int unmarshal_server(char* state_buf) ssize_t node; pthread_t slave_thread; - +#define fail soft_fail + /* Create memory address remapping table. */ - if (hash_table_create(&unmarshal_remap_map)) - { - xperror(*argv); - hash_table_destroy(&unmarshal_remap_map, NULL, NULL); - return -1; - } - + fail_if (hash_table_create(&unmarshal_remap_map)); + +#undef fail +#define fail clients_fail /* Get the marshal protocal version. Not needed, there is only the one version right now. */ /* buf_get(state_buf, int, 0, MDS_SERVER_VARS_VERSION); */ @@ -210,20 +208,16 @@ int unmarshal_server(char* state_buf) client_t* value; /* Allocate the client's information. */ - if (xmalloc(value, 1, client_t)) - goto clients_fail; + fail_if (xmalloc(value, 1, client_t)); /* Unmarshal the address, it is used the the client list and the client map, that are also marshalled. */ buf_get_next(state_buf, size_t, value_address); /* Unmarshal the client information. */ - n = client_unmarshal(value, state_buf); - if (n == 0) - goto clients_fail; + fail_if (n = client_unmarshal(value, state_buf), n == 0); /* Populate the remapping table. */ if (hash_table_put(&unmarshal_remap_map, value_address, (size_t)(void*)value) == 0) - if (errno) - goto clients_fail; + fail_if (errno); /* Delayed seeking. */ state_buf += n / sizeof(char); @@ -247,14 +241,15 @@ int unmarshal_server(char* state_buf) break; } +#undef fail +#define fail critical_fail + /* Unmarshal the client list. */ - if (linked_list_unmarshal(&client_list, state_buf)) - goto critical_fail; + fail_if (linked_list_unmarshal(&client_list, state_buf)); state_buf += list_size / sizeof(char); /* Unmarshal the client map. */ - if (fd_table_unmarshal(&client_map, state_buf, unmarshal_remapper)) - goto critical_fail; + fail_if (fd_table_unmarshal(&client_map, state_buf, unmarshal_remapper)); /* Remove non-found elements from the fd table. */ #define __bit(I, _OP_) client_map.used[I / 64] _OP_ ((uint64_t)1 << (I % 64)) @@ -291,8 +286,12 @@ int unmarshal_server(char* state_buf) hash_table_destroy(&unmarshal_remap_map, NULL, NULL); return with_error; +#undef fail - + soft_fail: + xperror(*argv); + hash_table_destroy(&unmarshal_remap_map, NULL, NULL); + return -1; critical_fail: xperror(*argv); abort(); diff --git a/src/mds-server/slavery.c b/src/mds-server/slavery.c index df6d552..088b6af 100644 --- a/src/mds-server/slavery.c +++ b/src/mds-server/slavery.c @@ -47,11 +47,15 @@ void* slave_loop(void*); int fetch_message(client_t* client) { int r = mds_message_read(&(client->message), client->socket_fd); + if (r == 0) return 0; if (r == -2) - eprint("corrupt message received."); + { + eprint("corrupt message received."); + fail_if (1); + } else if (errno == ECONNRESET) { r = mds_message_read(&(client->message), client->socket_fd); @@ -60,11 +64,14 @@ int fetch_message(client_t* client) } else if (errno != EINTR) { - r = -2; xperror(*argv); + fail_if (1); } + fail_if (r == -2); return r; + fail: + return -2; } @@ -81,14 +88,16 @@ int create_slave(pthread_t* thread_slot, int slave_fd) { xperror(*argv); with_mutex (slave_mutex, running_slaves--;); - return -1; + fail_if (1); } if ((errno = pthread_detach(*thread_slot))) { xperror(*argv); - return -1; + fail_if (1); } return 0; + fail: + return -1; } @@ -96,14 +105,13 @@ int create_slave(pthread_t* thread_slot, int slave_fd) * Initialise a client, except for threading * * @param client_fd The file descriptor of the client's socket - * @return The client information, NULL on error + * @return The client information, `NULL` on error */ client_t* initialise_client(int client_fd) { ssize_t entry = LINKED_LIST_UNUSED; - int locked = 0; client_t* information; - int errno_; + int locked = 0, saved_errno; size_t tmp; /* Create information table. */ @@ -131,14 +139,13 @@ client_t* initialise_client(int client_fd) return information; - pfail: - errno_ = errno; + fail: + saved_errno = errno; if (locked) pthread_mutex_unlock(&slave_mutex); free(information); if (entry != LINKED_LIST_UNUSED) with_mutex (slave_mutex, linked_list_remove(&client_list, entry);); - errno = errno_; - return NULL; + return errno = saved_errno, NULL; } diff --git a/src/mds-server/slavery.h b/src/mds-server/slavery.h index 92144fd..00f6084 100644 --- a/src/mds-server/slavery.h +++ b/src/mds-server/slavery.h @@ -45,7 +45,7 @@ int create_slave(pthread_t* thread_slot, int slave_fd); * Initialise a client, except for threading * * @param client_fd The file descriptor of the client's socket - * @return The client information, NULL on error + * @return The client information, `NULL` on error */ client_t* initialise_client(int client_fd); diff --git a/src/mds-vt.c b/src/mds-vt.c index c0a13ef..d761658 100644 --- a/src/mds-vt.c +++ b/src/mds-vt.c @@ -154,21 +154,20 @@ int __attribute__((const)) preinitialise_server(void) static int write_vt_file(void) { char buf[(sizeof(int) + sizeof(struct stat)) / sizeof(char)]; - int fd, r, old_errno; int* intbuf = (int*)buf; + int fd = -1, saved_errno; *intbuf = display_vt; *(struct stat*)(buf + sizeof(int) / sizeof(char)) = old_vt_stat; - fd = open(vtfile_path, O_WRONLY | O_CREAT); - if (fd < 0) - return -1; - - r = full_write(fd, buf, sizeof(buf)); - old_errno = errno; - close(fd); - errno = old_errno; - return r; + fail_if (open(vtfile_path, O_WRONLY | O_CREAT), fd < 0); + fail_if (full_write(fd, buf, sizeof(buf))); + return 0; + fail: + saved_errno = errno; + if (fd >= 0) + close(fd); + return errno = saved_errno, -1; } @@ -183,24 +182,20 @@ static int read_vt_file(void) size_t len; int fd; - fd = open(vtfile_path, O_RDONLY); - if (fd < 0) - return -1; - - buf = full_read(fd, &len); - if (buf == NULL) - return -1; + fail_if (fd = open(vtfile_path, O_RDONLY), fd < 0); + fail_if (buf = full_read(fd, &len), buf == NULL); if (len != sizeof(int) + sizeof(struct stat)) { eprint("VT file is of wrong size."); - errno = 0; - return -1; + return errno = 0, -1; } display_vt = *(int*)buf; old_vt_stat = *(struct stat*)(buf + sizeof(int) / sizeof(char)); return 0; + fail: + return -1; } @@ -215,6 +210,7 @@ int initialise_server(void) struct vt_mode mode; char* display_env; int primary_socket_fd; + int stage = 0; const char* const message = "Command: intercept\n" "Message ID: 0\n" @@ -231,8 +227,7 @@ int initialise_server(void) "Command: switching-vt\n"; primary_socket_fd = socket_fd; - if (connect_to_display()) - return 1; + fail_if (connect_to_display()); secondary_socket_fd = socket_fd; socket_fd = primary_socket_fd; @@ -243,12 +238,12 @@ int initialise_server(void) memset(vtfile_path, 0, sizeof(vtfile_path)); xsnprintf(vtfile_path, "%s/%s.vt", MDS_RUNTIME_ROOT_DIRECTORY, display_env + 1); + stage = 1; if (is_respawn == 0) { display_vt = select_vt(); - if (display_vt < 0) - goto pfail; + fail_if (display_vt < 0); display_tty_fd = vt_open(display_vt, &old_vt_stat); fail_if (write_vt_file() < 0); fail_if (vt_set_active(display_vt) < 0); @@ -260,12 +255,10 @@ int initialise_server(void) fail_if (vt_is_active < 0); } - if (full_send(secondary_socket_fd, secondary_message, strlen(secondary_message))) - return 1; - if (full_send(socket_fd, message, strlen(message))) - return 1; + fail_if (full_send(secondary_socket_fd, secondary_message, strlen(secondary_message))); + fail_if (full_send(socket_fd, message, strlen(message))); fail_if (server_initialised() < 0); - fail_if (mds_message_initialise(&received)); + fail_if (mds_message_initialise(&received)); stage = 2; fail_if (xsigaction(SIGRTMIN + 2, received_switch_vt) < 0); fail_if (xsigaction(SIGRTMIN + 3, received_switch_vt) < 0); @@ -278,12 +271,14 @@ int initialise_server(void) no_display: eprint("no display has been set, how did this happen."); return 1; - pfail: + fail: xperror(*argv); - unlink(vtfile_path); + if (stage >= 1) + unlink(vtfile_path); if (display_tty_fd >= 0) vt_close(display_tty_fd, &old_vt_stat); - mds_message_destroy(&received); + if (stage >= 2) + mds_message_destroy(&received); return 1; } @@ -302,14 +297,15 @@ int postinitialise_server(void) if (reconnect_to_display()) { mds_message_destroy(&received); - return 1; + fail_if (1); } connected = 1; - if ((errno = pthread_create(&secondary_thread, NULL, secondary_loop, NULL))) - return 1; + fail_if ((errno = pthread_create(&secondary_thread, NULL, secondary_loop, NULL))); return 0; + fail: + return 1; } @@ -430,19 +426,18 @@ int master_loop(void) if (r == -2) { eprint("corrupt message received, aborting."); - goto fail; + goto done; } else if (errno == EINTR) continue; - else if (errno != ECONNRESET) - goto pfail; + else + fail_if (errno != ECONNRESET); eprint("lost primary connection to server."); mds_message_destroy(&received); mds_message_initialise(&received); connected = 0; - if (reconnect_to_display()) - goto fail; + fail_if (reconnect_to_display()); connected = 1; } @@ -452,10 +447,10 @@ int master_loop(void) if (unlink(vtfile_path) < 0) xperror(*argv); vt_close(display_tty_fd, &old_vt_stat); - goto fail; - pfail: - xperror(*argv); + goto done; fail: + xperror(*argv); + done: rc |= secondary_thread_failed; if (rc || !reexecing) mds_message_destroy(&received); @@ -490,24 +485,23 @@ void* secondary_loop(void* data) if (r == -2) { eprint("corrupt message received, aborting."); - goto fail; + secondary_thread_failed = 1; + goto done; } else if (errno == EINTR) continue; - else if (errno != ECONNRESET) - goto pfail; + else + fail_if (errno != ECONNRESET); eprint("lost secondary connection to server."); mds_message_destroy(&secondary_received); mds_message_initialise(&secondary_received); - if (reconnect_fd_to_display(&secondary_socket_fd) < 0) - goto fail; + fail_if (reconnect_fd_to_display(&secondary_socket_fd) < 0); } goto done; - pfail: - xperror(*argv); fail: + xperror(*argv); secondary_thread_failed = 1; done: secondary_thread_started = 0; @@ -538,7 +532,10 @@ int switch_vt(int leave_foreground) message_id = message_id == UINT32_MAX ? 0 : (message_id + 1); - return -!!full_send(socket_fd, buf, strlen(buf)); + fail_if (full_send(socket_fd, buf, strlen(buf))); + return 0; + fail: + return -1; } @@ -641,7 +638,10 @@ int handle_get_vt(const char* client, const char* message) message_id = message_id == UINT32_MAX ? 0 : (message_id + 1); r = full_send(socket_fd, buf, strlen(buf)); - return ((active < 0) || r) ? -1 : 0; + fail_if ((active < 0) || r); + return 0; + fail: + return -1; } @@ -685,7 +685,10 @@ int handle_configure_vt(const char* client, const char* message, const char* gra message_id = message_id == UINT32_MAX ? 0 : (message_id + 1); - return -!!full_send(socket_fd, buf, strlen(buf)); + fail_if (full_send(socket_fd, buf, strlen(buf))); + return 0; + fail: + return -1; } @@ -738,15 +741,15 @@ int full_send(int socket, const char* message, size_t length) eprint("Sent more of a message than exists in the message, aborting."); return -1; } - else if ((sent < length) && (errno != EINTR)) - { - xperror(*argv); - return -1; - } + else + fail_if ((sent < length) && (errno != EINTR)); message += sent; length -= sent; } return 0; + fail: + xperror(*argv); + return -1; } @@ -771,7 +774,7 @@ int select_vt(void) if (r < 0) { eprint("the environment variable XDG_VTNR contains an invalid value."); - return errno = 0, -1; + fail_if (errno = 0, 1); } } else @@ -781,11 +784,13 @@ int select_vt(void) if (rc == 0) { eprint("out of available virtual terminals, I am stymied."); - return errno = 0, -1; + fail_if (errno = 0, 1); } } return rc; + fail: + return -1; } @@ -797,10 +802,10 @@ int select_vt(void) int vt_get_next_available(void) { int next_vt = -1; - int r = ioctl(STDIN_FILENO, VT_OPENQRY, &next_vt); - if (r < 0) - return r; + fail_if (ioctl(STDIN_FILENO, VT_OPENQRY, &next_vt) < 0); return ((next_vt < 0) || (MAX_NR_CONSOLES < next_vt)) ? 0 : next_vt; + fail: + return -1; } @@ -812,9 +817,10 @@ int vt_get_next_available(void) int vt_get_active(void) { struct vt_stat state; - if (ioctl(STDIN_FILENO, VT_GETSTATE, &state) < 0) - return -1; + fail_if (ioctl(STDIN_FILENO, VT_GETSTATE, &state) < 0); return state.v_active; + fail: + return -1; } @@ -826,13 +832,13 @@ int vt_get_active(void) */ int vt_set_active(int vt) { - if (ioctl(STDIN_FILENO, VT_ACTIVATE, vt) < 0) - return -1; - + fail_if (ioctl(STDIN_FILENO, VT_ACTIVATE, vt) < 0); if (ioctl(STDIN_FILENO, VT_WAITACTIVE, vt) < 0) xperror(*argv); return 0; + fail: + return -1; } @@ -848,18 +854,16 @@ int vt_open(int vt, struct stat* restrict old_stat) char vtpath[64]; /* Should be small enought and large enought for any lunatic alternative to /dev/ttyNNN, if not you will need to apply a patch (or fix your system.) */ - int fd; + int fd = -1, saved_errno; sprintf(vtpath, VT_PATH_PATTERN, vt); - fd = open(vtpath, O_RDWR); - if (fd < 0) - return -1; - if ((fstat(fd, old_stat) < 0) || - (fchown(fd, getuid(), getgid()) < 0)) - { - close(fd); - return -1; - } + fail_if (fd = open(vtpath, O_RDWR), fd < 0); + fail_if ((fstat(fd, old_stat) < 0) || (fchown(fd, getuid(), getgid()) < 0)); return fd; + fail: + saved_errno = errno; + if (fd >= 0) + close(fd); + return errno = saved_errno, -1; } @@ -73,7 +73,7 @@ int main(int argc_, char** argv_) struct sockaddr_un address; char pathname[PATH_MAX]; char piddata[64]; - unsigned int display; + unsigned int display = DISPLAY_MAX; FILE* f; int rc; int j, r; @@ -116,8 +116,7 @@ int main(int argc_, char** argv_) saved_umask = umask(0); /* Create directory for socket files, PID files and such. */ - if (create_directory_root(MDS_RUNTIME_ROOT_DIRECTORY)) - return 1; + fail_if (create_directory_root(MDS_RUNTIME_ROOT_DIRECTORY)); /* Determine display index. */ @@ -148,14 +147,12 @@ int main(int argc_, char** argv_) /* Yes, the directory could have been removed, but it probably was not. */ /* Create PID file. */ - fail_if ((f = fopen(pathname, "w")) == NULL); + fail_if (f = fopen(pathname, "w"), f == NULL); xsnprintf(piddata, "%u\n", getpid()); if (fwrite(piddata, 1, strlen(piddata), f) < strlen(piddata)) { fclose(f); - if (unlink(pathname) < 0) - xperror(*argv); - return 1; + fail_if (1); } fflush(f); fclose(f); @@ -205,6 +202,9 @@ int main(int argc_, char** argv_) unlink(pathname); } + if (display == DISPLAY_MAX) + return rc; + /* Remove PID file. */ xsnprintf(pathname, "%s/%u.pid", MDS_RUNTIME_ROOT_DIRECTORY, display); unlink(pathname); @@ -217,7 +217,7 @@ int main(int argc_, char** argv_) return rc; - pfail: + fail: xperror(*argv); rc = 1; goto done; @@ -236,9 +236,8 @@ int is_pid_file_reusable(FILE* f) size_t read_len; read_len = fread(piddata, 1, sizeof(piddata) / sizeof(char), f); - if (ferror(f)) /* Failed to read. */ - xperror(*argv); - else if (feof(f) == 0) /* Did not read everything. */ + fail_if (ferror(f)); /* Failed to read. */ + if (feof(f) == 0) /* Did not read everything. */ eprint("the content of a PID file is larger than expected."); else { @@ -251,6 +250,9 @@ int is_pid_file_reusable(FILE* f) } return 0; + fail: + xperror(*argv); + return 0; } @@ -293,11 +295,13 @@ static void exec_master_server(char** child_args) { /* Drop privileges. They most not be propagated non-authorised components. */ /* setgid should not be set, but just to be safe we are restoring both user and group. */ - if (drop_privileges()) - return; + fail_if (drop_privileges()); /* Start master server. */ execv(master_server, child_args); + fail_if (1); + fail: + return; } @@ -336,8 +340,7 @@ int spawn_and_respawn_server(int fd) respawn: pid = fork(); - if (pid == (pid_t)-1) - goto pfail; + fail_if (pid == (pid_t)-1); if (pid == 0) /* Child. */ { @@ -347,7 +350,7 @@ int spawn_and_respawn_server(int fd) umask(saved_umask); /* Change image into the master server. */ exec_master_server(child_args); - goto pfail; + fail_if (1); } @@ -358,13 +361,16 @@ int spawn_and_respawn_server(int fd) xperror(*argv); /* Wait for master server to die. */ - if (uninterruptable_waitpid(pid, &status, 0) == (pid_t)-1) - goto pfail; + fail_if (uninterruptable_waitpid(pid, &status, 0) == (pid_t)-1); /* If the server exited normally or SIGTERM, do not respawn. */ if (WIFEXITED(status) ? (WEXITSTATUS(status) == 0) : ((WTERMSIG(status) == SIGTERM) || (WTERMSIG(status) == SIGINT))) - goto done; /* Child exited normally, stop. */ + { + /* Child exited normally, stop. */ + rc--; + goto done; + } /* Get the current time. (End of child process.) */ time_error |= (monotone(&time_end) < 0); @@ -379,7 +385,7 @@ int spawn_and_respawn_server(int fd) { xperror(*argv); eprintf("`%s' died abnormally, not respawning because we could not read the time.", master_server); - goto fail; + goto done; } /* Respawn if the server did not die too fast. */ @@ -388,7 +394,7 @@ int spawn_and_respawn_server(int fd) else { eprintf("`%s' died abnormally, died too fast, not respawning.", master_server); - goto fail; + goto done; } if (first_spawn) @@ -396,16 +402,13 @@ int spawn_and_respawn_server(int fd) first_spawn = 0; free(child_args[argc + 0]); child_args[argc + 0] = strdup("--respawn"); - if (child_args[argc + 0] == NULL) - goto pfail; + fail_if (child_args[argc + 0] == NULL); } goto respawn; done: - rc--; - fail: rc++; free(child_args[0]); free(child_args[argc + 0]); @@ -413,9 +416,9 @@ int spawn_and_respawn_server(int fd) _exit(1); return rc; - pfail: + fail: xperror(*argv); - goto fail; + goto done; } @@ -442,20 +445,14 @@ int create_directory_root(const char* pathname) else /* Directory is missing, create it. */ if (mkdir(pathname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0) - { - if (errno != EEXIST) /* Unlikely race condition. */ - goto pfail; - } + /* Unlikely race condition. */ + fail_if (errno != EEXIST); else - { - /* Set ownership. */ - if (chown(pathname, ROOT_USER_UID, ROOT_GROUP_GID) < 0) - goto pfail; - } + /* Set ownership. */ + fail_if (chown(pathname, ROOT_USER_UID, ROOT_GROUP_GID) < 0); return 0; - - pfail: + fail: xperror(*argv); return 1; } @@ -482,26 +479,18 @@ int create_directory_user(const char* pathname) } } else - { - /* Directory is missing, create it. */ - if (mkdir(pathname, S_IRWXU) < 0) - { - if (errno != EEXIST) /* Unlikely race condition. */ - { - xperror(*argv); - return 1; - } - } - else - /* Set ownership. */ - if (chown(pathname, getuid(), NOBODY_GROUP_GID) < 0) - { - xperror(*argv); - return 1; - } - } + /* Directory is missing, create it. */ + if (mkdir(pathname, S_IRWXU) < 0) + /* Unlikely race condition. */ + fail_if (errno != EEXIST); + else + /* Set ownership. */ + fail_if (chown(pathname, getuid(), NOBODY_GROUP_GID) < 0); return 0; + fail: + xperror(*argv); + return 1; } @@ -520,12 +509,12 @@ int unlink_recursive(const char* pathname) /* Check that we could examine the directory. */ if (dir == NULL) { - int errno_ = errno; + int saved_errno = errno; struct stat _attr; if (stat(pathname, &_attr) < 0) return 0; /* Directory does not exist. */ - errno = errno_; - goto pfail; + errno = saved_errno; + fail_if (1); } /* Remove the content of the directory. */ @@ -534,14 +523,12 @@ int unlink_recursive(const char* pathname) strcmp(file->d_name, "..") && (unlink(file->d_name) < 0)) { - if (errno != EISDIR) - goto pfail; + fail_if (errno != EISDIR); unlink_recursive(file->d_name); } /* Remove the drectory. */ - if (rmdir(pathname) < 0) - goto pfail; + fail_if (rmdir(pathname) < 0); done: if (dir != NULL) @@ -549,7 +536,7 @@ int unlink_recursive(const char* pathname) return rc; - pfail: + fail: xperror(*argv); rc = -1; goto done; |