Mercurial > projects > pwm
diff cmd.c @ 19:5c6155c8e9b6
Handle signals
Handled signals are generally blocked and only unblocked when doing blocking
I/O, i.e. either when reading commands or printing results. A (possibly
queued) signal will then interrupt I/O and can be dealt with in the main loop.
author | Guido Berhoerster <guido+pwm@berhoerster.name> |
---|---|
date | Fri, 01 Sep 2017 22:33:41 +0200 |
parents | 1e39a251cbe9 |
children | ec01c579024a |
line wrap: on
line diff
--- a/cmd.c Thu Aug 24 13:10:56 2017 +0200 +++ b/cmd.c Fri Sep 01 22:33:41 2017 +0200 @@ -36,7 +36,9 @@ #include <unistd.h> #include "cmd.h" +#include "io.h" #include "pager.h" +#include "proc.h" #include "pw.h" #include "pwfile.h" #include "util.h" @@ -222,10 +224,14 @@ } if (ctx->errmsg != NULL) { - printf("%s\n", ctx->errmsg); + if (io_printf("%s\n", ctx->errmsg) == IO_SIGNAL) { + return (CMD_SIGNAL); + } } - printf("There are%sunsaved changes\n", ctx->unsaved_changes ? " " : - " no "); + if (io_printf("There are%sunsaved changes\n", + ctx->unsaved_changes ? " " : " no ") == IO_SIGNAL) { + return (CMD_SIGNAL); + } return (CMD_STATUS); } @@ -233,6 +239,7 @@ static enum cmd_return cmd_info(struct pwm_ctx *ctx, int argc, char *argv[]) { + enum cmd_return retval; struct metadata *metadata; struct pager *pager; struct tm *tm; @@ -244,7 +251,7 @@ metadata = pwfile_get_metadata(ctx); - pager = pager_create(stdout); + pager = pager_create(STDOUT_FILENO); pager_printf(pager, "Format: 0x%04x\n", metadata->version); if (metadata->user != NULL) { pager_printf(pager, "User: %s\n", metadata->user); @@ -258,12 +265,12 @@ tm = gmtime(&metadata->timestamp); strftime(timebuf, sizeof (timebuf), TIME_FORMAT, tm); pager_printf(pager, "Last Saved: %s\n", timebuf); - pager_show(pager); + retval = (pager_show(pager) != IO_SIGNAL) ? CMD_OK : CMD_SIGNAL; pager_destroy(pager); pwfile_destroy_metadata(metadata); - return (CMD_OK); + return (retval); } static enum cmd_return @@ -338,7 +345,7 @@ } } - pager = pager_create(stdout); + pager = pager_create(STDOUT_FILENO); list = pwfile_create_list(ctx); for (j = 0; list[j] != NULL; j++) { if (list[j]->any.type == ITEM_TYPE_GROUP) { @@ -363,9 +370,7 @@ pwfile_destroy_record(record); } } - pager_show(pager); - - retval = CMD_OK; + retval = (pager_show(pager) != IO_SIGNAL) ? CMD_OK : CMD_SIGNAL; out: pager_destroy(pager); @@ -633,12 +638,11 @@ pwm_err(ctx, "record %u does not exist", id); goto out; } + retval = CMD_OK; } else { - printf("%s\n", password); + retval = io_printf("%s\n", password); } - retval = CMD_OK; - out: free(char_groupv); @@ -667,14 +671,15 @@ return (CMD_OK); } -static void -print_record(struct record *record, int fields[], int show_labels, FILE *fp) +static int +print_record(struct record *record, int fields[], int show_labels, int fd) { struct pager *pager; struct tm *tm; char timebuf[TIME_SIZE]; + int retval; - pager = pager_create(fp); + pager = pager_create(fd); if (fields[FIELD_TITLE]) { pager_printf(pager, "%s%s\n", show_labels ? field_labels[FIELD_TITLE] : "", (record->title != NULL) ? @@ -717,13 +722,16 @@ pager_printf(pager, "%s%s\n", show_labels ? field_labels[FIELD_MTIME] : "", timebuf); } - pager_show(pager); + retval = pager_show(pager); pager_destroy(pager); + + return (retval); } static enum cmd_return cmd_show(struct pwm_ctx *ctx, int argc, char *argv[]) { + enum cmd_return retval; unsigned int id; struct record *record; int i; @@ -767,10 +775,11 @@ pwm_err(ctx, "record %u does not exist", id); return (CMD_ERR); } - print_record(record, fields, 1, stdout); + retval = (print_record(record, fields, 1, STDOUT_FILENO) != IO_SIGNAL) ? + CMD_OK : CMD_SIGNAL; pwfile_destroy_record(record); - return (CMD_OK); + return (retval); } static enum cmd_return @@ -781,7 +790,7 @@ struct record *record = NULL; enum field_type type; int fields[COUNTOF(field_namev) - 1] = { 0 }; - FILE *fp = NULL; + struct proc proc = { 0 }; if (argc != 4) { return (CMD_USAGE); @@ -799,9 +808,7 @@ } fields[type] = 1; - fp = popen(argv[3], "w"); - if (fp == NULL) { - warn("popen"); + if (proc_open(&proc, argv[3], "w") != IO_OK) { goto out; } @@ -811,14 +818,15 @@ goto out; } - print_record(record, fields, 0, fp); - - retval = CMD_OK; + retval = (print_record(record, fields, 0, proc.fd) != IO_SIGNAL) ? + CMD_OK : CMD_SIGNAL; out: pwfile_destroy_record(record); - if (fp != NULL) { - pclose(fp); + if (proc.pid != 0) { + if (proc_close(&proc) == IO_SIGNAL) { + retval = CMD_SIGNAL; + } } return (retval); @@ -883,6 +891,7 @@ static enum cmd_return cmd_help(struct pwm_ctx *ctx, int argc, char *argv[]) { + enum cmd_return retval = CMD_OK; struct pager *pager; struct cmd *cmd; @@ -890,7 +899,7 @@ return (CMD_USAGE); } - pager = pager_create(stdout); + pager = pager_create(STDOUT_FILENO); if (argc == 2) { for (cmd = cmds; cmd->cmd_func != NULL; cmd++) { if ((strcmp(argv[1], cmd->abbrev_cmd) == 0) || @@ -906,10 +915,10 @@ cmd->full_cmd, cmd->description); } } - pager_show(pager); + retval = (pager_show(pager) != IO_SIGNAL) ? CMD_OK : CMD_SIGNAL; pager_destroy(pager); - return (CMD_OK); + return (retval); } static enum cmd_return