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
diff --git a/Android.mk b/Android.mk
index bd5c33c..e76a3a9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -454,7 +454,7 @@
 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 d758430..e7f74d4 100644
--- a/gui/action.cpp
+++ b/gui/action.cpp
@@ -56,6 +56,7 @@
 
 #include "rapidxml.hpp"
 #include "objects.hpp"
+#include "../tw_atomic.hpp"
 
 void curtainClose(void);
 
@@ -169,6 +170,7 @@
 		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 @@
 	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::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 @@
 			else {
 				operation_end(1);
 				return -1;
-
 			}
 			DataManager::SetValue(TW_BACKUP_NAME, "(Auto Generate)");
 		} else if (arg == "restore") {
@@ -1112,16 +1120,42 @@
 			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 dd7efd7..c4ce65f 100644
--- a/gui/devices/480x854/res/ui.xml
+++ b/gui/devices/480x854/res/ui.xml
@@ -50,6 +50,7 @@
 		<variable name="col1_x" value="10" />
 		<variable name="col2_x" value="240" />
 		<variable name="col_center_x" value="128" />
+		<variable name="col_center_medium_x" value="183" />
 		<variable name="center_x" value="240" />
 		<variable name="row1_y" value="140" />
 		<variable name="row2_y" value="290" />
diff --git a/gui/devices/landscape/res/landscape.xml b/gui/devices/landscape/res/landscape.xml
index f66eb8b..eb6d9dd 100644
--- a/gui/devices/landscape/res/landscape.xml
+++ b/gui/devices/landscape/res/landscape.xml
@@ -670,7 +670,7 @@
 			<object type="button">
 				<highlight color="%highlight_color%" />
 				<condition var1="tw_has_cancel" var2="1" />
-				<placement x="%col4_x%" y="%slider_y%" />
+                                <placement x="%col_center_x%" y="%cancel_button_y%" />
 				<font resource="font" color="%button_text_color%" />
 				<text>Cancel</text>
 				<image resource="main_button" />
@@ -2157,6 +2157,17 @@
 
 			<object type="template" name="action_page_console" />
 
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_medium_x%" y="%row3_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="medium_button" />
+				<actions>
+					<action function="cancelbackup"></action>
+				</actions>
+			</object>
+
 			<object type="template" name="progress_bar" />
 
 			<object type="action">
@@ -2165,6 +2176,7 @@
 
 			<object type="action">
 				<condition var1="tw_operation_state" var2="1" />
+				<condition var1="tw_cancel_backup" var2="0" />
 				<actions>
 					<action function="set">tw_back=backup</action>
 					<action function="set">tw_complete_text1=Backup Complete</action>
@@ -2173,6 +2185,17 @@
 				</actions>
 			</object>
 
+			<object type="action">
+				<condition var1="tw_operation_state" var2="1" />
+				<condition var1="tw_cancel_backup" var2="1" />
+				<actions>
+					<action function="set">tw_back=backup</action>
+					<action function="set">tw_complete_text1=Backup Cancelled</action>
+					<action function="set">tw_show_reboot=1</action>
+					<action function="page">action_complete</action>
+				</actions>
+			</object>
+
 			<object type="template" name="footer" />
 		</page>
 
diff --git a/gui/devices/portrait/res/portrait.xml b/gui/devices/portrait/res/portrait.xml
index bb8e372..fe61671 100644
--- a/gui/devices/portrait/res/portrait.xml
+++ b/gui/devices/portrait/res/portrait.xml
@@ -1867,6 +1867,17 @@
 
 			<object type="template" name="action_page_console" />
 
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_medium_x%" y="%row4_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="medium_button" />
+				<actions>
+					<action function="cancelbackup"></action>
+				</actions>
+			</object>
+
 			<object type="template" name="progress_bar" />
 
 			<object type="action">
@@ -1875,6 +1886,7 @@
 
 			<object type="action">
 				<condition var1="tw_operation_state" var2="1" />
+				<condition var1="tw_cancel_backup" var2="0" />
 				<actions>
 					<action function="set">tw_back=backup</action>
 					<action function="set">tw_complete_text1=Backup Complete</action>
@@ -1882,6 +1894,17 @@
 					<action function="page">action_complete</action>
 				</actions>
 			</object>
+
+			<object type="action">
+				<condition var1="tw_operation_state" var2="1" />
+				<condition var1="tw_cancel_backup" var2="1" />
+				<actions>
+					<action function="set">tw_back=backup</action>
+					<action function="set">tw_complete_text1=Backup Cancelled</action>
+					<action function="set">tw_show_reboot=1</action>
+					<action function="page">action_complete</action>
+				</actions>
+			</object>
 		</page>
 
 		<page name="restore">
diff --git a/gui/devices/watch/res/watch.xml b/gui/devices/watch/res/watch.xml
index dc787b3..49e172e 100644
--- a/gui/devices/watch/res/watch.xml
+++ b/gui/devices/watch/res/watch.xml
@@ -1859,6 +1859,21 @@
 
 			<object type="template" name="action_page_console" />
 
+
+
+			<object type="template" name="progress_bar" />
+
+			<object type="button">
+				<highlight color="%highlight_color%" />
+				<placement x="%col_center_medium_x%" y="%row4_y%" />
+				<font resource="font" color="%button_text_color%" />
+				<text>Cancel</text>
+				<image resource="medium_button" />
+				<actions>
+					<action function="cancelbackup"></action>
+				</actions>
+			</object>
+
 			<object type="template" name="progress_bar" />
 
 			<object type="action">
@@ -1867,6 +1882,7 @@
 
 			<object type="action">
 				<condition var1="tw_operation_state" var2="1" />
+				<condition var1="tw_cancel_backup" var2="0" />
 				<actions>
 					<action function="set">tw_back=backup</action>
 					<action function="set">tw_complete_text1=Backup Complete</action>
@@ -1874,6 +1890,17 @@
 					<action function="page">action_complete</action>
 				</actions>
 			</object>
+
+			<object type="action">
+				<condition var1="tw_operation_state" var2="1" />
+				<condition var1="tw_cancel_backup" var2="1" />
+				<actions>
+					<action function="set">tw_back=backup</action>
+					<action function="set">tw_complete_text1=Backup Cancelled</action>
+					<action function="set">tw_show_reboot=1</action>
+					<action function="page">action_complete</action>
+				</actions>
+			</object>
 		</page>
 
 		<page name="restore">
diff --git a/gui/objects.hpp b/gui/objects.hpp
index 99b5855..832569c 100644
--- a/gui/objects.hpp
+++ b/gui/objects.hpp
@@ -360,6 +360,7 @@
 	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 db1f058..e30e6c1 100644
--- a/partition.cpp
+++ b/partition.cpp
@@ -1253,9 +1253,10 @@
 	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 @@
 #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 @@
 	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 23632d2..8e75a9a 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 @@
 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 @@
 	TWFunc::SetPerformanceMode(true);
 	time(&start);
 
-	if (Part->Backup(Backup_Folder, &total_size, &current_size)) {
+	if (Part->Backup(Backup_Folder, &total_size, &current_size, tar_fork_pid)) {
 		bool md5Success = false;
 		current_size += Part->Backup_Size;
 		pos = (float)((float)(current_size) / (float)(total_size));
@@ -569,7 +572,7 @@
 
 			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, &current_size)) {
+					if (!(*subpart)->Backup(Backup_Folder, &total_size, &current_size, tar_fork_pid)) {
 						TWFunc::SetPerformanceMode(false);
 						return false;
 					}
@@ -608,6 +611,30 @@
 		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 @@
 	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 @@
 	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 f26d8e5..8379de9 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 <vector>
 #include <string>
 #include "twrpDU.hpp"
+#include "tw_atomic.hpp"
 
 #define MAX_FSTAB_LINE_LENGTH 2048
 
@@ -58,7 +59,7 @@
 	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 @@
 	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 @@
 	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<PartitionList> *Partition_List);
@@ -224,6 +226,8 @@
 	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 @@
 	pid_t mtppid;
 	bool mtp_was_enabled;
 	int mtp_write_fd;
+	pid_t tar_fork_pid;
 
 private:
 	std::vector<TWPartition*> Partitions;                                     // Vector list of all partitions
diff --git a/tw_atomic.cpp b/tw_atomic.cpp
new file mode 100644
index 0000000..31cdd85
--- /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 <pthread.h>
+#include <stdio.h>
+#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 0000000..0f29f02
--- /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 <pthread.h>
+
+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 15f442f..f5bf1b0 100644
--- a/twrp-functions.cpp
+++ b/twrp-functions.cpp
@@ -585,7 +585,7 @@
 	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 7f057df..dfaa541 100644
--- a/twrpTar.cpp
+++ b/twrpTar.cpp
@@ -34,6 +34,7 @@
 #include <string>
 #include <sstream>
 #include <vector>
+#include <csignal>
 #include <dirent.h>
 #include <libgen.h>
 #include <sys/mman.h>
@@ -83,9 +84,13 @@
 	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 @@
 		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 @@
 		files_backup = 0;
 		size_backup = 0;
 
+		fork_pid = tar_fork_pid;
+
 		// Parent closes output side
 		close(progress_pipe[1]);
 
@@ -422,7 +430,7 @@
 		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::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 @@
 		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 @@
 #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 7994752..63cb375 100644
--- a/twrpTar.hpp
+++ b/twrpTar.hpp
@@ -45,7 +45,7 @@
 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 @@
 	static void* extractMulti(void *cookie);
 	int tarList(std::vector<TarListStruct> *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;