diff options
Diffstat (limited to '')
-rw-r--r-- | cg-remove.c | 564 |
1 files changed, 280 insertions, 284 deletions
diff --git a/cg-remove.c b/cg-remove.c index 0e81df0..20ca51e 100644 --- a/cg-remove.c +++ b/cg-remove.c @@ -23,12 +23,13 @@ static libcoopgamma_context_t cg; /** * Print usage information and exit */ -static void usage(void) +static void +usage(void) { - fprintf(stderr, - "Usage: %s [-M method] [-S site] [-c crtc]... class...\n", - argv0); - exit(1); + fprintf(stderr, + "usage: %s [-M method] [-S site] [-c crtc]... class...\n", + argv0); + exit(1); } @@ -38,22 +39,23 @@ static void usage(void) * * @return Zero on success, -1 on error */ -static int initialise_proc(void) +static int +initialise_proc(void) { - sigset_t sigmask; - int sig; - - for (sig = 1; sig < _NSIG; sig++) - if (signal(sig, SIG_DFL) == SIG_ERR) - if (sig == SIGCHLD) - return -1; - - if (sigemptyset(&sigmask) < 0) - return -1; - if (sigprocmask(SIG_SETMASK, &sigmask, NULL) < 0) - return -1; - - return 0; + sigset_t sigmask; + int sig; + + for (sig = 1; sig < _NSIG; sig++) + if (signal(sig, SIG_DFL) == SIG_ERR) + if (sig == SIGCHLD) + return -1; + + if (sigemptyset(&sigmask) < 0) + return -1; + if (sigprocmask(SIG_SETMASK, &sigmask, NULL) < 0) + return -1; + + return 0; } @@ -63,21 +65,22 @@ static int initialise_proc(void) * * @return Zero on success, -1 on error */ -static int list_methods(void) +static int +list_methods(void) { - char** list; - size_t i; - - list = libcoopgamma_get_methods(); - if (list == NULL) - return -1; - for (i = 0; list[i]; i++) - printf("%s\n", list[i]); - free(list); - if (fflush(stdout) < 0) - return -1; - - return 0; + char **list; + size_t i; + + list = libcoopgamma_get_methods(); + if (!list) + return -1; + for (i = 0; list[i]; i++) + printf("%s\n", list[i]); + free(list); + if (fflush(stdout) < 0) + return -1; + + return 0; } @@ -90,21 +93,22 @@ static int list_methods(void) * @return Zero on success, -1 on error, -2 * on libcoopgamma error */ -static int list_crtcs(void) +static int +list_crtcs(void) { - char** list; - size_t i; - - list = libcoopgamma_get_crtcs_sync(&cg); - if (list == NULL) - return -2; - for (i = 0; list[i]; i++) - printf("%s\n", list[i]); - free(list); - if (fflush(stdout) < 0) - return -1; - - return 0; + char **list; + size_t i; + + list = libcoopgamma_get_crtcs_sync(&cg); + if (!list) + return -2; + for (i = 0; list[i]; i++) + printf("%s\n", list[i]); + free(list); + if (fflush(stdout) < 0) + return -1; + + return 0; } @@ -116,123 +120,119 @@ static int list_crtcs(void) * @return Zero on success, -1 on error, -2 on * libcoopgamma error */ -static int remove_filters(char* const* restrict crtcs, char* const* restrict classes) +static int +remove_filters(char *const *restrict crtcs, char *const *restrict classes) { - size_t n = 0, unsynced = 0, selected, i, j; - char* synced = NULL; - libcoopgamma_async_context_t* asyncs = NULL; - int saved_errno, need_flush = 0, ret = 0; - struct pollfd pollfd; - libcoopgamma_filter_t command; - - for (i = 0; crtcs[i] != NULL; i++); - for (j = 0; classes[j] != NULL; j++); - synced = calloc(i, j * sizeof(*synced)); - if (synced == NULL) - goto fail; - asyncs = calloc(i, j * sizeof(*asyncs)); - if (asyncs == NULL) - goto fail; - - i = j = 0; - command.lifespan = LIBCOOPGAMMA_REMOVE; - pollfd.fd = cg.fd; - pollfd.events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; - - while ((unsynced > 0) || (crtcs[i] != NULL)) - { - wait: - if (crtcs[i] != NULL) - pollfd.events |= POLLOUT; - else - pollfd.events &= ~POLLOUT; - - pollfd.revents = 0; - if (poll(&pollfd, (nfds_t)1, -1) < 0) - goto fail; - - if (pollfd.revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL)) - { - if (need_flush && (libcoopgamma_flush(&cg) < 0)) - goto send_fail; - need_flush = 0; - for (; crtcs[i] != NULL; i++, j = 0) - { - command.crtc = crtcs[i]; - while (classes[j] != NULL) - { - command.class = classes[j++]; - if (unsynced++, libcoopgamma_set_gamma_send(&command, &cg, asyncs + n++) < 0) - goto send_fail; - } - } - goto send_done; - send_fail: - switch (errno) - { - case EINTR: - case EAGAIN: + size_t n = 0, unsynced = 0, selected, i, j; + char *synced = NULL; + libcoopgamma_async_context_t *asyncs = NULL; + int saved_errno, need_flush = 0, ret = 0; + struct pollfd pollfd; + libcoopgamma_filter_t command; + + for (i = 0; crtcs[i]; i++); + for (j = 0; classes[j]; j++); + synced = calloc(i, j * sizeof(*synced)); + if (!synced) + goto fail; + asyncs = calloc(i, j * sizeof(*asyncs)); + if (!asyncs) + goto fail; + + i = j = 0; + command.lifespan = LIBCOOPGAMMA_REMOVE; + pollfd.fd = cg.fd; + pollfd.events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; + + while (unsynced > 0 || crtcs[i]) { + wait: + if (crtcs[i]) + pollfd.events |= POLLOUT; + else + pollfd.events &= ~POLLOUT; + + pollfd.revents = 0; + if (poll(&pollfd, (nfds_t)1, -1) < 0) + goto fail; + + if (pollfd.revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL)) { + if (need_flush && (libcoopgamma_flush(&cg) < 0)) + goto send_fail; + need_flush = 0; + for (; crtcs[i]; i++, j = 0) { + command.crtc = crtcs[i]; + while (classes[j]) { + command.class = classes[j++]; + unsynced++; + if (libcoopgamma_set_gamma_send(&command, &cg, asyncs + n++) < 0) + goto send_fail; + } + } + goto send_done; + send_fail: + switch (errno) { + case EINTR: + case EAGAIN: #if EAGAIN != EWOULDBLOCK - case EWOULDBLOCK: + case EWOULDBLOCK: #endif - need_flush = 1; - if (classes[j] == NULL) - i++, j = 0; - break; - default: - goto fail; - } - } - send_done: - - if ((unsynced == 0) && (crtcs[i] == NULL)) - break; - - if (pollfd.revents & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) - while (unsynced > 0) - switch (libcoopgamma_synchronise(&cg, asyncs, n, &selected)) - { - case 0: - if (synced[selected]) - { - libcoopgamma_skip_message(&cg); - break; + need_flush = 1; + if (!classes[j]) + i++, j = 0; + break; + default: + goto fail; + } } - synced[selected] = 1; - unsynced -= 1; - if (libcoopgamma_set_gamma_recv(&cg, asyncs + selected) < 0) - goto cg_fail; - break; - default: - switch (errno) - { - case 0: - break; - case EINTR: - case EAGAIN: + send_done: + + if (!unsynced && !crtcs[i]) + break; + + if (pollfd.revents & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { + while (unsynced > 0) { + switch (libcoopgamma_synchronise(&cg, asyncs, n, &selected)) { + case 0: + if (synced[selected]) { + libcoopgamma_skip_message(&cg); + break; + } + synced[selected] = 1; + unsynced -= 1; + if (libcoopgamma_set_gamma_recv(&cg, asyncs + selected) < 0) + goto cg_fail; + break; + default: + switch (errno) { + case 0: + break; + case EINTR: + case EAGAIN: #if EAGAIN != EWOULDBLOCK - case EWOULDBLOCK: + case EWOULDBLOCK: #endif - goto wait; - default: - goto fail; + goto wait; + default: + goto fail; + } + break; + } + } } - break; - } - } - - done: - saved_errno = errno; - free(synced); - free(asyncs); - errno = saved_errno; - return ret; - fail: - ret = -1; - goto done; - cg_fail: - ret = -2; - goto done; + } + +done: + saved_errno = errno; + free(synced); + free(asyncs); + errno = saved_errno; + return ret; +fail: + ret = -1; + goto done; +cg_fail: + ret = -2; + goto done; } @@ -255,132 +255,128 @@ static int remove_filters(char* const* restrict crtcs, char* const* restrict cla * @param argv The command line arguments * @return 0 on success, 1 on error */ -int main(int argc, char* argv[]) +int +main(int argc, char *argv[]) { - int stage = 0; - int rc = 0; - char* method = NULL; - char* site = NULL; - char** crtcs_ = NULL; - char** crtcs = alloca(argc * sizeof(char*)); - size_t i, crtcs_n = 0; - - ARGBEGIN - { - case 'M': - if (method != NULL) - usage(); - method = EARGF(usage()); - break; - case 'S': - if (site != NULL) - usage(); - site = EARGF(usage()); - break; - case 'c': - crtcs[crtcs_n++] = EARGF(usage()); - break; - default: - usage(); - } - ARGEND; - - if (initialise_proc() < 0) - goto fail; - - if ((method != NULL) && !strcmp(method, "?")) - { - if ((site != NULL) || (crtcs_n > 0) || (argc > 0)) - usage(); - if (list_methods() < 0) - goto fail; - return 0; - } - - if (libcoopgamma_context_initialise(&cg) < 0) - goto fail; - stage++; - if (libcoopgamma_connect(method, site, &cg) < 0) - { - fprintf(stderr, "%s: server failed to initialise\n", argv0); - goto custom_fail; - } - stage++; - - for (i = 0; i < crtcs_n; i++) - if (!strcmp(crtcs[i], "?")) - { - if (argc > 0) - usage(); - switch (list_crtcs()) - { - case 0: - goto done; - case -1: - goto fail; - default: - goto cg_fail; - } - } - - if (argc == 0) - usage(); - - if (crtcs_n == 0) - { - crtcs = crtcs_ = libcoopgamma_get_crtcs_sync(&cg); - if (crtcs == NULL) - goto cg_fail; - } - else - crtcs[crtcs_n] = NULL; - - if (libcoopgamma_set_nonblocking(&cg, 1) < 0) - goto fail; - - switch (remove_filters(crtcs, argv)) - { - case 0: - break; - case -1: - goto fail; - default: - goto cg_fail; - } - - done: - if (stage >= 1) - libcoopgamma_context_destroy(&cg, stage >= 2); - free(crtcs_); - return rc; - - custom_fail: - rc = 1; - goto done; - - fail: - rc = 1; - perror(argv0); - goto done; + int stage = 0; + int rc = 0; + char *method = NULL; + char *site = NULL; + char **crtcs_ = NULL; + char **crtcs; + size_t i, crtcs_n = 0; + const char *side; + + crtcs = alloca((size_t)argc * sizeof(char *)); + + ARGBEGIN { + case 'M': + if (method) + usage(); + method = EARGF(usage()); + break; + case 'S': + if (site) + usage(); + site = EARGF(usage()); + break; + case 'c': + crtcs[crtcs_n++] = EARGF(usage()); + break; + default: + usage(); + } + ARGEND; + + if (initialise_proc() < 0) + goto fail; + + if (method && !strcmp(method, "?")) { + if (site || crtcs_n > 0 || argc > 0) + usage(); + if (list_methods() < 0) + goto fail; + return 0; + } + + if (libcoopgamma_context_initialise(&cg) < 0) + goto fail; + stage++; + if (libcoopgamma_connect(method, site, &cg) < 0) { + fprintf(stderr, "%s: server failed to initialise\n", argv0); + goto custom_fail; + } + stage++; + + for (i = 0; i < crtcs_n; i++) { + if (!strcmp(crtcs[i], "?")) { + if (argc > 0) + usage(); + switch (list_crtcs()) + { + case 0: + goto done; + case -1: + goto fail; + default: + goto cg_fail; + } + } + } + + if (!argc) + usage(); - cg_fail: - rc = 1; - { - const char* side = cg.error.server_side ? "server" : "client"; - if (cg.error.custom) - { - if ((cg.error.number != 0) || (cg.error.description != NULL)) - fprintf(stderr, "%s: %s-side error number %" PRIu64 ": %s\n", - argv0, side, cg.error.number, cg.error.description); - else if (cg.error.number != 0) - fprintf(stderr, "%s: %s-side error number %" PRIu64 "\n", argv0, side, cg.error.number); - else if (cg.error.description != NULL) - fprintf(stderr, "%s: %s-side error: %s\n", argv0, side, cg.error.description); - } - else if (cg.error.description != NULL) - fprintf(stderr, "%s: %s-side error: %s\n", argv0, side, cg.error.description); - else - fprintf(stderr, "%s: %s-side error: %s\n", argv0, side, strerror(cg.error.number)); - } - goto done; + if (!crtcs_n) { + crtcs = crtcs_ = libcoopgamma_get_crtcs_sync(&cg); + if (!crtcs) + goto cg_fail; + } else { + crtcs[crtcs_n] = NULL; + } + + if (libcoopgamma_set_nonblocking(&cg, 1) < 0) + goto fail; + + switch (remove_filters(crtcs, argv)) { + case 0: + break; + case -1: + goto fail; + default: + goto cg_fail; + } + +done: + if (stage >= 1) + libcoopgamma_context_destroy(&cg, stage >= 2); + free(crtcs_); + return rc; + +custom_fail: + rc = 1; + goto done; + +fail: + rc = 1; + perror(argv0); + goto done; + +cg_fail: + rc = 1; + side = cg.error.server_side ? "server" : "client"; + if (cg.error.custom) { + if (cg.error.number || cg.error.description) + fprintf(stderr, "%s: %s-side error number %" PRIu64 ": %s\n", + argv0, side, cg.error.number, cg.error.description); + else if (cg.error.number) + fprintf(stderr, "%s: %s-side error number %" PRIu64 "\n", argv0, side, cg.error.number); + else if (cg.error.description) + fprintf(stderr, "%s: %s-side error: %s\n", argv0, side, cg.error.description); + } else if (cg.error.description) { + fprintf(stderr, "%s: %s-side error: %s\n", argv0, side, cg.error.description); + } else { + fprintf(stderr, "%s: %s-side error: %s\n", argv0, side, strerror((int)cg.error.number)); + } + goto done; } |