From b8da6570e03eb22982366145b77030149bdd5242 Mon Sep 17 00:00:00 2001 From: void!yura Date: Mon, 7 Feb 2005 20:44:07 +0000 Subject: [PATCH] ntfscp: Added SIGINT (Ctrl+C) handler, improved error handling in sync failed case. (Yura) (Logical change 1.675) --- ChangeLog | 2 ++ ntfsprogs/ntfscp.c | 46 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 01b98021..b2945e9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -103,6 +103,8 @@ xx/xx/2005 - 2.0.0-WIP kernel driver. (Yura) - Port logfile checking routines from the kernel to the library and integrate them with mount process. (Yura) + - ntfscp: Added SIGINT (Ctrl+C) handler, improved error handling in + sync failed case. (Yura) 04/09/2004 - 1.9.4 - Urgent bug fixes. diff --git a/ntfsprogs/ntfscp.c b/ntfsprogs/ntfscp.c index de7d61f4..a8b93348 100644 --- a/ntfsprogs/ntfscp.c +++ b/ntfsprogs/ntfscp.c @@ -1,7 +1,7 @@ /** * ntfscp - Part of the Linux-NTFS project. * - * Copyright (c) 2004 Yura Pakhuchiy + * Copyright (c) 2004-2005 Yura Pakhuchiy * * This utility will overwrite files on ntfs volume * @@ -27,7 +27,9 @@ #include #include #include +#include #include +#include #include "types.h" #include "attrib.h" @@ -50,6 +52,7 @@ struct options { static const char *EXEC_NAME = "ntfscp"; static struct options opts; +static int caught_sigint = 0; GEN_PRINTF (Eprintf, stderr, NULL, FALSE) GEN_PRINTF (Vprintf, stderr, &opts.verbose, TRUE) @@ -229,6 +232,20 @@ static int parse_options (int argc, char **argv) return (!err && !help && !ver); } +/** + * sigint_handler - Handle SIGINT: abort write, sync and exit. + */ +static void sigint_handler(int arg __attribute__((unused))) +{ + caught_sigint++; + if (caught_sigint > 3) { + Eprintf("SIGTERM received more than 3 times. " + "Exit immediately.\n"); + exit(2); + } else + Eprintf("SIGTERM received. Aborting write.\n"); +} + /** * main - Begin here * @@ -257,6 +274,12 @@ int main (int argc, char *argv[]) utils_set_locale(); + /* Set SIGINT handler. */ + if (signal(SIGINT, sigint_handler) == SIG_ERR) { + perror("Failed to set SIGINT handler"); + return 1; + } + if (opts.noaction) flags = MS_RDONLY; @@ -338,11 +361,12 @@ int main (int argc, char *argv[]) goto close_attr; } + Vprintf("Starting write.\n"); offset = 0; - while (!feof(in)) { + while (!feof(in) && !caught_sigint) { br = fread(buf, 1, NTFS_BUF_SIZE, in); if (!br) { - if (!feof(in)) perror("ERROR: fread failed"); + if (!feof(in)) perror("ERROR: fread failed"); break; } bw = ntfs_attr_pwrite(na, offset, br, buf); @@ -352,16 +376,24 @@ int main (int argc, char *argv[]) } offset += bw; } + Vprintf("Syncing.\n"); result = 0; free(buf); close_attr: ntfs_attr_close(na); close_dst: - ntfs_inode_close(out); + while (ntfs_inode_close(out)) { + if (errno != EBUSY) { + Eprintf("Sync failed. Run chkdsk.\n"); + break; + } + Eprintf("Device busy. Will retry sync after 3 seconds.\n"); + sleep(3); + } close_src: - fclose (in); + fclose(in); umount: - ntfs_umount (vol, FALSE); - + ntfs_umount(vol, FALSE); + Vprintf("Done.\n"); return result; }