diff --git a/dbms/src/Common/ShellCommand.cpp b/dbms/src/Common/ShellCommand.cpp index a4c16ee5c48..00010799aee 100644 --- a/dbms/src/Common/ShellCommand.cpp +++ b/dbms/src/Common/ShellCommand.cpp @@ -66,8 +66,8 @@ namespace enum class ReturnCodes : int { CANNOT_DUP_STDIN = 42, /// The value is not important, but it is chosen so that it's rare to conflict with the program return code. - CANNOT_DUP_STDOUT = 43, - CANNOT_DUP_STDERR = 44, + CANNOT_DUP_STDOUT = 43, + CANNOT_DUP_STDERR = 44, CANNOT_EXEC = 45, }; } @@ -76,6 +76,11 @@ namespace namespace DB { +ShellCommand::~ShellCommand() +{ + if (!wait_called) + tryWait(); +} std::unique_ptr ShellCommand::executeImpl(const char * filename, char * const argv[], bool pipe_stdin_only) { @@ -176,6 +181,8 @@ std::unique_ptr ShellCommand::executeDirect(const std::string & pa int ShellCommand::tryWait() { + wait_called = true; + int status = 0; if (-1 == waitpid(pid, &status, 0)) throwFromErrno("Cannot waitpid", ErrorCodes::CANNOT_WAITPID); diff --git a/dbms/src/Common/ShellCommand.h b/dbms/src/Common/ShellCommand.h index a558216fcbf..8df7de1de35 100644 --- a/dbms/src/Common/ShellCommand.h +++ b/dbms/src/Common/ShellCommand.h @@ -27,6 +27,7 @@ class ShellCommand { private: pid_t pid; + bool wait_called = false; ShellCommand(pid_t pid, int in_fd, int out_fd, int err_fd) : pid(pid), in(in_fd), out(out_fd), err(err_fd) {}; @@ -38,6 +39,8 @@ public: ReadBufferFromFile out; ReadBufferFromFile err; + ~ShellCommand(); + /// Run the command using /bin/sh -c static std::unique_ptr execute(const std::string & command, bool pipe_stdin_only = false); diff --git a/dbms/src/Common/tests/shell_command_test.cpp b/dbms/src/Common/tests/shell_command_test.cpp index 564567373c8..81fadfd4a51 100644 --- a/dbms/src/Common/tests/shell_command_test.cpp +++ b/dbms/src/Common/tests/shell_command_test.cpp @@ -5,6 +5,8 @@ #include #include +#include +#include using namespace DB; @@ -43,6 +45,15 @@ try command->wait(); } + + // hunting: + for (int i = 0; i < 1000; ++i) { + auto command = ShellCommand::execute("echo " + std::to_string(i)); + //command->wait(); // now automatic + } + + // std::cerr << "inspect me: ps auxwwf" << "\n"; + // std::this_thread::sleep_for(std::chrono::seconds(100)); } catch (...) {