Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 46 additions & 34 deletions subprocess.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,6 @@ extern "C" {
#include <windows.h>
#include <io.h>
#include <cwchar>

#define close _close
#define open _open
#define fileno _fileno
#else
#include <sys/wait.h>
#include <unistd.h>
Expand All @@ -77,6 +73,22 @@ extern "C" {
#include <sys/types.h>
}

// The Microsoft C++ compiler issues deprecation warnings
// for the standard POSIX function names.
// Its preferred implementations have a leading underscore.
// See: https://learn.microsoft.com/en-us/cpp/c-runtime-library/compatibility.
#if (defined _MSC_VER)
#define subprocess_close _close
#define subprocess_fileno _fileno
#define subprocess_open _open
#define subprocess_write _write
#else
#define subprocess_close close
#define subprocess_fileno fileno
#define subprocess_open open
#define subprocess_write write
#endif

/*!
* Getting started with reading this source code.
* The source is mainly divided into four parts:
Expand Down Expand Up @@ -281,7 +293,7 @@ namespace util

FILE *fp = _fdopen(os_fhandle, mode);
if (fp == 0) {
_close(os_fhandle);
subprocess_close(os_fhandle);
throw OSError("_fdopen", 0);
}

Expand Down Expand Up @@ -514,7 +526,7 @@ namespace util
{
size_t nwritten = 0;
while (nwritten < length) {
int written = write(fd, buf + nwritten, length - nwritten);
int written = subprocess_write(fd, buf + nwritten, length - nwritten);
if (written == -1) return -1;
nwritten += written;
}
Expand Down Expand Up @@ -542,7 +554,7 @@ namespace util
#ifdef __USING_WINDOWS__
return (int)fread(buf, 1, read_upto, fp);
#else
int fd = fileno(fp);
int fd = subprocess_fileno(fp);
int rbytes = 0;
int eintr_cnter = 0;

Expand Down Expand Up @@ -783,10 +795,10 @@ struct input
explicit input(int fd): rd_ch_(fd) {}

// FILE pointer.
explicit input (FILE* fp):input(fileno(fp)) { assert(fp); }
explicit input (FILE* fp):input(subprocess_fileno(fp)) { assert(fp); }

explicit input(const char* filename) {
int fd = open(filename, O_RDONLY);
int fd = subprocess_open(filename, O_RDONLY);
if (fd == -1) throw OSError("File not found: ", errno);
rd_ch_ = fd;
}
Expand Down Expand Up @@ -816,10 +828,10 @@ struct output
{
explicit output(int fd): wr_ch_(fd) {}

explicit output (FILE* fp):output(fileno(fp)) { assert(fp); }
explicit output (FILE* fp):output(subprocess_fileno(fp)) { assert(fp); }

explicit output(const char* filename) {
int fd = open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
int fd = subprocess_open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
if (fd == -1) throw OSError("File not found: ", errno);
wr_ch_ = fd;
}
Expand Down Expand Up @@ -847,10 +859,10 @@ struct error
{
explicit error(int fd): wr_ch_(fd) {}

explicit error(FILE* fp):error(fileno(fp)) { assert(fp); }
explicit error(FILE* fp):error(subprocess_fileno(fp)) { assert(fp); }

explicit error(const char* filename) {
int fd = open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
int fd = subprocess_open(filename, O_APPEND | O_CREAT | O_RDWR, 0640);
if (fd == -1) throw OSError("File not found: ", errno);
wr_ch_ = fd;
}
Expand Down Expand Up @@ -1105,28 +1117,28 @@ class Streams
void cleanup_fds()
{
if (write_to_child_ != -1 && read_from_parent_ != -1) {
close(write_to_child_);
subprocess_close(write_to_child_);
}
if (write_to_parent_ != -1 && read_from_child_ != -1) {
close(read_from_child_);
subprocess_close(read_from_child_);
}
if (err_write_ != -1 && err_read_ != -1) {
close(err_read_);
subprocess_close(err_read_);
}
}

void close_parent_fds()
{
if (write_to_child_ != -1) close(write_to_child_);
if (read_from_child_ != -1) close(read_from_child_);
if (err_read_ != -1) close(err_read_);
if (write_to_child_ != -1) subprocess_close(write_to_child_);
if (read_from_child_ != -1) subprocess_close(read_from_child_);
if (err_read_ != -1) subprocess_close(err_read_);
}

void close_child_fds()
{
if (write_to_parent_ != -1) close(write_to_parent_);
if (read_from_parent_ != -1) close(read_from_parent_);
if (err_write_ != -1) close(err_write_);
if (write_to_parent_ != -1) subprocess_close(write_to_parent_);
if (read_from_parent_ != -1) subprocess_close(read_from_parent_);
if (err_write_ != -1) subprocess_close(err_write_);
}

FILE* input() { return input_.get(); }
Expand Down Expand Up @@ -1613,8 +1625,8 @@ inline void Popen::execute_process() noexcept(false)
child_pid_ = fork();

if (child_pid_ < 0) {
close(err_rd_pipe);
close(err_wr_pipe);
subprocess_close(err_rd_pipe);
subprocess_close(err_wr_pipe);
throw OSError("fork failed", errno);
}

Expand All @@ -1626,14 +1638,14 @@ inline void Popen::execute_process() noexcept(false)
stream_.close_parent_fds();

//Close the read end of the error pipe
close(err_rd_pipe);
subprocess_close(err_rd_pipe);

detail::Child chld(this, err_wr_pipe);
chld.execute_child();
}
else
{
close (err_wr_pipe);// close child side of pipe, else get stuck in read below
subprocess_close(err_wr_pipe);// close child side of pipe, else get stuck in read below

stream_.close_child_fds();

Expand All @@ -1642,7 +1654,7 @@ inline void Popen::execute_process() noexcept(false)

FILE* err_fp = fdopen(err_rd_pipe, "r");
if (!err_fp) {
close(err_rd_pipe);
subprocess_close(err_rd_pipe);
throw OSError("fdopen failed", errno);
}
int read_bytes = util::read_atmost_n(err_fp, err_buf, SP_MAX_ERR_BUF_SIZ);
Expand Down Expand Up @@ -1765,13 +1777,13 @@ namespace detail {

// Close the duped descriptors
if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
close(stream.read_from_parent_);
subprocess_close(stream.read_from_parent_);

if (stream.write_to_parent_ != -1 && stream.write_to_parent_ > 2)
close(stream.write_to_parent_);
subprocess_close(stream.write_to_parent_);

if (stream.err_write_ != -1 && stream.err_write_ > 2)
close(stream.err_write_);
subprocess_close(stream.err_write_);

// Close all the inherited fd's except the error write pipe
if (parent_->close_fds_) {
Expand All @@ -1780,7 +1792,7 @@ namespace detail {

for (int i = 3; i < max_fd; i++) {
if (i == err_wr_pipe_) continue;
close(i);
subprocess_close(i);
}
}

Expand Down Expand Up @@ -1831,15 +1843,15 @@ namespace detail {
#ifdef __USING_WINDOWS__
util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
this->input(util::file_from_handle(this->g_hChildStd_IN_Wr, "w"));
this->write_to_child_ = _fileno(this->input());
this->write_to_child_ = subprocess_fileno(this->input());

util::configure_pipe(&this->g_hChildStd_OUT_Rd, &this->g_hChildStd_OUT_Wr, &this->g_hChildStd_OUT_Rd);
this->output(util::file_from_handle(this->g_hChildStd_OUT_Rd, "r"));
this->read_from_child_ = _fileno(this->output());
this->read_from_child_ = subprocess_fileno(this->output());

util::configure_pipe(&this->g_hChildStd_ERR_Rd, &this->g_hChildStd_ERR_Wr, &this->g_hChildStd_ERR_Rd);
this->error(util::file_from_handle(this->g_hChildStd_ERR_Rd, "r"));
this->err_read_ = _fileno(this->error());
this->err_read_ = subprocess_fileno(this->error());
#else

if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
Expand Down