v29.4-roots.3 · Commit 2: [PATCH 02/30] runtime: preserve shared operator controls
src/util/subprocess.h
Before: src/util/subprocess.h · After: src/util/subprocess.h
File metadata
index 3449fa3b1bacce60422267110b27e54b13b19458..7cabd1baf27c5366aea0fed3a6b6bbb4ded01475 100644
Download original patch · Release notes
Diff rows 401–478 of 478. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
src/util/subprocess.h
CHANGED
|
@@ -1156,36 +1285,40 @@ inline void Popen::execute_process() noexcept(false) (continued)
|
|
| 1175 |
else
|
| 1176 |
{
|
| 1177 |
-
close (err_wr_pipe);// close child side of pipe, else get stuck in read below
|
| 1178 |
|
| 1179 |
stream_.close_child_fds();
|
| 1180 |
|
| 1181 |
try {
|
| 1182 |
char err_buf[SP_MAX_ERR_BUF_SIZ] = {0,};
|
| 1183 |
|
| 1184 |
-
int read_bytes = util::read_atmost_n(
|
| 1185 |
-
fdopen(err_rd_pipe, "r"),
|
| 1186 |
-
err_buf,
|
| 1187 |
-
SP_MAX_ERR_BUF_SIZ);
|
| 1188 |
-
close(err_rd_pipe);
|
|
|
|
|
|
|
| 1189 |
|
| 1190 |
if (read_bytes || strlen(err_buf)) {
|
| 1191 |
// Call waitpid to reap the child process
|
|
@@ -1233,6 +1366,14 @@ namespace detail {
|
|
| 1233 |
if (err.rd_ch_ != -1) popen_->stream_.err_read_ = err.rd_ch_;
|
| 1234 |
}
|
| 1235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1236 |
|
| 1237 |
inline void Child::execute_child() {
|
| 1238 |
#ifndef __USING_WINDOWS__
|
|
@@ -1271,13 +1412,18 @@ namespace detail {
|
|
| 1271 |
|
| 1272 |
// Close the duped descriptors
|
| 1273 |
if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
|
| 1274 |
-
close(stream.read_from_parent_);
|
| 1275 |
|
| 1276 |
if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2)
|
| 1277 |
-
close(stream.write_to_parent_);
|
| 1278 |
|
| 1279 |
if (stream.err_write_ != -1 && stream.err_write_ > 2)
|
| 1280 |
-
close(stream.err_write_);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1281 |
|
| 1282 |
// Replace the current image with the executable
|
| 1283 |
sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
|
|
@@ -1304,15 +1450,15 @@ namespace detail {
|
|
| 1304 |
#ifdef __USING_WINDOWS__
|
| 1305 |
util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
|
| 1306 |
this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
|
| 1307 |
-
this->write_to_child_ = _fileno(this->input());
|
| 1308 |
|
| 1309 |
util::configure_pipe(&this->g_hChildStd_OUT_Rd, &this->g_hChildStd_OUT_Wr, &this->g_hChildStd_OUT_Rd);
|
| 1310 |
this->output(util::file_from_handle(this->g_hChildStd_OUT_Rd, "r"));
|
| 1311 |
-
this->read_from_child_ = _fileno(this->output());
|
| 1312 |
|
| 1313 |
util::configure_pipe(&this->g_hChildStd_ERR_Rd, &this->g_hChildStd_ERR_Wr, &this->g_hChildStd_ERR_Rd);
|
| 1314 |
this->error(util::file_from_handle(this->g_hChildStd_ERR_Rd, "r"));
|
| 1315 |
-
this->err_read_ = _fileno(this->error());
|
| 1316 |
#else
|
| 1317 |
|
| 1318 |
if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
|
|
|
|
| 1306 |
else
|
| 1307 |
{
|
| 1308 |
+
subprocess_close(err_wr_pipe);// close child side of pipe, else get stuck in read below
|
| 1309 |
|
| 1310 |
stream_.close_child_fds();
|
| 1311 |
|
| 1312 |
try {
|
| 1313 |
char err_buf[SP_MAX_ERR_BUF_SIZ] = {0,};
|
| 1314 |
|
| 1315 |
+
FILE* err_fp = fdopen(err_rd_pipe, "r");
|
| 1316 |
+
if (!err_fp) {
|
| 1317 |
+
subprocess_close(err_rd_pipe);
|
| 1318 |
+
throw OSError("fdopen failed", errno);
|
| 1319 |
+
}
|
| 1320 |
+
int read_bytes = util::read_atmost_n(err_fp, err_buf, SP_MAX_ERR_BUF_SIZ);
|
| 1321 |
+
fclose(err_fp);
|
| 1322 |
|
| 1323 |
if (read_bytes || strlen(err_buf)) {
|
| 1324 |
// Call waitpid to reap the child process
|
|
|
|
| 1366 |
if (err.rd_ch_ != -1) popen_->stream_.err_read_ = err.rd_ch_;
|
| 1367 |
}
|
| 1368 |
|
| 1369 |
+
inline void ArgumentDeducer::set_option(close_fds&& cfds) {
|
| 1370 |
+
popen_->close_fds_ = cfds.close_all;
|
| 1371 |
+
}
|
| 1372 |
+
|
| 1373 |
+
#ifndef __USING_WINDOWS__
|
| 1374 |
+
void subprocess_close_all_fds(int except_fd);
|
| 1375 |
+
#endif
|
| 1376 |
+
|
| 1377 |
|
| 1378 |
inline void Child::execute_child() {
|
| 1379 |
#ifndef __USING_WINDOWS__
|
|
|
|
| 1412 |
|
| 1413 |
// Close the duped descriptors
|
| 1414 |
if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
|
| 1415 |
+
subprocess_close(stream.read_from_parent_);
|
| 1416 |
|
| 1417 |
if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2)
|
| 1418 |
+
subprocess_close(stream.write_to_parent_);
|
| 1419 |
|
| 1420 |
if (stream.err_write_ != -1 && stream.err_write_ > 2)
|
| 1421 |
+
subprocess_close(stream.err_write_);
|
| 1422 |
+
|
| 1423 |
+
// Close all the inherited fd's except the error write pipe
|
| 1424 |
+
if (parent_->close_fds_) {
|
| 1425 |
+
subprocess_close_all_fds(/*except_fd=*/ err_wr_pipe_);
|
| 1426 |
+
}
|
| 1427 |
|
| 1428 |
// Replace the current image with the executable
|
| 1429 |
sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
|
|
|
|
| 1450 |
#ifdef __USING_WINDOWS__
|
| 1451 |
util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
|
| 1452 |
this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
|
| 1453 |
+
this->write_to_child_ = subprocess_fileno(this->input());
|
| 1454 |
|
| 1455 |
util::configure_pipe(&this->g_hChildStd_OUT_Rd, &this->g_hChildStd_OUT_Wr, &this->g_hChildStd_OUT_Rd);
|
| 1456 |
this->output(util::file_from_handle(this->g_hChildStd_OUT_Rd, "r"));
|
| 1457 |
+
this->read_from_child_ = subprocess_fileno(this->output());
|
| 1458 |
|
| 1459 |
util::configure_pipe(&this->g_hChildStd_ERR_Rd, &this->g_hChildStd_ERR_Wr, &this->g_hChildStd_ERR_Rd);
|
| 1460 |
this->error(util::file_from_handle(this->g_hChildStd_ERR_Rd, "r"));
|
| 1461 |
+
this->err_read_ = subprocess_fileno(this->error());
|
| 1462 |
#else
|
| 1463 |
|
| 1464 |
if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
|