| 1260 | |
| 1261 | #ifndef WIN32 |
| 1262 | inline void Child::execute_child() { |
| 1263 | int sys_ret = -1; |
| 1264 | auto& stream = parent_->stream_; |
| 1265 | |
| 1266 | try { |
| 1267 | if (stream.write_to_parent_ == 0) |
| 1268 | stream.write_to_parent_ = dup(stream.write_to_parent_); |
| 1269 | |
| 1270 | if (stream.err_write_ == 0 || stream.err_write_ == 1) |
| 1271 | stream.err_write_ = dup(stream.err_write_); |
| 1272 | |
| 1273 | // Make the child owned descriptors as the |
| 1274 | // stdin, stdout and stderr for the child process |
| 1275 | auto _dup2_ = [](int fd, int to_fd) { |
| 1276 | if (fd == to_fd) { |
| 1277 | // dup2 syscall does not reset the |
| 1278 | // CLOEXEC flag if the descriptors |
| 1279 | // provided to it are same. |
| 1280 | // But, we need to reset the CLOEXEC |
| 1281 | // flag as the provided descriptors |
| 1282 | // are now going to be the standard |
| 1283 | // input, output and error |
| 1284 | util::set_clo_on_exec(fd, false); |
| 1285 | } else if(fd != -1) { |
| 1286 | int res = dup2(fd, to_fd); |
| 1287 | if (res == -1) throw OSError("dup2 failed", errno); |
| 1288 | } |
| 1289 | }; |
| 1290 | |
| 1291 | // Create the standard streams |
| 1292 | _dup2_(stream.read_from_parent_, 0); // Input stream |
| 1293 | _dup2_(stream.write_to_parent_, 1); // Output stream |
| 1294 | _dup2_(stream.err_write_, 2); // Error stream |
| 1295 | |
| 1296 | // Close the duped descriptors |
| 1297 | if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2) |
| 1298 | subprocess_close(stream.read_from_parent_); |
| 1299 | |
| 1300 | if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2) |
| 1301 | subprocess_close(stream.write_to_parent_); |
| 1302 | |
| 1303 | if (stream.err_write_ != -1 && stream.err_write_ > 2) |
| 1304 | subprocess_close(stream.err_write_); |
| 1305 | |
| 1306 | // Replace the current image with the executable |
| 1307 | sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data()); |
| 1308 | |
| 1309 | if (sys_ret == -1) throw OSError("execve failed", errno); |
| 1310 | |
| 1311 | } catch (const OSError& exp) { |
| 1312 | // Just write the exception message |
| 1313 | // TODO: Give back stack trace ? |
| 1314 | std::string err_msg(exp.what()); |
| 1315 | //ATTN: Can we do something on error here ? |
| 1316 | util::write_n(err_wr_pipe_, err_msg.c_str(), err_msg.length()); |
| 1317 | } |
| 1318 | |
| 1319 | // Calling application would not get this |
no test coverage detected