mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-13 03:30:42 +02:00
subprocess: Avoid leaking POSIX name aliases beyond subprocess.h
The commit a32c0f3df4b6bcd1d2e93f19e8f380bb890cd507 introduced code to silence MSVC's "warning C4996: The POSIX name for this item is deprecated." However, it exhibits several issues: 1. The aliases may leak into code outside the `subprocess.hpp` header. 2. They are unnecessarily applied when using the MinGW-w64 toolchain. 3. The fix is incomplete: downstream projects still see C4996 warnings. 4. The implementation lacks documentation. This change addresses all of the above shortcomings. Github-Pull: arun11299/cpp-subprocess#112 Rebased-From: 778543b2f2ca7f5d1c4f0241b635bbb265d750dd Co-authored-by: Luke Dashjr <luke-jr+git@utopios.org>
This commit is contained in:
parent
7997b7656f
commit
174bd43f2e
@ -68,10 +68,6 @@ extern "C" {
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <cwchar>
|
#include <cwchar>
|
||||||
|
|
||||||
#define close _close
|
|
||||||
#define open _open
|
|
||||||
#define fileno _fileno
|
|
||||||
#else
|
#else
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -81,6 +77,22 @@ extern "C" {
|
|||||||
#include <sys/types.h>
|
#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.
|
* Getting started with reading this source code.
|
||||||
* The source is mainly divided into four parts:
|
* The source is mainly divided into four parts:
|
||||||
@ -264,7 +276,7 @@ namespace util
|
|||||||
|
|
||||||
FILE *fp = _fdopen(os_fhandle, mode);
|
FILE *fp = _fdopen(os_fhandle, mode);
|
||||||
if (fp == 0) {
|
if (fp == 0) {
|
||||||
_close(os_fhandle);
|
subprocess_close(os_fhandle);
|
||||||
throw OSError("_fdopen", 0);
|
throw OSError("_fdopen", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +395,7 @@ namespace util
|
|||||||
{
|
{
|
||||||
size_t nwritten = 0;
|
size_t nwritten = 0;
|
||||||
while (nwritten < length) {
|
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;
|
if (written == -1) return -1;
|
||||||
nwritten += written;
|
nwritten += written;
|
||||||
}
|
}
|
||||||
@ -411,7 +423,7 @@ namespace util
|
|||||||
#ifdef __USING_WINDOWS__
|
#ifdef __USING_WINDOWS__
|
||||||
return (int)fread(buf, 1, read_upto, fp);
|
return (int)fread(buf, 1, read_upto, fp);
|
||||||
#else
|
#else
|
||||||
int fd = fileno(fp);
|
int fd = subprocess_fileno(fp);
|
||||||
int rbytes = 0;
|
int rbytes = 0;
|
||||||
int eintr_cnter = 0;
|
int eintr_cnter = 0;
|
||||||
|
|
||||||
@ -573,10 +585,10 @@ struct input
|
|||||||
explicit input(int fd): rd_ch_(fd) {}
|
explicit input(int fd): rd_ch_(fd) {}
|
||||||
|
|
||||||
// FILE pointer.
|
// 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) {
|
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);
|
if (fd == -1) throw OSError("File not found: ", errno);
|
||||||
rd_ch_ = fd;
|
rd_ch_ = fd;
|
||||||
}
|
}
|
||||||
@ -606,10 +618,10 @@ struct output
|
|||||||
{
|
{
|
||||||
explicit output(int fd): wr_ch_(fd) {}
|
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) {
|
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);
|
if (fd == -1) throw OSError("File not found: ", errno);
|
||||||
wr_ch_ = fd;
|
wr_ch_ = fd;
|
||||||
}
|
}
|
||||||
@ -637,10 +649,10 @@ struct error
|
|||||||
{
|
{
|
||||||
explicit error(int fd): wr_ch_(fd) {}
|
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) {
|
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);
|
if (fd == -1) throw OSError("File not found: ", errno);
|
||||||
wr_ch_ = fd;
|
wr_ch_ = fd;
|
||||||
}
|
}
|
||||||
@ -803,28 +815,28 @@ public:
|
|||||||
void cleanup_fds()
|
void cleanup_fds()
|
||||||
{
|
{
|
||||||
if (write_to_child_ != -1 && read_from_parent_ != -1) {
|
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) {
|
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) {
|
if (err_write_ != -1 && err_read_ != -1) {
|
||||||
close(err_read_);
|
subprocess_close(err_read_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_parent_fds()
|
void close_parent_fds()
|
||||||
{
|
{
|
||||||
if (write_to_child_ != -1) close(write_to_child_);
|
if (write_to_child_ != -1) subprocess_close(write_to_child_);
|
||||||
if (read_from_child_ != -1) close(read_from_child_);
|
if (read_from_child_ != -1) subprocess_close(read_from_child_);
|
||||||
if (err_read_ != -1) close(err_read_);
|
if (err_read_ != -1) subprocess_close(err_read_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_child_fds()
|
void close_child_fds()
|
||||||
{
|
{
|
||||||
if (write_to_parent_ != -1) close(write_to_parent_);
|
if (write_to_parent_ != -1) subprocess_close(write_to_parent_);
|
||||||
if (read_from_parent_ != -1) close(read_from_parent_);
|
if (read_from_parent_ != -1) subprocess_close(read_from_parent_);
|
||||||
if (err_write_ != -1) close(err_write_);
|
if (err_write_ != -1) subprocess_close(err_write_);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* input() { return input_.get(); }
|
FILE* input() { return input_.get(); }
|
||||||
@ -1161,8 +1173,8 @@ inline void Popen::execute_process() noexcept(false)
|
|||||||
child_pid_ = fork();
|
child_pid_ = fork();
|
||||||
|
|
||||||
if (child_pid_ < 0) {
|
if (child_pid_ < 0) {
|
||||||
close(err_rd_pipe);
|
subprocess_close(err_rd_pipe);
|
||||||
close(err_wr_pipe);
|
subprocess_close(err_wr_pipe);
|
||||||
throw OSError("fork failed", errno);
|
throw OSError("fork failed", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1172,14 +1184,14 @@ inline void Popen::execute_process() noexcept(false)
|
|||||||
stream_.close_parent_fds();
|
stream_.close_parent_fds();
|
||||||
|
|
||||||
//Close the read end of the error pipe
|
//Close the read end of the error pipe
|
||||||
close(err_rd_pipe);
|
subprocess_close(err_rd_pipe);
|
||||||
|
|
||||||
detail::Child chld(this, err_wr_pipe);
|
detail::Child chld(this, err_wr_pipe);
|
||||||
chld.execute_child();
|
chld.execute_child();
|
||||||
}
|
}
|
||||||
else
|
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();
|
stream_.close_child_fds();
|
||||||
|
|
||||||
@ -1188,7 +1200,7 @@ inline void Popen::execute_process() noexcept(false)
|
|||||||
|
|
||||||
FILE* err_fp = fdopen(err_rd_pipe, "r");
|
FILE* err_fp = fdopen(err_rd_pipe, "r");
|
||||||
if (!err_fp) {
|
if (!err_fp) {
|
||||||
close(err_rd_pipe);
|
subprocess_close(err_rd_pipe);
|
||||||
throw OSError("fdopen failed", errno);
|
throw OSError("fdopen failed", errno);
|
||||||
}
|
}
|
||||||
int read_bytes = util::read_atmost_n(err_fp, err_buf, SP_MAX_ERR_BUF_SIZ);
|
int read_bytes = util::read_atmost_n(err_fp, err_buf, SP_MAX_ERR_BUF_SIZ);
|
||||||
@ -1278,13 +1290,13 @@ namespace detail {
|
|||||||
|
|
||||||
// Close the duped descriptors
|
// Close the duped descriptors
|
||||||
if (stream.read_from_parent_ != -1 && stream.read_from_parent_ > 2)
|
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)
|
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)
|
if (stream.err_write_ != -1 && stream.err_write_ > 2)
|
||||||
close(stream.err_write_);
|
subprocess_close(stream.err_write_);
|
||||||
|
|
||||||
// Replace the current image with the executable
|
// Replace the current image with the executable
|
||||||
sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
|
sys_ret = execvp(parent_->exe_name_.c_str(), parent_->cargv_.data());
|
||||||
@ -1311,15 +1323,15 @@ namespace detail {
|
|||||||
#ifdef __USING_WINDOWS__
|
#ifdef __USING_WINDOWS__
|
||||||
util::configure_pipe(&this->g_hChildStd_IN_Rd, &this->g_hChildStd_IN_Wr, &this->g_hChildStd_IN_Wr);
|
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->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);
|
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->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);
|
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->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
|
#else
|
||||||
|
|
||||||
if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
|
if (write_to_child_ != -1) input(fdopen(write_to_child_, "wb"));
|
||||||
|
Loading…
Reference in New Issue
Block a user