twrptar: fix backup freeze with pigz and openaes

The filedescriptors must be opened with the close-on-exec flag, so
child processes don't keep opened parent fd around, that prevents
the processing pipe to be properly closed.

Change-Id: I285d57d04d13452383f1b81910a8eda02f17a156
diff --git a/twrpTar.cpp b/twrpTar.cpp
index d15eea6..b2d0ea6 100644
--- a/twrpTar.cpp
+++ b/twrpTar.cpp
@@ -315,6 +315,7 @@
 			}
 			/*if (pthread_attr_setstacksize(&tattr, 524288)) {
 				LOGERR("Error setting pthread_attr_setstacksize\n");
+				close(progress_pipe[1]);
 				_exit(-1);
 			}*/
 
@@ -874,10 +875,10 @@
 int twrpTar::addFilesToExistingTar(vector <string> files, string fn) {
 	char* charTarFile = (char*) fn.c_str();
 
-	if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) == -1)
+	if (tar_open(&t, charTarFile, NULL, O_CLOEXEC | O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) == -1)
 		return -1;
 	removeEOT(charTarFile);
-	if (tar_open(&t, charTarFile, NULL, O_WRONLY | O_APPEND | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) == -1)
+	if (tar_open(&t, charTarFile, NULL, O_CLOEXEC | O_WRONLY | O_APPEND | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) == -1)
 		return -1;
 	for (unsigned int i = 0; i < files.size(); ++i) {
 		char* file = (char*) files.at(i).c_str();
@@ -901,17 +902,17 @@
 		LOGINFO("Using encryption and compression...\n");
 		int i, pipes[4];
 
-		if (pipe(pipes) < 0) {
+		if (pipe2(pipes, O_CLOEXEC) < 0) {
 			LOGINFO("Error creating first pipe\n");
 			gui_err("backup_error=Error creating backup.");
 			return -1;
 		}
-		if (pipe(pipes + 2) < 0) {
+		if (pipe2(pipes + 2, O_CLOEXEC) < 0) {
 			LOGINFO("Error creating second pipe\n");
 			gui_err("backup_error=Error creating backup.");
 			return -1;
 		}
-		output_fd = open(tarfn.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+		output_fd = open(tarfn.c_str(), O_CLOEXEC | O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
 		if (output_fd < 0) {
 			gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(tarfn)(strerror(errno)));
 			for (i = 0; i < 4; i++)
@@ -929,20 +930,11 @@
 			return -1;
 		} else if (pigz_pid == 0) {
 			// pigz Child
-			close(pipes[1]);
-			close(pipes[2]);
-			int stdinfd = fileno(stdin);
-			int stdoutfd = fileno(stdout);
-			close(stdinfd);
-			dup2(pipes[0], stdinfd);
-			close(stdoutfd);
-			dup2(pipes[3], stdoutfd);
+			dup2(pipes[0], STDIN_FILENO);
+			dup2(pipes[3], STDOUT_FILENO);
 			if (execlp("pigz", "pigz", "-", NULL) < 0) {
 				LOGINFO("execlp pigz ERROR!\n");
 				gui_err("backup_error=Error creating backup.");
-				close(output_fd);
-				close(pipes[0]);
-				close(pipes[3]);
 				_exit(-1);
 			}
 		} else {
@@ -958,20 +950,11 @@
 				return -1;
 			} else if (oaes_pid == 0) {
 				// openaes Child
-				close(pipes[0]);
-				close(pipes[1]);
-				close(pipes[3]);
-				int stdinfd = fileno(stdin);
-				int stdoutfd = fileno(stdout);
-				close(stdinfd);
-				dup2(pipes[2], stdinfd);
-				close(stdoutfd);
-				dup2(output_fd, stdoutfd);
+				dup2(pipes[2], STDIN_FILENO);
+				dup2(output_fd, STDOUT_FILENO);
 				if (execlp("openaes", "openaes", "enc", "--key", password.c_str(), NULL) < 0) {
 					LOGINFO("execlp openaes ERROR!\n");
 					gui_err("backup_error=Error creating backup.");
-					close(pipes[2]);
-					close(output_fd);
 					_exit(-1);
 				}
 			} else {
@@ -982,7 +965,7 @@
 				fd = pipes[1];
 				init_libtar_no_buffer(progress_pipe_fd);
 				tar_type.writefunc = write_tar_no_buffer;
-				if (tar_fdopen(&t, fd, charRootDir, &tar_type, O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
+				if (tar_fdopen(&t, fd, charRootDir, &tar_type, O_CLOEXEC | O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
 					close(fd);
 					LOGINFO("tar_fdopen failed\n");
 					gui_err("backup_error=Error creating backup.");
@@ -1001,15 +984,14 @@
 			output_fd = open(TW_ADB_BACKUP, O_WRONLY);
 		}
 		else {
-			output_fd = open(tarfn.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+			output_fd = open(tarfn.c_str(), O_CLOEXEC | O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
 		}
 		if (output_fd < 0) {
 			gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(tarfn)(strerror(errno)));
-			close(pigzfd[0]);
 			return -1;
 		}
 
-		if (pipe(pigzfd) < 0) {
+		if (pipe2(pigzfd, O_CLOEXEC) < 0) {
 			LOGINFO("Error creating pipe\n");
 			gui_err("backup_error=Error creating backup.");
 			close(output_fd);
@@ -1026,14 +1008,11 @@
 			return -1;
 		} else if (pigz_pid == 0) {
 			// Child
-			close(pigzfd[1]);   // close unused output pipe
-			dup2(pigzfd[0], fileno(stdin)); // remap stdin
-			dup2(output_fd, fileno(stdout)); // remap stdout to output file
+			dup2(pigzfd[0], STDIN_FILENO); // remap stdin
+			dup2(output_fd, STDOUT_FILENO); // remap stdout to output file
 			if (execlp("pigz", "pigz", "-", NULL) < 0) {
 				LOGINFO("execlp pigz ERROR!\n");
 				gui_err("backup_error=Error creating backup.");
-				close(output_fd);
-				close(pigzfd[0]);
 				_exit(-1);
 			}
 		} else {
@@ -1042,7 +1021,7 @@
 			fd = pigzfd[1];   // copy parent output
 			init_libtar_no_buffer(progress_pipe_fd);
 			tar_type.writefunc = write_tar_no_buffer;
-			if (tar_fdopen(&t, fd, charRootDir, &tar_type, O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
+			if (tar_fdopen(&t, fd, charRootDir, &tar_type, O_CLOEXEC | O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
 				close(fd);
 				LOGINFO("tar_fdopen failed\n");
 				gui_err("backup_error=Error creating backup.");
@@ -1054,12 +1033,12 @@
 		current_archive_type = ENCRYPTED;
 		LOGINFO("Using encryption...\n");
 		int oaesfd[2];
-		output_fd = open(tarfn.c_str(), O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+		output_fd = open(tarfn.c_str(), O_CLOEXEC | O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
 		if (output_fd < 0) {
 			gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(tarfn)(strerror(errno)));
 			return -1;
 		}
-		if (pipe(oaesfd) < 0) {
+		if (pipe2(oaesfd, O_CLOEXEC) < 0) {
 			LOGINFO("Error creating pipe\n");
 			gui_err("backup_error=Error creating backup.");
 			close(output_fd);
@@ -1076,14 +1055,11 @@
 			return -1;
 		} else if (oaes_pid == 0) {
 			// Child
-			close(oaesfd[1]);   // close unused
-			dup2(oaesfd[0], fileno(stdin)); // remap stdin
-			dup2(output_fd, fileno(stdout)); // remap stdout to output file
+			dup2(oaesfd[0], STDIN_FILENO); // remap stdin
+			dup2(output_fd, STDOUT_FILENO); // remap stdout to output file
 			if (execlp("openaes", "openaes", "enc", "--key", password.c_str(), NULL) < 0) {
 				LOGINFO("execlp openaes ERROR!\n");
 				gui_err("backup_error=Error creating backup.");
-				close(output_fd);
-				close(oaesfd[0]);
 				_exit(-1);
 			}
 		} else {
@@ -1092,7 +1068,7 @@
 			fd = oaesfd[1];   // copy parent output
 			init_libtar_no_buffer(progress_pipe_fd);
 			tar_type.writefunc = write_tar_no_buffer;
-			if (tar_fdopen(&t, fd, charRootDir, &tar_type, O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
+			if (tar_fdopen(&t, fd, charRootDir, &tar_type, O_CLOEXEC | O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
 				close(fd);
 				LOGINFO("tar_fdopen failed\n");
 				gui_err("backup_error=Error creating backup.");
@@ -1108,7 +1084,7 @@
 			LOGINFO("Opening TW_ADB_BACKUP uncompressed stream\n");
 			tar_type.writefunc = write_tar_no_buffer;
 			output_fd = open(TW_ADB_BACKUP, O_WRONLY);
-			if(tar_fdopen(&t, output_fd, charRootDir, &tar_type, O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
+			if(tar_fdopen(&t, output_fd, charRootDir, &tar_type, O_CLOEXEC | O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
 				close(output_fd);
 				LOGERR("tar_fdopen failed\n");
 				return -1;
@@ -1116,7 +1092,7 @@
 		}
 		else {
 			tar_type.writefunc = write_tar;
-			if (tar_open(&t, charTarFile, &tar_type, O_WRONLY | O_CREAT | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) == -1) {
+			if (tar_open(&t, charTarFile, &tar_type, O_CLOEXEC | O_WRONLY | O_CREAT | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) == -1) {
 				LOGERR("tar_open error opening '%s'\n", tarfn.c_str());
 				gui_err("backup_error=Error creating backup.");
 				return -1;
@@ -1134,19 +1110,19 @@
 	if (current_archive_type == COMPRESSED_ENCRYPTED) {
 		LOGINFO("Opening encrypted and compressed backup...\n");
 		int i, pipes[4];
-		input_fd = open(tarfn.c_str(), O_RDONLY | O_LARGEFILE);
+		input_fd = open(tarfn.c_str(), O_CLOEXEC | O_RDONLY | O_LARGEFILE);
 		if (input_fd < 0) {
 			gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(tarfn)(strerror(errno)));
 			return -1;
 		}
 
-		if (pipe(pipes) < 0) {
+		if (pipe2(pipes, O_CLOEXEC) < 0) {
 			LOGINFO("Error creating first pipe\n");
 			gui_err("restore_error=Error during restore process.");
 			close(input_fd);
 			return -1;
 		}
-		if (pipe(pipes + 2) < 0) {
+		if (pipe2(pipes + 2, O_CLOEXEC) < 0) {
 			LOGINFO("Error creating second pipe\n");
 			gui_err("restore_error=Error during restore process.");
 			close(pipes[0]);
@@ -1165,20 +1141,11 @@
 			return -1;
 		} else if (oaes_pid == 0) {
 			// openaes Child
-			close(pipes[0]); // Close pipes that are not used by this child
-			close(pipes[2]);
-			close(pipes[3]);
-			int stdinfd = fileno(stdin);
-			int stdoutfd = fileno(stdout);
-			close(stdinfd);
-			dup2(input_fd, stdinfd);
-			close(stdoutfd);
-			dup2(pipes[1], stdoutfd);
+			dup2(input_fd, STDIN_FILENO);
+			dup2(pipes[1], STDOUT_FILENO);
 			if (execlp("openaes", "openaes", "dec", "--key", password.c_str(), NULL) < 0) {
 				LOGINFO("execlp openaes ERROR!\n");
 				gui_err("restore_error=Error during restore process.");
-				close(input_fd);
-				close(pipes[1]);
 				_exit(-1);
 			}
 		} else {
@@ -1194,20 +1161,11 @@
 				return -1;
 			} else if (pigz_pid == 0) {
 				// pigz Child
-				close(pipes[1]); // Close pipes not used by this child
-				close(pipes[2]);
-				int stdinfd = fileno(stdin);
-				int stdoutfd = fileno(stdout);
-				close(stdinfd);
-				dup2(pipes[0], stdinfd);
-				close(stdoutfd);
-				dup2(pipes[3], stdoutfd);
+				dup2(pipes[0], STDIN_FILENO);
+				dup2(pipes[3], STDOUT_FILENO);
 				if (execlp("pigz", "pigz", "-d", "-c", NULL) < 0) {
 					LOGINFO("execlp pigz ERROR!\n");
 					gui_err("restore_error=Error during restore process.");
-					close(input_fd);
-					close(pipes[0]);
-					close(pipes[3]);
 					_exit(-1);
 				}
 			} else {
@@ -1216,7 +1174,7 @@
 				close(pipes[1]);
 				close(pipes[3]);
 				fd = pipes[2];
-				if (tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
+				if (tar_fdopen(&t, fd, charRootDir, NULL, O_CLOEXEC | O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
 					close(fd);
 					LOGINFO("tar_fdopen failed\n");
 					gui_err("restore_error=Error during restore process.");
@@ -1227,13 +1185,13 @@
 	} else if (current_archive_type == ENCRYPTED) {
 		LOGINFO("Opening encrypted backup...\n");
 		int oaesfd[2];
-		input_fd = open(tarfn.c_str(), O_RDONLY | O_LARGEFILE);
+		input_fd = open(tarfn.c_str(), O_CLOEXEC | O_RDONLY | O_LARGEFILE);
 		if (input_fd < 0) {
 			gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(tarfn)(strerror(errno)));
 			return -1;
 		}
 
-		if (pipe(oaesfd) < 0) {
+		if (pipe2(oaesfd, O_CLOEXEC) < 0) {
 			LOGINFO("Error creating pipe\n");
 			gui_err("restore_error=Error during restore process.");
 			close(input_fd);
@@ -1250,23 +1208,18 @@
 			return -1;
 		} else if (oaes_pid == 0) {
 			// Child
-			close(oaesfd[0]); // Close unused pipe
-			int stdinfd = fileno(stdin);
-			close(stdinfd);   // close stdin
-			dup2(oaesfd[1], fileno(stdout)); // remap stdout
-			dup2(input_fd, stdinfd); // remap input fd to stdin
+			dup2(oaesfd[1], STDOUT_FILENO); // remap stdout
+			dup2(input_fd, STDIN_FILENO); // remap input fd to stdin
 			if (execlp("openaes", "openaes", "dec", "--key", password.c_str(), NULL) < 0) {
 				LOGINFO("execlp openaes ERROR!\n");
 				gui_err("restore_error=Error during restore process.");
-				close(input_fd);
-				close(oaesfd[1]);
 				_exit(-1);
 			}
 		} else {
 			// Parent
 			close(oaesfd[1]); // close parent output
 			fd = oaesfd[0];   // copy parent input
-			if (tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
+			if (tar_fdopen(&t, fd, charRootDir, NULL, O_CLOEXEC | O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
 				close(fd);
 				LOGINFO("tar_fdopen failed\n");
 				gui_err("restore_error=Error during restore process.");
@@ -1279,17 +1232,17 @@
 		LOGINFO("Opening gzip compressed tar...\n");
 		if (part_settings->adbbackup)  {
 			LOGINFO("opening TW_ADB_RESTORE compressed stream\n");
-			input_fd = open(TW_ADB_RESTORE, O_RDONLY | O_LARGEFILE);
+			input_fd = open(TW_ADB_RESTORE, O_CLOEXEC | O_RDONLY | O_LARGEFILE);
 		}
 		else
-			input_fd = open(tarfn.c_str(), O_RDONLY | O_LARGEFILE);
+			input_fd = open(tarfn.c_str(), O_CLOEXEC | O_RDONLY | O_LARGEFILE);
 
 		if (input_fd < 0) {
 			gui_msg(Msg(msg::kError, "error_opening_strerr=Error opening: '{1}' ({2})")(tarfn)(strerror(errno)));
 			return -1;
 		}
 
-		if (pipe(pigzfd) < 0) {
+		if (pipe2(pigzfd, O_CLOEXEC) < 0) {
 			LOGINFO("Error creating pipe\n");
 			gui_err("restore_error=Error during restore process.");
 			close(input_fd);
@@ -1306,13 +1259,10 @@
 			return -1;
 		} else if (pigz_pid == 0) {
 			// Child
-			close(pigzfd[0]);
-			dup2(pigzfd[1], fileno(stdout)); // remap stdout
-			dup2(input_fd, fileno(stdin)); // remap input fd to stdin
+			dup2(pigzfd[1], STDOUT_FILENO); // remap stdout
+			dup2(input_fd, STDIN_FILENO); // remap input fd to stdin
 			if (execlp("pigz", "pigz", "-d", "-c", NULL) < 0) {
-				close(pigzfd[1]);
-				close(input_fd);
-				LOGINFO("execlp openaes ERROR!\n");
+				LOGINFO("execlp pigz ERROR!\n");
 				gui_err("restore_error=Error during restore process.");
 				_exit(-1);
 			}
@@ -1320,7 +1270,7 @@
 			// Parent
 			close(pigzfd[1]); // close parent output
 			fd = pigzfd[0];   // copy parent input
-			if (tar_fdopen(&t, fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
+			if (tar_fdopen(&t, fd, charRootDir, NULL, O_CLOEXEC | O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
 				close(fd);
 				LOGINFO("tar_fdopen failed\n");
 				gui_err("restore_error=Error during restore process.");
@@ -1331,14 +1281,14 @@
 		if (part_settings->adbbackup) {
 			LOGINFO("Opening TW_ADB_RESTORE uncompressed stream\n");
 			input_fd = open(TW_ADB_RESTORE, O_RDONLY);
-			if (tar_fdopen(&t, input_fd, charRootDir, NULL, O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
+			if (tar_fdopen(&t, input_fd, charRootDir, NULL, O_CLOEXEC | O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
 				LOGERR("Unable to open tar archive '%s'\n", charTarFile);
 				gui_err("restore_error=Error during restore process.");
 				return -1;
 			}
 		}
 		else {
-			if (tar_open(&t, charTarFile, NULL, O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
+			if (tar_open(&t, charTarFile, NULL, O_CLOEXEC | O_RDONLY | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, TWTAR_FLAGS) != 0) {
 				LOGERR("Unable to open tar archive '%s'\n", charTarFile);
 				gui_err("restore_error=Error during restore process.");
 				return -1;
@@ -1395,7 +1345,6 @@
 		return -1;
 	}
 	if (current_archive_type > 0) {
-		close(fd);
 		int status;
 		if (pigz_pid > 0 && TWFunc::Wait_For_Child(pigz_pid, &status, "pigz") != 0)
 			return -1;