diff options
author | Mattias Andrée <maandree@kth.se> | 2017-11-05 00:09:50 +0100 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2017-11-05 00:09:50 +0100 |
commit | 9e8dec188d55ca1f0a3b33acab702ced8ed07a18 (patch) | |
tree | cbb43c22e72674dc672e645e6596358e3868568e /src/mds-server/mds-server.c | |
parent | typo (diff) | |
download | mds-9e8dec188d55ca1f0a3b33acab702ced8ed07a18.tar.gz mds-9e8dec188d55ca1f0a3b33acab702ced8ed07a18.tar.bz2 mds-9e8dec188d55ca1f0a3b33acab702ced8ed07a18.tar.xz |
Work on changing style, and an important typo fix
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/mds-server/mds-server.c')
-rw-r--r-- | src/mds-server/mds-server.c | 835 |
1 files changed, 408 insertions, 427 deletions
diff --git a/src/mds-server/mds-server.c b/src/mds-server/mds-server.c index cfedf82..bb0e26c 100644 --- a/src/mds-server/mds-server.c +++ b/src/mds-server/mds-server.c @@ -51,29 +51,28 @@ * * This tells the server-base how to behave */ -server_characteristics_t server_characteristics = - { - .require_privileges = 0, - .require_display = 0, /* We will service one ourself. */ - .require_respawn_info = 1, - .sanity_check_argc = 1, - .fork_for_safety = 0, - .danger_is_deadly = 0 - }; - - - -#define __free(I) \ - if (I > 0) pthread_mutex_destroy(&slave_mutex); \ - if (I > 1) pthread_cond_destroy(&slave_cond); \ - if (I > 2) pthread_mutex_destroy(&modify_mutex); \ - if (I > 3) pthread_cond_destroy(&modify_cond); \ - if (I >= 4) hash_table_destroy(&modify_map, NULL, NULL); \ - if (I >= 5) fd_table_destroy(&client_map, NULL, NULL); \ - if (I >= 6) linked_list_destroy(&client_list) - -#define error_if(I, CONDITION) \ - if (CONDITION) { xperror(*argv); __free(I); return 1; } +server_characteristics_t server_characteristics = { + .require_privileges = 0, + .require_display = 0, /* We will service one ourself. */ + .require_respawn_info = 1, + .sanity_check_argc = 1, + .fork_for_safety = 0, + .danger_is_deadly = 0 +}; + + + +#define __free(I)\ + if (I > 0) pthread_mutex_destroy(&slave_mutex);\ + if (I > 1) pthread_cond_destroy(&slave_cond);\ + if (I > 2) pthread_mutex_destroy(&modify_mutex);\ + if (I > 3) pthread_cond_destroy(&modify_cond);\ + if (I >= 4) hash_table_destroy(&modify_map, NULL, NULL);\ + if (I >= 5) fd_table_destroy(&client_map, NULL, NULL);\ + if (I >= 6) linked_list_destroy(&client_list) + +#define error_if(I, CONDITION)\ + if (CONDITION) { xperror(*argv); __free(I); return 1; } /** @@ -82,74 +81,71 @@ server_characteristics_t server_characteristics = * * @return Non-zero on error */ -int preinitialise_server(void) +int +preinitialise_server(void) { - int unparsed_args_ptr = 1; - char* unparsed_args[ARGC_LIMIT + LIBEXEC_ARGC_EXTRA_LIMIT + 1]; - int i; - + int unparsed_args_ptr = 1; + char *unparsed_args[ARGC_LIMIT + LIBEXEC_ARGC_EXTRA_LIMIT + 1]; + char *arg; + int i; + pid_t pid; + #if (LIBEXEC_ARGC_EXTRA_LIMIT < 3) # error LIBEXEC_ARGC_EXTRA_LIMIT is too small, need at least 3. #endif - - - /* Parse command line arguments. */ - for (i = 1; i < argc; i++) - { - char* arg = argv[i]; - if (startswith(arg, "--socket-fd=")) /* Socket file descriptor. */ - { - exit_if (socket_fd != -1, - eprintf("duplicate declaration of %s.", "--socket-fd");); - exit_if (strict_atoi(arg += strlen("--socket-fd="), &socket_fd, 0, INT_MAX) < 0, - eprintf("invalid value for %s: %s.", "--socket-fd", arg);); + + + /* Parse command line arguments. */ + for (i = 1; i < argc; i++) { + arg = argv[i]; + if (startswith(arg, "--socket-fd=")) { /* Socket file descriptor. */ + exit_if (socket_fd != -1, + eprintf("duplicate declaration of %s.", "--socket-fd");); + exit_if (strict_atoi(arg += strlen("--socket-fd="), &socket_fd, 0, INT_MAX) < 0, + eprintf("invalid value for %s: %s.", "--socket-fd", arg);); + } else if (startswith(arg, "--alarm=")) { /* Schedule an alarm signal for forced abort. */ + alarm((unsigned)min(atou(arg + strlen("--alarm=")), 60)); /* At most 1 minute. */ + } else if (!strequals(arg, "--initial-spawn") && !strequals(arg, "--respawn")) { + /* Not recognised, it is probably for another server. */ + unparsed_args[unparsed_args_ptr++] = arg; + } } - else if (startswith(arg, "--alarm=")) /* Schedule an alarm signal for forced abort. */ - alarm((unsigned)min(atou(arg + strlen("--alarm=")), 60)); /* At most 1 minute. */ - else - if (!strequals(arg, "--initial-spawn") && !strequals(arg, "--respawn")) - /* Not recognised, it is probably for another server. */ - unparsed_args[unparsed_args_ptr++] = arg; - } - unparsed_args[unparsed_args_ptr] = NULL; - - /* Check that mandatory arguments have been specified. */ - exit_if (socket_fd < 0, - eprint("missing socket file descriptor argument.");); - - - /* Run mdsinitrc. */ - if (is_respawn == 0) - { - pid_t pid = fork(); - fail_if (pid == (pid_t)-1); - - if (pid == 0) /* Child process exec:s, the parent continues without waiting for it. */ - { - /* Close all files except stdin, stdout and stderr. */ - close_files((fd > 2) || (fd == socket_fd)); - - /* Run mdsinitrc. */ - run_initrc(unparsed_args); /* Does not return. */ + unparsed_args[unparsed_args_ptr] = NULL; + + /* Check that mandatory arguments have been specified. */ + exit_if (socket_fd < 0, eprint("missing socket file descriptor argument.");); + + + /* Run mdsinitrc. */ + if (!is_respawn) { + pid = fork(); + fail_if (pid == (pid_t)-1); + + if (!pid) { /* Child process exec:s, the parent continues without waiting for it. */ + /* Close all files except stdin, stdout and stderr. */ + close_files(fd > 2 || fd == socket_fd); + + /* Run mdsinitrc. */ + run_initrc(unparsed_args); /* Does not return. */ + } } - } - - - /* Create mutex and condition for slave counter. */ - error_if (0, (errno = pthread_mutex_init(&slave_mutex, NULL))); - error_if (1, (errno = pthread_cond_init(&slave_cond, NULL))); - - /* Create mutex, condition and map for message modification. */ - error_if (2, (errno = pthread_mutex_init(&modify_mutex, NULL))); - error_if (3, (errno = pthread_cond_init(&modify_cond, NULL))); - error_if (4, hash_table_create(&modify_map)); - - - return 0; - - fail: - xperror(*argv); - return 1; + + + /* Create mutex and condition for slave counter. */ + error_if (0, (errno = pthread_mutex_init(&slave_mutex, NULL))); + error_if (1, (errno = pthread_cond_init(&slave_cond, NULL))); + + /* Create mutex, condition and map for message modification. */ + error_if (2, (errno = pthread_mutex_init(&modify_mutex, NULL))); + error_if (3, (errno = pthread_cond_init(&modify_cond, NULL))); + error_if (4, hash_table_create(&modify_map)); + + + return 0; + +fail: + xperror(*argv); + return 1; } @@ -159,13 +155,14 @@ int preinitialise_server(void) * * @return Non-zero on error */ -int initialise_server(void) +int +initialise_server(void) { - /* Create list and table of clients. */ - error_if (5, fd_table_create(&client_map)); - error_if (6, linked_list_create(&client_list, 32)); - - return 0; + /* Create list and table of clients. */ + error_if (5, fd_table_create(&client_map)); + error_if (6, linked_list_create(&client_list, 32)); + + return 0; } @@ -175,10 +172,11 @@ int initialise_server(void) * * @return Non-zero on error */ -int __attribute__((const)) postinitialise_server(void) +int __attribute__((const)) +postinitialise_server(void) { - /* We do not need to initialise anything else. */ - return 0; + /* We do not need to initialise anything else. */ + return 0; } @@ -187,33 +185,31 @@ int __attribute__((const)) postinitialise_server(void) * * @return Non-zero on error */ -int master_loop(void) +int +master_loop(void) { - /* Accepting incoming connections and take care of dangers. */ - while (running && (terminating == 0)) - { - if (danger) - { - danger = 0; - with_mutex (slave_mutex, linked_list_pack(&client_list);); + /* Accepting incoming connections and take care of dangers. */ + while (running && !terminating) { + if (danger) { + danger = 0; + with_mutex (slave_mutex, linked_list_pack(&client_list);); + } + + if (accept_connection() == 1) + break; } - - if (accept_connection() == 1) - break; - } - - /* Join with all slaves threads. */ - with_mutex (slave_mutex, - while (running_slaves > 0) - pthread_cond_wait(&slave_cond, &slave_mutex);); - - if (reexecing == 0) - { - /* Release resources. */ - __free(9999); - } - - return 0; + + /* Join with all slaves threads. */ + with_mutex (slave_mutex, + while (running_slaves > 0) + pthread_cond_wait(&slave_cond, &slave_mutex);); + + if (!reexecing) { + /* Release resources. */ + __free(9999); + } + + return 0; } @@ -226,29 +222,29 @@ int master_loop(void) * * @return Zero normally, 1 if terminating */ -int accept_connection(void) +int +accept_connection(void) { - pthread_t slave_thread; - int client_fd; - - /* Accept connection. */ - client_fd = accept(socket_fd, NULL, NULL); - if (client_fd >= 0) - { - /* Increase number of running slaves. */ - with_mutex (slave_mutex, running_slaves++;); - - /* Start slave thread. */ - create_slave(&slave_thread, client_fd); - } - else - /* Handle errors and shutdown. */ - if ((errno == EINTR) && terminating) /* Interrupted for termination. */ - return 1; - else if ((errno == ECONNABORTED) || (errno == EINVAL)) /* Closing. */ - running = 0; - else if (errno != EINTR) /* Error. */ - xperror(*argv); + pthread_t slave_thread; + int client_fd; + + /* Accept connection. */ + client_fd = accept(socket_fd, NULL, NULL); + if (client_fd >= 0) { + /* Increase number of running slaves. */ + with_mutex (slave_mutex, running_slaves++;); + + /* Start slave thread. */ + create_slave(&slave_thread, client_fd); + } else { + /* Handle errors and shutdown. */ + if (errno == EINTR && terminating) /* Interrupted for termination. */ + return 1; + else if (errno == ECONNABORTED || errno == EINVAL) /* Closing. */ + running = 0; + else if (errno != EINTR) /* Error. */ + xperror(*argv); + } return 0; } @@ -259,108 +255,105 @@ int accept_connection(void) * @param data Input data * @return Output data */ -void* slave_loop(void* data) +void * +slave_loop(void *data) { - int slave_fd = (int)(intptr_t)data; - size_t information_address = fd_table_get(&client_map, (size_t)slave_fd); - client_t* information = (client_t*)(void*)information_address; - char* msgbuf = NULL; - char buf[] = "To: all"; - size_t n; - int r; - - - if (information == NULL) /* Did not re-exec. */ - { - /* Initialise the client. */ - fail_if ((information = initialise_client(slave_fd)) == NULL); - - /* Register client to receive broadcasts. */ - add_intercept_condition(information, buf, 0, 0, 0); - } - - /* Store slave thread and create mutexes and conditions. */ - fail_if (client_initialise_threading(information)); - - /* Set up traps for especially handled signals. */ - fail_if (trap_signals() < 0); - - - /* Fetch messages from the slave. */ - while ((terminating == 0) && information->open) - { - /* Send queued multicast messages. */ - send_multicast_queue(information); - - /* Send queued messages. */ - send_reply_queue(information); - - - /* Fetch message. */ - r = fetch_message(information); - if ((r == 0) && message_received(information)) - goto terminate; - else if (r == -2) + int slave_fd = (int)(intptr_t)data; + size_t information_address = fd_table_get(&client_map, (size_t)slave_fd); + client_t *information = (void *)information_address; + char *msgbuf = NULL; + char buf[] = "To: all"; + size_t n; + int r; + + + if (!information) { /* Did not re-exec. */ + /* Initialise the client. */ + fail_if (!(information = initialise_client(slave_fd))); + + /* Register client to receive broadcasts. */ + add_intercept_condition(information, buf, 0, 0, 0); + } + + /* Store slave thread and create mutexes and conditions. */ + fail_if (client_initialise_threading(information)); + + /* Set up traps for especially handled signals. */ + fail_if (trap_signals() < 0); + + + /* Fetch messages from the slave. */ + while (!terminating && information->open) { + /* Send queued multicast messages. */ + send_multicast_queue(information); + + /* Send queued messages. */ + send_reply_queue(information); + + /* Fetch message. */ + r = fetch_message(information); + if (!r && message_received(information)) + goto terminate; + else if (r == -2) + goto done; + else if (r && errno == EINTR && terminating) + goto terminate; /* Stop the thread if we are re-exec:ing or terminating the server. */ + } + /* Stop the thread if we are re-exec:ing or terminating the server. */ + if (terminating) + goto terminate; + + + /* Multicast information about the client closing. */ + n = 2 * 10 + 1 + strlen("Client closed: :\n\n"); + fail_if (xmalloc(msgbuf, n, char)); + snprintf(msgbuf, n, + "Client closed: %" PRIu32 ":%" PRIu32 "\n" + "\n", + (uint32_t)(information->id >> 32), + (uint32_t)(information->id >> 0)); + n = strlen(msgbuf); + queue_message_multicast(msgbuf, n, information); + msgbuf = NULL; + send_multicast_queue(information); + + +terminate: /* This done on success as well. */ + if (reexecing) + goto reexec; + +done: + /* Close socket and free resources. */ + xclose(slave_fd); + free(msgbuf); + if (information) { + /* Unlist and free client. */ + with_mutex (slave_mutex, linked_list_remove(&client_list, information->list_entry);); + client_destroy(information); + } + + /* Unmap client and decrease the slave count. */ + with_mutex (slave_mutex, + fd_table_remove(&client_map, slave_fd); + running_slaves--; + pthread_cond_signal(&slave_cond);); + return NULL; + + +fail: + xperror(*argv); goto done; - else if (r && (errno == EINTR) && terminating) - goto terminate; /* Stop the thread if we are re-exec:ing or terminating the server. */ - } - /* Stop the thread if we are re-exec:ing or terminating the server. */ - if (terminating) - goto terminate; - - - /* Multicast information about the client closing. */ - n = 2 * 10 + 1 + strlen("Client closed: :\n\n"); - fail_if (xmalloc(msgbuf, n, char)); - snprintf(msgbuf, n, - "Client closed: %" PRIu32 ":%" PRIu32 "\n" - "\n", - (uint32_t)(information->id >> 32), - (uint32_t)(information->id >> 0)); - n = strlen(msgbuf); - queue_message_multicast(msgbuf, n, information); - msgbuf = NULL; - send_multicast_queue(information); - - - terminate: /* This done on success as well. */ - if (reexecing) - goto reexec; - - done: - /* Close socket and free resources. */ - xclose(slave_fd); - free(msgbuf); - if (information != NULL) - { - /* Unlist and free client. */ - with_mutex (slave_mutex, linked_list_remove(&client_list, information->list_entry);); - client_destroy(information); - } - - /* Unmap client and decrease the slave count. */ - with_mutex (slave_mutex, - fd_table_remove(&client_map, slave_fd); - running_slaves--; - pthread_cond_signal(&slave_cond);); - return NULL; - - - fail: - xperror(*argv); - goto done; - - - reexec: - /* Tell the master thread that the slave has closed, - this is done because re-exec causes a race-condition - between the acception of a slave and the execution - of the the slave thread. */ - with_mutex (slave_mutex, - running_slaves--; - pthread_cond_signal(&slave_cond);); - return NULL; + + +reexec: + /* Tell the master thread that the slave has closed, + this is done because re-exec causes a race-condition + between the acception of a slave and the execution + of the the slave thread. */ + with_mutex (slave_mutex, + running_slaves--; + pthread_cond_signal(&slave_cond);); + return NULL; } @@ -371,13 +364,12 @@ void* slave_loop(void* data) * @param b:const queued_interception_t* The other of the two interceptors * @return Negative if a before b, positive if a after b, otherwise zero */ -__attribute__((nonnull)) -static int cmp_queued_interception(const void* a, const void* b) +static int __attribute__((nonnull)) +cmp_queued_interception(const void *a, const void *b) { - const queued_interception_t* p = b; /* Highest first, so swap them. */ - const queued_interception_t* q = a; - return p->priority < q->priority ? -1 : - p->priority > q->priority ? 1 : 0; + const queued_interception_t *p = b; /* Highest first, so swap them. */ + const queued_interception_t *q = a; + return p->priority < q->priority ? -1 : p->priority > q->priority; } @@ -388,127 +380,127 @@ static int cmp_queued_interception(const void* a, const void* b) * @param length The length of the message * @param sender The original sender of the message */ -void queue_message_multicast(char* message, size_t length, client_t* sender) +void +queue_message_multicast(char *message, size_t length, client_t *sender) { - char* msg = message; - size_t header_count = 0; - size_t n = length - 1; - size_t* hashes = NULL; - char** headers = NULL; - char** header_values = NULL; - queued_interception_t* interceptions = NULL; - size_t interceptions_count = 0; - multicast_t* multicast = NULL; - size_t i; - 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') - if (header_count++, message[i + 1] == '\n') - break; - - if (header_count == 0) - return; /* Invalid message. */ - - /* Allocate multicast message. */ - fail_if (xmalloc(multicast, 1, multicast_t)); - multicast_initialise(multicast); - - /* Allocate header lists. */ - fail_if (xmalloc(hashes, header_count, size_t)); - fail_if (xmalloc(headers, header_count, char*)); - fail_if (xmalloc(header_values, header_count, char*)); - - /* Populate header lists. */ - for (i = 0; i < header_count; i++) - { - char* end = strchr(msg, '\n'); - char* colon = strchr(msg, ':'); - - *end = '\0'; - if (xstrdup(header_values[i], msg)) - { - header_count = i; - fail_if (1); - } - *colon = '\0'; - if (xstrdup(headers[i], msg)) - { - saved_errno = errno, free(headers[i]), errno = saved_errno; - header_count = i; - fail_if (1); - } - *colon = ':'; - *end = '\n'; - hashes[i] = string_hash(headers[i]); - - msg = end + 1; - } - - /* Get intercepting clients. */ - pthread_mutex_lock(&(slave_mutex)); - interceptions = get_interceptors(sender, hashes, headers, header_values, header_count, &interceptions_count); - pthread_mutex_unlock(&(slave_mutex)); - fail_if (interceptions == NULL); - - /* Sort interceptors. */ - qsort(interceptions, interceptions_count, sizeof(queued_interception_t), cmp_queued_interception); - - /* Add prefix to message with ‘Modify ID’ header. */ - with_mutex (slave_mutex, - modify_id = next_modify_id++; - if (next_modify_id == 0) - next_modify_id = 1; - ); - xsnprintf(modify_id_header, "Modify ID: %" PRIu64 "\n", modify_id); - n = strlen(modify_id_header); - new_buf = message; - fail_if (xrealloc(new_buf, n + length, char)); - message = new_buf; - memmove(message + n, message, length * sizeof(char)); - memcpy(message, modify_id_header, n * sizeof(char)); - - /* Store information. */ - multicast->interceptions = interceptions; - multicast->interceptions_count = interceptions_count; - multicast->message = message; - multicast->message_length = length + n; - multicast->message_prefix = n; - message = NULL; - -#define fail fail_in_mutex - /* Queue message multicasting. */ - with_mutex (sender->mutex, - new_buf = sender->multicasts; - 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; - errno = 0; - fail_in_mutex: - xperror(*argv); - ); + char *msg = message; + size_t header_count = 0; + size_t n = length - 1; + size_t *hashes = NULL; + char **headers = NULL; + char **header_values = NULL; + queued_interception_t *interceptions = NULL; + size_t interceptions_count = 0; + multicast_t *multicast = NULL; + size_t i; + uint64_t modify_id; + char modify_id_header[13 + 3 * sizeof(uint64_t)]; + void *new_buf; + int saved_errno; + char *end, *colon; + + /* Count the number of headers. */ + for (i = 0; i < n; i++) + if (message[i] == '\n') + if (header_count++, message[i + 1] == '\n') + break; + + if (!header_count) + return; /* Invalid message. */ + + /* Allocate multicast message. */ + fail_if (xmalloc(multicast, 1, multicast_t)); + multicast_initialise(multicast); + + /* Allocate header lists. */ + fail_if (xmalloc(hashes, header_count, size_t)); + fail_if (xmalloc(headers, header_count, char *)); + fail_if (xmalloc(header_values, header_count, char *)); + + /* Populate header lists. */ + for (i = 0; i < header_count; i++) + { + end = strchr(msg, '\n'); + colon = strchr(msg, ':'); + + *end = '\0'; + if (xstrdup(header_values[i], msg)) { + header_count = i; + fail_if (1); + } + *colon = '\0'; + if (xstrdup(headers[i], msg)) { + saved_errno = errno, free(headers[i]), errno = saved_errno; + header_count = i; + fail_if (1); + } + *colon = ':'; + *end = '\n'; + hashes[i] = string_hash(headers[i]); + + msg = end + 1; + } + + /* Get intercepting clients. */ + pthread_mutex_lock(&(slave_mutex)); + interceptions = get_interceptors(sender, hashes, headers, header_values, header_count, &interceptions_count); + pthread_mutex_unlock(&(slave_mutex)); + fail_if (!interceptions); + + /* Sort interceptors. */ + qsort(interceptions, interceptions_count, sizeof(queued_interception_t), cmp_queued_interception); + + /* Add prefix to message with ‘Modify ID’ header. */ + with_mutex (slave_mutex, + modify_id = next_modify_id++; + if (!next_modify_id) + next_modify_id = 1; + ); + xsnprintf(modify_id_header, "Modify ID: %" PRIu64 "\n", modify_id); + n = strlen(modify_id_header); + new_buf = message; + fail_if (xrealloc(new_buf, n + length, char)); + message = new_buf; + memmove(message + n, message, length * sizeof(char)); + memcpy(message, modify_id_header, n * sizeof(char)); + + /* Store information. */ + multicast->interceptions = interceptions; + multicast->interceptions_count = interceptions_count; + multicast->message = message; + multicast->message_length = length + n; + multicast->message_prefix = n; + message = NULL; + +#define fail fail_in_mutex + /* Queue message multicasting. */ + with_mutex (sender->mutex, + new_buf = sender->multicasts; + 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; + errno = 0; + fail_in_mutex: + xperror(*argv); + ); #undef fail - - done: - /* Release resources. */ - xfree(headers, header_count); - xfree(header_values, header_count); - free(hashes); - free(message); - if (multicast != NULL) - multicast_destroy(multicast); - free(multicast); - return; - - fail: - xperror(*argv); - goto done; + +done: + /* Release resources. */ + xfree(headers, header_count); + xfree(header_values, header_count); + free(hashes); + free(message); + if (multicast) + multicast_destroy(multicast); + free(multicast); + return; + +fail: + xperror(*argv); + goto done; } @@ -517,70 +509,59 @@ 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) { - char pathname[PATH_MAX]; - struct passwd* pwd; - char* env; - char* home; - args[0] = pathname; - -#define __exec(FORMAT, ...) \ - xsnprintf(pathname, FORMAT, __VA_ARGS__); execv(args[0], args) - - /* Test $XDG_CONFIG_HOME. */ - if ((env = getenv_nonempty("XDG_CONFIG_HOME")) != NULL) - { - __exec("%s/%s", env, INITRC_FILE); - } - - /* Test $HOME. */ - if ((env = getenv_nonempty("HOME")) != NULL) - { - __exec("%s/.config/%s", env, INITRC_FILE); - __exec("%s/.%s", env, INITRC_FILE); - } - - /* Test ~. */ - pwd = getpwuid(getuid()); /* Ignore error. */ - if (pwd != NULL) - { - home = pwd->pw_dir; - if ((home != NULL) && (*home != '\0')) - { - __exec("%s/.config/%s", home, INITRC_FILE); - __exec("%s/.%s", home, INITRC_FILE); + char pathname[PATH_MAX]; + struct passwd *pwd; + char *env, *home, *begin, *end; + int len; + + args[0] = pathname; + +#define __exec(FORMAT, ...)\ + (xsnprintf(pathname, FORMAT, __VA_ARGS__), execv(args[0], args)) + + /* Test $XDG_CONFIG_HOME. */ + if ((env = getenv_nonempty("XDG_CONFIG_HOME"))) + __exec("%s/%s", env, INITRC_FILE); + + /* Test $HOME. */ + if ((env = getenv_nonempty("HOME"))) { + __exec("%s/.config/%s", env, INITRC_FILE); + __exec("%s/.%s", env, INITRC_FILE); } - } - - /* Test $XDG_CONFIG_DIRS. */ - if ((env = getenv_nonempty("XDG_CONFIG_DIRS")) != NULL) - { - char* begin = env; - char* end; - int len; - for (;;) - { - end = strchrnul(begin, ':'); - len = (int)(end - begin); - if (len > 0) - { - __exec("%.*s/%s", len, begin, INITRC_FILE); - } - if (*end == '\0') - break; - begin = end + 1; + + /* Test ~. */ + pwd = getpwuid(getuid()); /* Ignore error. */ + if (pwd) { + home = pwd->pw_dir; + if (home && *home) { + __exec("%s/.config/%s", home, INITRC_FILE); + __exec("%s/.%s", home, INITRC_FILE); + } + } + + /* Test $XDG_CONFIG_DIRS. */ + if ((env = getenv_nonempty("XDG_CONFIG_DIRS"))) { + for (begin = env;;) { + end = strchrnul(begin, ':'); + len = (int)(end - begin); + if (len > 0) + __exec("%.*s/%s", len, begin, INITRC_FILE); + if (!*end) + break; + begin = end + 1; + } } - } - - /* Test /etc. */ - __exec("%s/%s", SYSCONFDIR, INITRC_FILE); + + /* Test /etc. */ + __exec("%s/%s", SYSCONFDIR, INITRC_FILE); #undef __exec - - /* 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); -} + /* 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); +} |