| 234 | #define PIPE_READ 0 |
| 235 | #define PIPE_WRITE 1 |
| 236 | bool FullCommandList::runCommandN(const char *file, ShellState &state, |
| 237 | ArgumentValueList &args, std::vector<const char *> extraArgv) const { |
| 238 | |
| 239 | int p1[2], p2[2]; |
| 240 | pipe(p1); |
| 241 | pipe(p2); |
| 242 | |
| 243 | auto pid = fork(); |
| 244 | if(!pid) { |
| 245 | dup2(p1[PIPE_READ], STDIN_FILENO); |
| 246 | dup2(p2[PIPE_WRITE], STDOUT_FILENO); |
| 247 | close(p1[0]); close(p1[1]); close(p2[0]); close(p2[1]); |
| 248 | |
| 249 | unsigned long file0 = (file ? 1 : 0); |
| 250 | unsigned long extra = extraArgv.size(); |
| 251 | unsigned long count = args.getIndexedCount(); |
| 252 | char **argv = static_cast<char **>( |
| 253 | malloc((file0 + extra + count + 1) * sizeof(*argv))); |
| 254 | unsigned long argc = 0; |
| 255 | if(file0) argv[argc++] = const_cast<char *>(file); |
| 256 | for(unsigned long i = 0; i < extra; i ++) { |
| 257 | argv[argc++] = const_cast<char *>(extraArgv[i]); |
| 258 | } |
| 259 | for(unsigned long i = 0; i < count; i ++) { |
| 260 | argv[argc++] = strdup(args.getIndexed(i).getString().c_str()); |
| 261 | } |
| 262 | argv[argc] = nullptr; |
| 263 | #if 0 |
| 264 | for(unsigned long i = 0; argv[i]; i ++) { |
| 265 | std::cout << "\"" << argv[i] << "\","; |
| 266 | } |
| 267 | std::cout << std::endl; |
| 268 | #endif |
| 269 | execvp(argv[0], argv); |
| 270 | std::exit(1); |
| 271 | } |
| 272 | else { |
| 273 | close(p1[PIPE_READ]); |
| 274 | close(p2[PIPE_WRITE]); |
| 275 | auto flags = fcntl(p2[PIPE_READ], F_GETFL, 0); |
| 276 | fcntl(p2[PIPE_READ], F_SETFL, flags | O_NONBLOCK); |
| 277 | |
| 278 | auto in = args.getInStream(); |
| 279 | auto out = args.getOutStream(); |
| 280 | |
| 281 | char buffer[BUFSIZ]; |
| 282 | ssize_t n = 0; |
| 283 | std::string line; |
| 284 | if(in) while(std::getline(*in, line)) { |
| 285 | //std::cout << "write [" << line << "]\n"; |
| 286 | line += '\n'; |
| 287 | write(p1[PIPE_WRITE], line.c_str(), line.length()); |
| 288 | if((n = read(p2[PIPE_READ], buffer, sizeof buffer)) > 0) { |
| 289 | //std::cout << "read [" << buffer << "]\n"; |
| 290 | out->write(buffer, n); |
| 291 | } |
| 292 | } |
| 293 | close(p1[PIPE_WRITE]); |
nothing calls this directly
no test coverage detected