76 void createPipe(int& readerFD, int& writerFD) { |
77 void createPipe(int& readerFD, int& writerFD) { |
77 int fds[2]; |
78 int fds[2]; |
78 int result = pipe(fds); |
79 int result = pipe(fds); |
79 readerFD = fds[0]; |
80 readerFD = fds[0]; |
80 writerFD = fds[1]; |
81 writerFD = fds[1]; |
81 if (result < 0) throw cli::RelpipeCLIException(L"Unable to create a pipe.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
82 if (result < 0) throw AwkException(L"Unable to create a pipe."); |
82 } |
83 } |
83 |
84 |
84 void redirectFD(int oldfd, int newfd) { |
85 void redirectFD(int oldfd, int newfd) { |
85 int result = dup2(oldfd, newfd); |
86 int result = dup2(oldfd, newfd); |
86 if (result < 0) throw cli::RelpipeCLIException(L"Unable redirect FD.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
87 if (result < 0) throw AwkException(L"Unable redirect FD."); |
87 } |
88 } |
88 |
89 |
89 void closeOrThrow(int fd) { |
90 void closeOrThrow(int fd) { |
90 int error = close(fd); |
91 int error = close(fd); |
91 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? |
92 if (error) throw AwkException(L"Unable to close FD: " + to_wstring(fd) + L" from PID: " + to_wstring(getpid())); |
92 } |
93 } |
93 |
94 |
94 void execp(const std::vector<std::string>& args) { |
95 void execp(const std::vector<std::string>& args) { |
95 const char** a = new const char*[args.size() + 1]; |
96 const char** a = new const char*[args.size() + 1]; |
96 for (size_t i = 0; i < args.size(); i++) a[i] = args[i].c_str(); |
97 for (size_t i = 0; i < args.size(); i++) a[i] = args[i].c_str(); |
97 a[args.size()] = nullptr; |
98 a[args.size()] = nullptr; |
98 |
99 |
99 execvp(a[0], (char*const*) a); |
100 execvp(a[0], (char*const*) a); |
100 |
101 |
101 delete[] a; |
102 delete[] a; |
102 throw cli::RelpipeCLIException(L"Unable to do execvp().", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
103 throw AwkException(L"Unable to do execvp()."); |
103 } |
104 } |
104 |
105 |
105 /* TODO: move to lib-cli when stable and used in other modules */ |
106 /* TODO: move to lib-cli when stable and used in other modules */ |
106 void setEnv(const char * name, const string_t& value) { |
107 void setEnv(const char * name, const string_t& value) { |
107 setenv(name, convertor.to_bytes(value).c_str(), true); |
108 setenv(name, convertor.to_bytes(value).c_str(), true); |
159 } |
160 } |
160 } |
161 } |
161 |
162 |
162 string_t a2v(const string_t& attributeName) { |
163 string_t a2v(const string_t& attributeName) { |
163 if (currenVariablesMapping.find(attributeName) != currenVariablesMapping.end()) return currenVariablesMapping[attributeName]; |
164 if (currenVariablesMapping.find(attributeName) != currenVariablesMapping.end()) return currenVariablesMapping[attributeName]; |
164 else throw cli::RelpipeCLIException(L"Unable to find value in currenVariablesMapping", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
165 else throw AwkException(L"Unable to find value in currenVariablesMapping"); |
165 } |
166 } |
166 |
167 |
167 template <typename K, typename V> bool containsValue(std::map<K, V> map, V value) { |
168 template <typename K, typename V> bool containsValue(std::map<K, V> map, V value) { |
168 for (std::pair<K, V> p : map) if (p.second == value) return true; |
169 for (std::pair<K, V> p : map) if (p.second == value) return true; |
169 return false; |
170 return false; |
216 } else if (ch == '\\') { |
217 } else if (ch == '\\') { |
217 ch = awkOutputReader.get(); |
218 ch = awkOutputReader.get(); |
218 if (ch == 't') currentValue << L'\t'; |
219 if (ch == 't') currentValue << L'\t'; |
219 else if (ch == 'n') currentValue << L'\n'; |
220 else if (ch == 'n') currentValue << L'\n'; |
220 else if (ch == '\\') currentValue << L'\\'; |
221 else if (ch == '\\') currentValue << L'\\'; |
221 else throw cli::RelpipeCLIException(L"Unknown escape sequence. Only \\t, \\n and \\\\ are supported.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
222 else throw AwkException(L"Unknown escape sequence. Only \\t, \\n and \\\\ are supported."); |
222 } else { |
223 } else { |
223 currentValue << ch; |
224 currentValue << ch; |
224 } |
225 } |
225 } |
226 } |
226 } |
227 } |
286 |
287 |
287 relationalWriterFlush(); |
288 relationalWriterFlush(); |
288 __pid_t awkPid = fork(); |
289 __pid_t awkPid = fork(); |
289 |
290 |
290 if (awkPid < 0) { |
291 if (awkPid < 0) { |
291 throw cli::RelpipeCLIException(L"Unable to fork AWK process.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
292 throw AwkException(L"Unable to fork AWK process."); |
292 } else if (awkPid == 0) { |
293 } else if (awkPid == 0) { |
293 // AWK child process |
294 // AWK child process |
294 closeOrThrow(awkInputWriterFD); |
295 closeOrThrow(awkInputWriterFD); |
295 closeOrThrow(awkOutputReaderFD); |
296 closeOrThrow(awkOutputReaderFD); |
296 |
297 |
377 closeOrThrow(awkOutputWriterFD); |
378 closeOrThrow(awkOutputWriterFD); |
378 |
379 |
379 __pid_t writerPid = fork(); |
380 __pid_t writerPid = fork(); |
380 |
381 |
381 if (writerPid < 0) { |
382 if (writerPid < 0) { |
382 throw cli::RelpipeCLIException(L"Unable to fork Writer process.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // TODO: better exceptions? |
383 throw AwkException(L"Unable to fork Writer process."); |
383 } else if (writerPid == 0) { |
384 } else if (writerPid == 0) { |
384 // Writer child process |
385 // Writer child process |
385 closeOrThrow(awkInputWriterFD); |
386 closeOrThrow(awkInputWriterFD); |
386 |
387 |
387 if (currentRelationConfiguration->debugVariableMapping) debugVariableMapping(name); |
388 if (currentRelationConfiguration->debugVariableMapping) debugVariableMapping(name); |