variable execvp() arguments v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Mon, 06 May 2019 20:38:17 +0200
branchv_0
changeset 11 f515d14794e0
parent 10 f911910fd68f
child 12 8844ebce8fb4
variable execvp() arguments
src/AwkHandler.h
--- a/src/AwkHandler.h	Mon May 06 17:46:49 2019 +0200
+++ b/src/AwkHandler.h	Mon May 06 20:38:17 2019 +0200
@@ -86,6 +86,17 @@
 		if (error) throw cli::RelpipeCLIException(L"Unable to close FD: " + to_wstring(fd) + L" from PID: " + to_wstring(getpid()), cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
 	}
 
+	void execp(const std::vector<std::string>& args) {
+		const char** a = new const char*[args.size() + 1];
+		for (size_t i = 0; i < args.size(); i++) a[i] = args[i].c_str();
+		a[args.size()] = nullptr;
+
+		execvp(a[0], (char*const*) a);
+
+		delete[] a;
+		throw cli::RelpipeCLIException(L"Unable to do execvp().", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
+	}
+
 	void cleanUp() {
 		if (awkInputWriterFD >= 0) {
 			closeOrThrow(awkInputWriterFD);
@@ -140,8 +151,23 @@
 			redirectFD(awkInputReaderFD, STDIN_FILENO);
 			redirectFD(awkOutputWriterFD, STDOUT_FILENO);
 
+			std::wstringstream awkScript;
+			awkScript << L"BEGIN {" << std::endl;
+			awkScript << L"FS=\"\\t\";" << std::endl;
+			awkScript << L"};" << std::endl;
+
+			awkScript << L"END {" << std::endl;
+			// awkScript << … << std::endl;
+			awkScript << L"};" << std::endl;
+
+			awkScript << L"{print \"AWK says: line \" NR \" '\" $0 \"' has \" NF \" fields; first field is '\" $1 \"'\";}" << std::endl;
+
+			std::vector<std::string> args;
+			args.push_back("awk");
+			args.push_back(convertor.to_bytes(awkScript.str()));
+
 			// Runs AWK program found on $PATH → user can plug-in a custom implementation or a wrapper, but this can be also bit dangerous (however AWK itself is dangerous).
-			execlp("awk", "awk", "BEGIN { FS=\"\\t\" }; {print \"AWK says: line \" NR \" '\" $0 \"' has \" NF \" fields; first field is '\" $1 \"'\";}", nullptr);
+			execp(args);
 		} else {
 			// Parent process
 			closeOrThrow(awkInputReaderFD);
@@ -156,7 +182,7 @@
 				closeOrThrow(awkInputWriterFD);
 
 				locale::global(locale("")); // needed for processing unicode texts, otherwise getline() stopped working on first line with non-ascii characters; TODO: move somewhere else?
-				
+
 				__gnu_cxx::stdio_filebuf<wchar_t> awkOutputReaderBuffer(awkOutputReaderFD, std::ios::in);
 				std::wistream awkOutputReader(&awkOutputReaderBuffer);