From 7abc5fe195cfa203d215781e2a04672cebecca1e Mon Sep 17 00:00:00 2001 From: bigbiff Date: Sat, 17 Jan 2015 16:53:12 -0500 Subject: Add cancel backup capability. This will stop the iteration of the partition objects, kill the current twrpTar thread and remove the backup directory. Implement TWAtomicInt class to give us a wrapper that automatically uses mutexes before the read and write to help ensure that the reads and writes will be atomic based on documentation. Change-Id: I645b22bc980a292e9c7202acb24ffd22ebe68c63 --- Android.mk | 2 +- gui/action.cpp | 52 ++++++++++++++++++++----- gui/devices/480x854/res/ui.xml | 1 + gui/devices/landscape/res/landscape.xml | 25 +++++++++++- gui/devices/portrait/res/portrait.xml | 23 +++++++++++ gui/devices/watch/res/watch.xml | 27 +++++++++++++ gui/objects.hpp | 1 + partition.cpp | 11 +++--- partitionmanager.cpp | 36 +++++++++++++++-- partitions.hpp | 11 ++++-- tw_atomic.cpp | 68 +++++++++++++++++++++++++++++++++ tw_atomic.hpp | 36 +++++++++++++++++ twrp-functions.cpp | 2 +- twrpTar.cpp | 30 +++++++++------ twrpTar.hpp | 3 +- 15 files changed, 293 insertions(+), 35 deletions(-) create mode 100644 tw_atomic.cpp create mode 100644 tw_atomic.hpp diff --git a/Android.mk b/Android.mk index bd5c33ccb..e76a3a91f 100644 --- a/Android.mk +++ b/Android.mk @@ -454,7 +454,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := libaosprecovery LOCAL_MODULE_TAGS := eng optional LOCAL_C_INCLUDES := $(LOCAL_PATH)/libmincrypt/includes -LOCAL_SRC_FILES := adb_install.cpp asn1_decoder.cpp bootloader.cpp legacy_property_service.c verifier.cpp set_metadata.c +LOCAL_SRC_FILES := adb_install.cpp asn1_decoder.cpp bootloader.cpp legacy_property_service.c verifier.cpp set_metadata.c tw_atomic.cpp LOCAL_SHARED_LIBRARIES += libc liblog libcutils libmtdutils libfusesideload libmincrypttwrp libselinux ifneq ($(BOARD_RECOVERY_BLDRMSG_OFFSET),) diff --git a/gui/action.cpp b/gui/action.cpp index d75843044..e7f74d48a 100644 --- a/gui/action.cpp +++ b/gui/action.cpp @@ -56,6 +56,7 @@ extern "C" { #include "rapidxml.hpp" #include "objects.hpp" +#include "../tw_atomic.hpp" void curtainClose(void); @@ -169,6 +170,7 @@ GUIAction::GUIAction(xml_node<>* node) mf["fixsu"] = &GUIAction::fixsu; mf["startmtp"] = &GUIAction::startmtp; mf["stopmtp"] = &GUIAction::stopmtp; + mf["cancelbackup"] = &GUIAction::cancelbackup; // remember actions that run in the caller thread for (mapFunc::const_iterator it = mf.begin(); it != mf.end(); ++it) @@ -314,6 +316,13 @@ void GUIAction::simulate_progress_bar(void) gui_print("Simulating actions...\n"); for (int i = 0; i < 5; i++) { + if (PartitionManager.stop_backup.get_value()) { + DataManager::SetValue("tw_cancel_backup", 1); + gui_print("Backup Canceled.\n"); + DataManager::SetValue("ui_progress", 0); + PartitionManager.stop_backup.set_value(0); + return; + } usleep(500000); DataManager::SetValue("ui_progress", i * 20); } @@ -1087,13 +1096,13 @@ int GUIAction::refreshsizes(std::string arg) int GUIAction::nandroid(std::string arg) { - operation_start("Nandroid"); - int ret = 0; - if (simulate) { DataManager::SetValue("tw_partition", "Simulation"); simulate_progress_bar(); } else { + operation_start("Nandroid"); + int ret = 0; + if (arg == "backup") { string Backup_Name; DataManager::GetValue(TW_BACKUP_NAME, Backup_Name); @@ -1103,7 +1112,6 @@ int GUIAction::nandroid(std::string arg) else { operation_end(1); return -1; - } DataManager::SetValue(TW_BACKUP_NAME, "(Auto Generate)"); } else if (arg == "restore") { @@ -1112,16 +1120,42 @@ int GUIAction::nandroid(std::string arg) ret = PartitionManager.Run_Restore(Restore_Name); } else { operation_end(1); - return -1; - } - } - DataManager::SetValue("tw_encrypt_backup", 0); + return -1; + } + DataManager::SetValue("tw_encrypt_backup", 0); + if (!PartitionManager.stop_backup.get_value()) { if (ret == false) ret = 1; // 1 for failure else ret = 0; // 0 for success + DataManager::SetValue("tw_cancel_backup", 0); operation_end(ret); - return 0; + } + else { + DataManager::SetValue("tw_cancel_backup", 1); + gui_print("Backup Canceled.\n"); + ret = 0; + } + return ret; + } + return 0; +} + +int GUIAction::cancelbackup(std::string arg) { + if (simulate) { + simulate_progress_bar(); + PartitionManager.stop_backup.set_value(1); + operation_end(0); + } + else { + operation_start("Cancel Backup"); + int op_status = PartitionManager.Cancel_Backup(); + if (op_status != 0) + op_status = 1; // failure + operation_end(op_status); + } + + return 0; } int GUIAction::fixpermissions(std::string arg) diff --git a/gui/devices/480x854/res/ui.xml b/gui/devices/480x854/res/ui.xml index dd7efd720..c4ce65f35 100644 --- a/gui/devices/480x854/res/ui.xml +++ b/gui/devices/480x854/res/ui.xml @@ -50,6 +50,7 @@ + diff --git a/gui/devices/landscape/res/landscape.xml b/gui/devices/landscape/res/landscape.xml index f66eb8bb6..eb6d9ddd6 100644 --- a/gui/devices/landscape/res/landscape.xml +++ b/gui/devices/landscape/res/landscape.xml @@ -670,7 +670,7 @@ - + Cancel @@ -2157,6 +2157,17 @@ + + + + + Cancel + + + + + + @@ -2165,6 +2176,7 @@ + tw_back=backup tw_complete_text1=Backup Complete @@ -2173,6 +2185,17 @@ + + + + + tw_back=backup + tw_complete_text1=Backup Cancelled + tw_show_reboot=1 + action_complete + + + diff --git a/gui/devices/portrait/res/portrait.xml b/gui/devices/portrait/res/portrait.xml index bb8e37217..fe6167155 100644 --- a/gui/devices/portrait/res/portrait.xml +++ b/gui/devices/portrait/res/portrait.xml @@ -1867,6 +1867,17 @@ + + + + + Cancel + + + + + + @@ -1875,6 +1886,7 @@ + tw_back=backup tw_complete_text1=Backup Complete @@ -1882,6 +1894,17 @@ action_complete + + + + + + tw_back=backup + tw_complete_text1=Backup Cancelled + tw_show_reboot=1 + action_complete + + diff --git a/gui/devices/watch/res/watch.xml b/gui/devices/watch/res/watch.xml index dc787b37c..49e172e3a 100644 --- a/gui/devices/watch/res/watch.xml +++ b/gui/devices/watch/res/watch.xml @@ -1859,6 +1859,21 @@ + + + + + + + + + Cancel + + + + + + @@ -1867,6 +1882,7 @@ + tw_back=backup tw_complete_text1=Backup Complete @@ -1874,6 +1890,17 @@ action_complete + + + + + + tw_back=backup + tw_complete_text1=Backup Cancelled + tw_show_reboot=1 + action_complete + + diff --git a/gui/objects.hpp b/gui/objects.hpp index 99b585507..832569c1d 100644 --- a/gui/objects.hpp +++ b/gui/objects.hpp @@ -360,6 +360,7 @@ protected: int startmtp(std::string arg); int stopmtp(std::string arg); int flashimage(std::string arg); + int cancelbackup(std::string arg); int simulate; }; diff --git a/partition.cpp b/partition.cpp index db1f0581c..e30e6c11d 100644 --- a/partition.cpp +++ b/partition.cpp @@ -1253,9 +1253,10 @@ bool TWPartition::Repair() { return false; } -bool TWPartition::Backup(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size) { - if (Backup_Method == FILES) - return Backup_Tar(backup_folder, overall_size, other_backups_size); +bool TWPartition::Backup(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size, pid_t &tar_fork_pid) { + if (Backup_Method == FILES) { + return Backup_Tar(backup_folder, overall_size, other_backups_size, tar_fork_pid); + } else if (Backup_Method == DD) return Backup_DD(backup_folder); else if (Backup_Method == FLASH_UTILS) @@ -1702,7 +1703,7 @@ bool TWPartition::Wipe_Data_Without_Wiping_Media() { #endif // ifdef TW_OEM_BUILD } -bool TWPartition::Backup_Tar(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size) { +bool TWPartition::Backup_Tar(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size, pid_t &tar_fork_pid) { char back_name[255], split_index[5]; string Full_FileName, Split_FileName, Tar_Args, Command; int use_compression, use_encryption = 0, index, backup_count; @@ -1744,7 +1745,7 @@ bool TWPartition::Backup_Tar(string backup_folder, const unsigned long long *ove tar.setsize(Backup_Size); tar.partition_name = Backup_Name; tar.backup_folder = backup_folder; - if (tar.createTarFork(overall_size, other_backups_size) != 0) + if (tar.createTarFork(overall_size, other_backups_size, tar_fork_pid) != 0) return false; return true; } diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 23632d28f..8e75a9a06 100644 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -1,5 +1,5 @@ /* - Copyright 2012 bigbiff/Dees_Troy TeamWin + Copyright 2014 TeamWin This file is part of TWRP/TeamWin Recovery Project. TWRP is free software: you can redistribute it and/or modify @@ -39,6 +39,7 @@ #include "twrpDigest.hpp" #include "twrpDU.hpp" #include "set_metadata.h" +#include "tw_atomic.hpp" #ifdef TW_HAS_MTP #include "mtp/mtp_MtpServer.hpp" @@ -59,6 +60,8 @@ extern bool datamedia; TWPartitionManager::TWPartitionManager(void) { mtp_was_enabled = false; mtp_write_fd = -1; + stop_backup.set_value(0); + tar_fork_pid = 0; } int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) { @@ -559,7 +562,7 @@ bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folde TWFunc::SetPerformanceMode(true); time(&start); - if (Part->Backup(Backup_Folder, &total_size, ¤t_size)) { + if (Part->Backup(Backup_Folder, &total_size, ¤t_size, tar_fork_pid)) { bool md5Success = false; current_size += Part->Backup_Size; pos = (float)((float)(current_size) / (float)(total_size)); @@ -569,7 +572,7 @@ bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folde for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) { if ((*subpart)->Can_Be_Backed_Up && (*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == Part->Mount_Point) { - if (!(*subpart)->Backup(Backup_Folder, &total_size, ¤t_size)) { + if (!(*subpart)->Backup(Backup_Folder, &total_size, ¤t_size, tar_fork_pid)) { TWFunc::SetPerformanceMode(false); return false; } @@ -608,6 +611,30 @@ bool TWPartitionManager::Backup_Partition(TWPartition* Part, string Backup_Folde TWFunc::SetPerformanceMode(false); return false; } + return 0; +} + +int TWPartitionManager::Cancel_Backup() { + string Backup_Folder, Backup_Name, Full_Backup_Path; + + stop_backup.set_value(1); + + if (tar_fork_pid != 0) { + DataManager::GetValue(TW_BACKUP_NAME, Backup_Name); + DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, Backup_Folder); + Full_Backup_Path = Backup_Folder + "/" + Backup_Name + "/"; + LOGINFO("Killing pid: %d\n", tar_fork_pid); + kill(tar_fork_pid, SIGUSR2); + while (kill(tar_fork_pid, 0) == 0) { + usleep(1000); + } + LOGINFO("Backup_Run stopped and returning false, backup cancelled.\n"); + LOGINFO("Removing directory %s\n", Full_Backup_Path.c_str()); + TWFunc::removeDir(Full_Backup_Path, false); + tar_fork_pid = 0; + } + + return 0; } int TWPartitionManager::Run_Backup(void) { @@ -621,6 +648,7 @@ int TWPartitionManager::Run_Backup(void) { struct tm *t; time_t start, stop, seconds, total_start, total_stop; size_t start_pos = 0, end_pos = 0; + stop_backup.set_value(0); seconds = time(0); t = localtime(&seconds); @@ -718,6 +746,8 @@ int TWPartitionManager::Run_Backup(void) { start_pos = 0; end_pos = Backup_List.find(";", start_pos); while (end_pos != string::npos && start_pos < Backup_List.size()) { + if (stop_backup.get_value() != 0) + return -1; backup_path = Backup_List.substr(start_pos, end_pos - start_pos); backup_part = Find_Partition_By_Path(backup_path); if (backup_part != NULL) { diff --git a/partitions.hpp b/partitions.hpp index f26d8e5d8..8379de9b3 100644 --- a/partitions.hpp +++ b/partitions.hpp @@ -1,5 +1,5 @@ /* - Copyright 2012 bigbiff/Dees_Troy TeamWin + Copyright 2014 TeamWin This file is part of TWRP/TeamWin Recovery Project. TWRP is free software: you can redistribute it and/or modify @@ -22,6 +22,7 @@ #include #include #include "twrpDU.hpp" +#include "tw_atomic.hpp" #define MAX_FSTAB_LINE_LENGTH 2048 @@ -58,7 +59,7 @@ public: bool Can_Repair(); // Checks to see if we have everything needed to be able to repair the current file system uint64_t Get_Max_FileSize(); //get partition maxFileSie bool Repair(); // Repairs the current file system - bool Backup(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size); // Backs up the partition to the folder specified + bool Backup(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size, pid_t &tar_fork_pid); // Backs up the partition to the folder specified bool Check_MD5(string restore_folder); // Checks MD5 of a backup bool Restore(string restore_folder, const unsigned long long *total_restore_size, unsigned long long *already_restored_size); // Restores the partition using the backup folder provided unsigned long long Get_Restore_Size(string restore_folder); // Returns the overall restore size of the backup @@ -104,7 +105,7 @@ private: bool Wipe_RMRF(); // Uses rm -rf to wipe bool Wipe_F2FS(); // Uses mkfs.f2fs to wipe bool Wipe_Data_Without_Wiping_Media(); // Uses rm -rf to wipe but does not wipe /data/media - bool Backup_Tar(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size); // Backs up using tar for file systems + bool Backup_Tar(string backup_folder, const unsigned long long *overall_size, const unsigned long long *other_backups_size, pid_t &tar_fork_pid); // Backs up using tar for file systems bool Backup_DD(string backup_folder); // Backs up using dd for emmc memory types bool Backup_Dump_Image(string backup_folder); // Backs up using dump_image for MTD memory types string Get_Restore_File_System(string restore_folder); // Returns the file system that was in place at the time of the backup @@ -211,6 +212,7 @@ public: void UnMount_Main_Partitions(void); // Unmounts system and data if not data/media and boot if boot is mountable int Partition_SDCard(void); // Repartitions the sdcard TWPartition *Get_Default_Storage_Partition(); // Returns a pointer to a default storage partition + int Cancel_Backup(); // Signals partition backup to cancel int Fix_Permissions(); void Get_Partition_List(string ListType, std::vector *Partition_List); @@ -224,6 +226,8 @@ public: bool Remove_MTP_Storage(unsigned int Storage_ID); // Adds or removes an MTP Storage partition bool Flash_Image(string Filename); // Flashes an image to a selected partition from the partition list + TWAtomicInt stop_backup; + private: void Setup_Settings_Storage_Partition(TWPartition* Part); // Sets up settings storage void Setup_Android_Secure_Location(TWPartition* Part); // Sets up .android_secure if needed @@ -238,6 +242,7 @@ private: pid_t mtppid; bool mtp_was_enabled; int mtp_write_fd; + pid_t tar_fork_pid; private: std::vector Partitions; // Vector list of all partitions diff --git a/tw_atomic.cpp b/tw_atomic.cpp new file mode 100644 index 000000000..31cdd859f --- /dev/null +++ b/tw_atomic.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015 The Team Win Recovery Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "tw_atomic.hpp" + +/* + * According to this documentation: + * https://developer.android.com/training/articles/smp.html + * it is recommended to use mutexes instead of atomics. This class + * provides us with a wrapper to make "atomic" variables easy to use. + */ + +TWAtomicInt::TWAtomicInt(int initial_value /* = 0 */) { + if (pthread_mutex_init(&mutex_lock, NULL) != 0) { + // This should hopefully never happen. If it does, the + // operations will not be atomic, but we will allow things to + // continue anyway after logging the issue and just hope for + // the best. + printf("TWAtomic error initializing mutex.\n"); + use_mutex = false; + } else { + use_mutex = true; + } + value = initial_value; +} + +TWAtomicInt::~TWAtomicInt() { + if (use_mutex) + pthread_mutex_destroy(&mutex_lock); +} + +void TWAtomicInt::set_value(int new_value) { + if (use_mutex) { + pthread_mutex_lock(&mutex_lock); + value = new_value; + pthread_mutex_unlock(&mutex_lock); + } else { + value = new_value; + } +} + +int TWAtomicInt::get_value(void) { + int ret_val; + + if (use_mutex) { + pthread_mutex_lock(&mutex_lock); + ret_val = value; + pthread_mutex_unlock(&mutex_lock); + } else { + ret_val = value; + } + return ret_val; +} diff --git a/tw_atomic.hpp b/tw_atomic.hpp new file mode 100644 index 000000000..0f29f0200 --- /dev/null +++ b/tw_atomic.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 The Team Win Recovery Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _TWATOMIC_HPP_HEADER +#define _TWATOMIC_HPP_HEADER + +#include + +class TWAtomicInt +{ +public: + TWAtomicInt(int initial_value = 0); + ~TWAtomicInt(); + void set_value(int new_value); + int get_value(); + +private: + int value; + bool use_mutex; + pthread_mutex_t mutex_lock; +}; + +#endif //_TWATOMIC_HPP_HEADER diff --git a/twrp-functions.cpp b/twrp-functions.cpp index 15f442f76..f5bf1b0f0 100644 --- a/twrp-functions.cpp +++ b/twrp-functions.cpp @@ -585,7 +585,7 @@ int TWFunc::removeDir(const string path, bool skipParent) { string new_path; if (d == NULL) { - LOGERR("Error opening '%s'\n", path.c_str()); + LOGERR("Error opening dir: '%s'\n", path.c_str()); return -1; } diff --git a/twrpTar.cpp b/twrpTar.cpp index 7f057df98..dfaa541d9 100644 --- a/twrpTar.cpp +++ b/twrpTar.cpp @@ -34,6 +34,7 @@ extern "C" { #include #include #include +#include #include #include #include @@ -83,9 +84,13 @@ void twrpTar::setpassword(string pass) { password = pass; } -int twrpTar::createTarFork(const unsigned long long *overall_size, const unsigned long long *other_backups_size) { +void twrpTar::Signal_Kill(int signum) { + _exit(255); +} + +int twrpTar::createTarFork(const unsigned long long *overall_size, const unsigned long long *other_backups_size, pid_t &fork_pid) { int status = 0; - pid_t pid, rc_pid; + pid_t rc_pid, tar_fork_pid; int progress_pipe[2], ret; file_count = 0; @@ -94,16 +99,17 @@ int twrpTar::createTarFork(const unsigned long long *overall_size, const unsigne LOGERR("Error creating progress tracking pipe\n"); return -1; } - if ((pid = fork()) == -1) { + if ((tar_fork_pid = fork()) == -1) { LOGINFO("create tar failed to fork.\n"); close(progress_pipe[0]); close(progress_pipe[1]); return -1; } - if (pid == 0) { - // Child process + if (tar_fork_pid == 0) { + // Child process // Child closes input side of progress pipe + signal(SIGUSR2, twrpTar::Signal_Kill); close(progress_pipe[0]); progress_pipe_fd = progress_pipe[1]; @@ -375,6 +381,8 @@ int twrpTar::createTarFork(const unsigned long long *overall_size, const unsigne files_backup = 0; size_backup = 0; + fork_pid = tar_fork_pid; + // Parent closes output side close(progress_pipe[1]); @@ -422,7 +430,7 @@ int twrpTar::createTarFork(const unsigned long long *overall_size, const unsigne backup_info.SetValue("file_count", files_backup); backup_info.SaveValues(); #endif //ndef BUILD_TWRPTAR_MAIN - if (TWFunc::Wait_For_Child(pid, &status, "createTarFork()") != 0) + if (TWFunc::Wait_For_Child(tar_fork_pid, &status, "createTarFork()") != 0) return -1; } return 0; @@ -430,7 +438,7 @@ int twrpTar::createTarFork(const unsigned long long *overall_size, const unsigne int twrpTar::extractTarFork(const unsigned long long *overall_size, unsigned long long *other_backups_size) { int status = 0; - pid_t pid, rc_pid; + pid_t rc_pid, tar_fork_pid; int progress_pipe[2], ret; if (pipe(progress_pipe) < 0) { @@ -438,10 +446,10 @@ int twrpTar::extractTarFork(const unsigned long long *overall_size, unsigned lon return -1; } - pid = fork(); - if (pid >= 0) // fork was successful + tar_fork_pid = fork(); + if (tar_fork_pid >= 0) // fork was successful { - if (pid == 0) // child process + if (tar_fork_pid == 0) // child process { close(progress_pipe[0]); progress_pipe_fd = progress_pipe[1]; @@ -585,7 +593,7 @@ int twrpTar::extractTarFork(const unsigned long long *overall_size, unsigned lon #endif //ndef BUILD_TWRPTAR_MAIN *other_backups_size += size_backup; - if (TWFunc::Wait_For_Child(pid, &status, "extractTarFork()") != 0) + if (TWFunc::Wait_For_Child(tar_fork_pid, &status, "extractTarFork()") != 0) return -1; } } diff --git a/twrpTar.hpp b/twrpTar.hpp index 799475234..63cb3752a 100644 --- a/twrpTar.hpp +++ b/twrpTar.hpp @@ -45,7 +45,7 @@ class twrpTar { public: twrpTar(); virtual ~twrpTar(); - int createTarFork(const unsigned long long *overall_size, const unsigned long long *other_backups_size); + int createTarFork(const unsigned long long *overall_size, const unsigned long long *other_backups_size, pid_t &fork_pid); int extractTarFork(const unsigned long long *overall_size, unsigned long long *other_backups_size); void setfn(string fn); void setdir(string dir); @@ -80,6 +80,7 @@ private: static void* extractMulti(void *cookie); int tarList(std::vector *TarList, unsigned thread_id); unsigned long long uncompressedSize(string filename, int *archive_type); + static void Signal_Kill(int signum); int Archive_Current_Type; unsigned long long Archive_Current_Size; -- cgit v1.2.3