src/AwkHandler.h
branchv_0
changeset 11 f515d14794e0
parent 10 f911910fd68f
child 12 8844ebce8fb4
equal deleted inserted replaced
10:f911910fd68f 11:f515d14794e0
    84 	void closeOrThrow(int fd) {
    84 	void closeOrThrow(int fd) {
    85 		int error = close(fd);
    85 		int error = close(fd);
    86 		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?
    86 		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?
    87 	}
    87 	}
    88 
    88 
       
    89 	void execp(const std::vector<std::string>& args) {
       
    90 		const char** a = new const char*[args.size() + 1];
       
    91 		for (size_t i = 0; i < args.size(); i++) a[i] = args[i].c_str();
       
    92 		a[args.size()] = nullptr;
       
    93 
       
    94 		execvp(a[0], (char*const*) a);
       
    95 
       
    96 		delete[] a;
       
    97 		throw cli::RelpipeCLIException(L"Unable to do execvp().", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions?
       
    98 	}
       
    99 
    89 	void cleanUp() {
   100 	void cleanUp() {
    90 		if (awkInputWriterFD >= 0) {
   101 		if (awkInputWriterFD >= 0) {
    91 			closeOrThrow(awkInputWriterFD);
   102 			closeOrThrow(awkInputWriterFD);
    92 			// TODO: check exit codes
   103 			// TODO: check exit codes
    93 			__pid_t waitResult1 = wait(NULL);
   104 			__pid_t waitResult1 = wait(NULL);
   138 			closeOrThrow(awkOutputReaderFD);
   149 			closeOrThrow(awkOutputReaderFD);
   139 
   150 
   140 			redirectFD(awkInputReaderFD, STDIN_FILENO);
   151 			redirectFD(awkInputReaderFD, STDIN_FILENO);
   141 			redirectFD(awkOutputWriterFD, STDOUT_FILENO);
   152 			redirectFD(awkOutputWriterFD, STDOUT_FILENO);
   142 
   153 
       
   154 			std::wstringstream awkScript;
       
   155 			awkScript << L"BEGIN {" << std::endl;
       
   156 			awkScript << L"FS=\"\\t\";" << std::endl;
       
   157 			awkScript << L"};" << std::endl;
       
   158 
       
   159 			awkScript << L"END {" << std::endl;
       
   160 			// awkScript << … << std::endl;
       
   161 			awkScript << L"};" << std::endl;
       
   162 
       
   163 			awkScript << L"{print \"AWK says: line \" NR \" '\" $0 \"' has \" NF \" fields; first field is '\" $1 \"'\";}" << std::endl;
       
   164 
       
   165 			std::vector<std::string> args;
       
   166 			args.push_back("awk");
       
   167 			args.push_back(convertor.to_bytes(awkScript.str()));
       
   168 
   143 			// 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).
   169 			// 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).
   144 			execlp("awk", "awk", "BEGIN { FS=\"\\t\" }; {print \"AWK says: line \" NR \" '\" $0 \"' has \" NF \" fields; first field is '\" $1 \"'\";}", nullptr);
   170 			execp(args);
   145 		} else {
   171 		} else {
   146 			// Parent process
   172 			// Parent process
   147 			closeOrThrow(awkInputReaderFD);
   173 			closeOrThrow(awkInputReaderFD);
   148 			closeOrThrow(awkOutputWriterFD);
   174 			closeOrThrow(awkOutputWriterFD);
   149 
   175 
   154 			} else if (writerPid == 0) {
   180 			} else if (writerPid == 0) {
   155 				// Writer child process
   181 				// Writer child process
   156 				closeOrThrow(awkInputWriterFD);
   182 				closeOrThrow(awkInputWriterFD);
   157 
   183 
   158 				locale::global(locale("")); // needed for processing unicode texts, otherwise getline() stopped working on first line with non-ascii characters; TODO: move somewhere else?
   184 				locale::global(locale("")); // needed for processing unicode texts, otherwise getline() stopped working on first line with non-ascii characters; TODO: move somewhere else?
   159 				
   185 
   160 				__gnu_cxx::stdio_filebuf<wchar_t> awkOutputReaderBuffer(awkOutputReaderFD, std::ios::in);
   186 				__gnu_cxx::stdio_filebuf<wchar_t> awkOutputReaderBuffer(awkOutputReaderFD, std::ios::in);
   161 				std::wistream awkOutputReader(&awkOutputReaderBuffer);
   187 				std::wistream awkOutputReader(&awkOutputReaderBuffer);
   162 
   188 
   163 				relationalWriter->startRelation(L"writer_debug",{
   189 				relationalWriter->startRelation(L"writer_debug",{
   164 					{L"message", writer::TypeId::STRING},
   190 					{L"message", writer::TypeId::STRING},