X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Futils_tools.c;h=23e4acb42c3e0947a7496cb8801ece1b2fef78fa;hb=965f0e55d4136f7f78aa1bd05695302c980765d2;hp=035e3fc9e699d0b9cf976f68b0ddd416ce6a21e5;hpb=710aad20d338bf8124b8daecb821fcf6a5f55d14;p=platform%2Fupstream%2Fcryptsetup.git diff --git a/src/utils_tools.c b/src/utils_tools.c index 035e3fc..23e4acb 100644 --- a/src/utils_tools.c +++ b/src/utils_tools.c @@ -1,13 +1,15 @@ /* * cryptsetup - setup cryptographic volumes for dm-crypt * - * Copyright (C) 2004, Christophe Saout + * Copyright (C) 2004, Jana Saout * Copyright (C) 2004-2007, Clemens Fruhwirth * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved. + * Copyright (C) 2009-2014, Milan Broz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -28,31 +30,48 @@ int opt_batch_mode = 0; /* interrupt handling */ volatile int quit = 0; +static int signals_blocked = 0; static void int_handler(int sig __attribute__((__unused__))) { quit++; } +int tools_signals_blocked(void) +{ + return signals_blocked; +} + void set_int_block(int block) { sigset_t signals_open; + log_dbg("%slocking interruption on signal.", block ? "B" : "Unb"); + sigemptyset(&signals_open); sigaddset(&signals_open, SIGINT); sigaddset(&signals_open, SIGTERM); sigprocmask(block ? SIG_SETMASK : SIG_UNBLOCK, &signals_open, NULL); + signals_blocked = block; + quit = 0; } -void set_int_handler(void) +void set_int_handler(int block) { struct sigaction sigaction_open; + log_dbg("Installing SIGINT/SIGTERM handler."); memset(&sigaction_open, 0, sizeof(struct sigaction)); sigaction_open.sa_handler = int_handler; sigaction(SIGINT, &sigaction_open, 0); sigaction(SIGTERM, &sigaction_open, 0); - set_int_block(0); + set_int_block(block); +} + +void check_signal(int *r) +{ + if (quit && !*r) + *r = -EINTR; } __attribute__((format(printf, 5, 6))) @@ -115,27 +134,37 @@ int yesDialog(const char *msg, void *usrptr __attribute__((unused))) { char *answer = NULL; size_t size = 0; - int r = 1; + int r = 1, block; + + block = tools_signals_blocked(); + if (block) + set_int_block(0); if(isatty(STDIN_FILENO) && !opt_batch_mode) { log_std("\nWARNING!\n========\n"); log_std("%s\n\nAre you sure? (Type uppercase yes): ", msg); + fflush(stdout); if(getline(&answer, &size, stdin) == -1) { - perror("getline"); - free(answer); - return 0; - } - if(strcmp(answer, "YES\n")) r = 0; - free(answer); + /* Aborted by signal */ + if (!quit) + log_err(_("Error reading response from terminal.\n")); + else + log_dbg("Query interrupted on signal."); + } else if(strcmp(answer, "YES\n")) + r = 0; } + if (block && !quit) + set_int_block(1); + + free(answer); return r; } void show_status(int errcode) { - char error[256], *error_; + char error[256]; if(!opt_verbose) return; @@ -147,12 +176,16 @@ void show_status(int errcode) crypt_get_error(error, sizeof(error)); - if (!error[0]) { - error_ = strerror_r(-errcode, error, sizeof(error)); - if (error_ != error) { + if (*error) { +#ifdef STRERROR_R_CHAR_P /* GNU-specific strerror_r */ + char *error_ = strerror_r(-errcode, error, sizeof(error)); + if (error_ != error) strncpy(error, error_, sizeof(error)); - error[sizeof(error) - 1] = '\0'; - } +#else /* POSIX strerror_r variant */ + if (strerror_r(-errcode, error, sizeof(error))) + *error = '\0'; +#endif + error[sizeof(error) - 1] = '\0'; } log_err(_("Command failed with code %i"), -errcode);