From f5b479fbabdceda48e3fd20d60bef1af393799cc Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Sun, 18 Oct 2020 13:39:44 +0300 Subject: stream.hpp -> process_io.hpp, move IO there --- include/winapi/process.hpp | 45 +---------------- include/winapi/process_io.hpp | 103 +++++++++++++++++++++++++++++++++++++ include/winapi/stream.hpp | 110 ---------------------------------------- src/process.cpp | 13 ++--- src/process_io.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++ src/stream.cpp | 48 ------------------ test/unit_tests/process.cpp | 7 +-- 7 files changed, 228 insertions(+), 213 deletions(-) create mode 100644 include/winapi/process_io.hpp delete mode 100644 include/winapi/stream.hpp create mode 100644 src/process_io.cpp delete mode 100644 src/stream.cpp diff --git a/include/winapi/process.hpp b/include/winapi/process.hpp index 5f841a0..d52ad0a 100644 --- a/include/winapi/process.hpp +++ b/include/winapi/process.hpp @@ -7,8 +7,8 @@ #include "cmd_line.hpp" #include "handle.hpp" +#include "process_io.hpp" #include "resource.hpp" -#include "stream.hpp" #include @@ -21,36 +21,8 @@ namespace winapi { class Process { public: - struct IO { - IO() = default; - - void close(); - - process::Stdin std_in; - process::Stdout std_out; - process::Stderr std_err; - - // VS 2013 won't generate these automatically. - - IO(IO&& other) BOOST_NOEXCEPT_OR_NOTHROW { swap(other); } - - IO& operator=(IO other) BOOST_NOEXCEPT_OR_NOTHROW { - swap(other); - return *this; - } - - void swap(IO& other) BOOST_NOEXCEPT_OR_NOTHROW { - using std::swap; - swap(std_in, other.std_in); - swap(std_out, other.std_out); - swap(std_err, other.std_err); - } - - IO(const IO&) = delete; - }; - static Process create(const CommandLine&); - static Process create(const CommandLine&, IO); + static Process create(const CommandLine&, process::IO); void wait() const; @@ -69,17 +41,4 @@ private: Handle m_handle; }; -inline void swap(Process::IO& a, Process::IO& b) BOOST_NOEXCEPT_OR_NOTHROW { - a.swap(b); -} - } // namespace winapi - -namespace std { - -template <> -inline void swap(winapi::Process::IO& a, winapi::Process::IO& b) BOOST_NOEXCEPT_OR_NOTHROW { - a.swap(b); -} - -} // namespace std diff --git a/include/winapi/process_io.hpp b/include/winapi/process_io.hpp new file mode 100644 index 0000000..597cc08 --- /dev/null +++ b/include/winapi/process_io.hpp @@ -0,0 +1,103 @@ +// Copyright (c) 2020 Egor Tensin +// This file is part of the "winapi-common" project. +// For details, see https://github.com/egor-tensin/winapi-common. +// Distributed under the MIT License. + +#pragma once + +#include "handle.hpp" +#include "path.hpp" +#include "pipe.hpp" + +#include + +#include +#include + +namespace winapi { +namespace process { + +struct Stream { + Stream(Handle&& handle) : handle{std::move(handle)} {} + + Handle handle; + + // VS 2013 won't generate these automatically. + Stream(Stream&& other) BOOST_NOEXCEPT_OR_NOTHROW; + Stream& operator=(Stream other) BOOST_NOEXCEPT_OR_NOTHROW; + void swap(Stream& other) BOOST_NOEXCEPT_OR_NOTHROW; + Stream(const Stream&) = delete; +}; + +void swap(Stream& a, Stream& b) BOOST_NOEXCEPT_OR_NOTHROW; + +struct Stdin : Stream { + Stdin(); + explicit Stdin(const std::string& file); + explicit Stdin(const CanonicalPath& file); + explicit Stdin(Pipe&); + + // VS 2013 won't generate these automatically. + Stdin(Stdin&& other) BOOST_NOEXCEPT_OR_NOTHROW; + Stdin& operator=(Stdin other) BOOST_NOEXCEPT_OR_NOTHROW; + Stdin(const Stdin&) = delete; +}; + +struct Stdout : Stream { + Stdout(); + explicit Stdout(const std::string& file); + explicit Stdout(const CanonicalPath& file); + explicit Stdout(Pipe&); + + // VS 2013 won't generate these automatically. + Stdout(Stdout&& other) BOOST_NOEXCEPT_OR_NOTHROW; + Stdout& operator=(Stdout other) BOOST_NOEXCEPT_OR_NOTHROW; + Stdout(const Stdout&) = delete; +}; + +struct Stderr : Stream { + Stderr(); + explicit Stderr(const std::string& file); + explicit Stderr(const CanonicalPath& file); + explicit Stderr(Pipe&); + + // VS 2013 won't generate these automatically. + Stderr(Stderr&& other) BOOST_NOEXCEPT_OR_NOTHROW; + Stderr& operator=(Stderr other) BOOST_NOEXCEPT_OR_NOTHROW; + Stderr(const Stderr&) = delete; +}; + +struct IO { + IO() = default; + + void close(); + + process::Stdin std_in; + process::Stdout std_out; + process::Stderr std_err; + + // VS 2013 won't generate these automatically. + IO(IO&& other) BOOST_NOEXCEPT_OR_NOTHROW; + IO& operator=(IO other) BOOST_NOEXCEPT_OR_NOTHROW; + void swap(IO& other) BOOST_NOEXCEPT_OR_NOTHROW; + IO(const IO&) = delete; +}; + +void swap(IO& a, IO& b) BOOST_NOEXCEPT_OR_NOTHROW; + +} // namespace process +} // namespace winapi + +namespace std { + +template <> +inline void swap(winapi::process::Stream& a, winapi::process::Stream& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + +template <> +inline void swap(winapi::process::IO& a, winapi::process::IO& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + +} // namespace std diff --git a/include/winapi/stream.hpp b/include/winapi/stream.hpp deleted file mode 100644 index ed5b40c..0000000 --- a/include/winapi/stream.hpp +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) 2020 Egor Tensin -// This file is part of the "winapi-common" project. -// For details, see https://github.com/egor-tensin/winapi-common. -// Distributed under the MIT License. - -#pragma once - -#include "handle.hpp" -#include "path.hpp" -#include "pipe.hpp" - -#include - -#include -#include - -namespace winapi { -namespace process { - -struct Stream { - Stream(Handle&& handle) : handle{std::move(handle)} {} - - Handle handle; - - // VS 2013 won't generate these automatically. - - Stream(Stream&& other) BOOST_NOEXCEPT_OR_NOTHROW { swap(other); } - - Stream& operator=(Stream other) BOOST_NOEXCEPT_OR_NOTHROW { - swap(other); - return *this; - } - - void swap(Stream& other) BOOST_NOEXCEPT_OR_NOTHROW { - using std::swap; - swap(handle, other.handle); - } - - Stream(const Stream&) = delete; -}; - -inline void swap(Stream& a, Stream& b) BOOST_NOEXCEPT_OR_NOTHROW { - a.swap(b); -} - -struct Stdin : Stream { - Stdin(); - explicit Stdin(const std::string& file); - explicit Stdin(const CanonicalPath& file); - explicit Stdin(Pipe&); - - // VS 2013 won't generate these automatically. - - Stdin(Stdin&& other) BOOST_NOEXCEPT_OR_NOTHROW : Stream{std::move(other)} {} - - Stdin& operator=(Stdin other) BOOST_NOEXCEPT_OR_NOTHROW { - Stream::operator=(std::move(other)); - return *this; - } - - Stdin(const Stdin&) = delete; -}; - -struct Stdout : Stream { - Stdout(); - explicit Stdout(const std::string& file); - explicit Stdout(const CanonicalPath& file); - explicit Stdout(Pipe&); - - // VS 2013 won't generate these automatically. - - Stdout(Stdout&& other) BOOST_NOEXCEPT_OR_NOTHROW : Stream{std::move(other)} {} - - Stdout& operator=(Stdout other) BOOST_NOEXCEPT_OR_NOTHROW { - Stream::operator=(std::move(other)); - return *this; - } - - Stdout(const Stdout&) = delete; -}; - -struct Stderr : Stream { - Stderr(); - explicit Stderr(const std::string& file); - explicit Stderr(const CanonicalPath& file); - explicit Stderr(Pipe&); - - // VS 2013 won't generate these automatically. - - Stderr(Stderr&& other) BOOST_NOEXCEPT_OR_NOTHROW : Stream{std::move(other)} {} - - Stderr& operator=(Stderr other) BOOST_NOEXCEPT_OR_NOTHROW { - Stream::operator=(std::move(other)); - return *this; - } - - Stderr(const Stderr&) = delete; -}; - -} // namespace process -} // namespace winapi - -namespace std { - -template <> -inline void swap(winapi::process::Stream& a, winapi::process::Stream& b) BOOST_NOEXCEPT_OR_NOTHROW { - a.swap(b); -} - -} // namespace std diff --git a/src/process.cpp b/src/process.cpp index 1e0a970..9fe19e5 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -26,7 +27,7 @@ namespace { typedef std::vector EscapedCommandLine; -Handle create_process(EscapedCommandLine cmd_line, Process::IO& io) { +Handle create_process(EscapedCommandLine cmd_line, process::IO& io) { BOOST_STATIC_CONSTEXPR DWORD flags = /*CREATE_NO_WINDOW | */ CREATE_UNICODE_ENVIRONMENT; STARTUPINFOW startup_info; @@ -64,23 +65,17 @@ EscapedCommandLine escape_command_line(const CommandLine& cmd_line) { return buffer; } -Handle create_process(const CommandLine& cmd_line, Process::IO& io) { +Handle create_process(const CommandLine& cmd_line, process::IO& io) { return create_process(escape_command_line(cmd_line), io); } } // namespace -void Process::IO::close() { - std_in.handle.close(); - std_out.handle.close(); - std_err.handle.close(); -} - Process Process::create(const CommandLine& cmd_line) { return create(cmd_line, {}); } -Process Process::create(const CommandLine& cmd_line, IO io) { +Process Process::create(const CommandLine& cmd_line, process::IO io) { return Process{create_process(cmd_line, io)}; } diff --git a/src/process_io.cpp b/src/process_io.cpp new file mode 100644 index 0000000..ec7dbc9 --- /dev/null +++ b/src/process_io.cpp @@ -0,0 +1,115 @@ +// Copyright (c) 2020 Egor Tensin +// This file is part of the "winapi-common" project. +// For details, see https://github.com/egor-tensin/winapi-common. +// Distributed under the MIT License. + +#include +#include +#include +#include + +#include + +#include +#include + +namespace winapi { +namespace process { + +Stdin::Stdin() : Stream{Handle::std_in()} {} + +Stdout::Stdout() : Stream{Handle::std_out()} {} + +Stderr::Stderr() : Stream{Handle::std_err()} {} + +Stdin::Stdin(const std::string& path) : Stream{File::open_r(path)} {} + +Stdin::Stdin(const CanonicalPath& path) : Stream{File::open_r(path)} {} + +Stdout::Stdout(const std::string& path) : Stream{File::open_w(path)} {} + +Stdout::Stdout(const CanonicalPath& path) : Stream{File::open_w(path)} {} + +Stderr::Stderr(const std::string& path) : Stream{File::open_w(path)} {} + +Stderr::Stderr(const CanonicalPath& path) : Stream{File::open_w(path)} {} + +Stdin::Stdin(Pipe& pipe) : Stream{std::move(pipe.read_end())} { + pipe.write_end().dont_inherit(); +} + +Stdout::Stdout(Pipe& pipe) : Stream{std::move(pipe.write_end())} { + pipe.read_end().dont_inherit(); +} + +Stderr::Stderr(Pipe& pipe) : Stream{std::move(pipe.write_end())} { + pipe.read_end().dont_inherit(); +} + +Stream::Stream(Stream&& other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); +} + +Stream& Stream::operator=(Stream other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); + return *this; +} + +void Stream::swap(Stream& other) BOOST_NOEXCEPT_OR_NOTHROW { + using std::swap; + swap(handle, other.handle); +} + +void swap(Stream& a, Stream& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + +Stdin::Stdin(Stdin&& other) BOOST_NOEXCEPT_OR_NOTHROW : Stream{std::move(other)} {} + +Stdin& Stdin::operator=(Stdin other) BOOST_NOEXCEPT_OR_NOTHROW { + Stream::operator=(std::move(other)); + return *this; +} + +Stdout::Stdout(Stdout&& other) BOOST_NOEXCEPT_OR_NOTHROW : Stream{std::move(other)} {} + +Stdout& Stdout::operator=(Stdout other) BOOST_NOEXCEPT_OR_NOTHROW { + Stream::operator=(std::move(other)); + return *this; +} + +Stderr::Stderr(Stderr&& other) BOOST_NOEXCEPT_OR_NOTHROW : Stream{std::move(other)} {} + +Stderr& Stderr::operator=(Stderr other) BOOST_NOEXCEPT_OR_NOTHROW { + Stream::operator=(std::move(other)); + return *this; +} + +void IO::close() { + std_in.handle.close(); + std_out.handle.close(); + std_err.handle.close(); +} + +IO::IO(IO&& other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); +} + +IO& IO::operator=(IO other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); + return *this; +} + +void IO::swap(IO& other) BOOST_NOEXCEPT_OR_NOTHROW { + using std::swap; + swap(std_in, other.std_in); + swap(std_out, other.std_out); + swap(std_err, other.std_err); +} + +void swap(IO& a, IO& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + +} // namespace process +} // namespace winapi diff --git a/src/stream.cpp b/src/stream.cpp deleted file mode 100644 index 76dd5a5..0000000 --- a/src/stream.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2020 Egor Tensin -// This file is part of the "winapi-common" project. -// For details, see https://github.com/egor-tensin/winapi-common. -// Distributed under the MIT License. - -#include -#include -#include -#include - -#include -#include - -namespace winapi { -namespace process { - -Stdin::Stdin() : Stream{Handle::std_in()} {} - -Stdout::Stdout() : Stream{Handle::std_out()} {} - -Stderr::Stderr() : Stream{Handle::std_err()} {} - -Stdin::Stdin(const std::string& path) : Stream{File::open_r(path)} {} - -Stdin::Stdin(const CanonicalPath& path) : Stream{File::open_r(path)} {} - -Stdout::Stdout(const std::string& path) : Stream{File::open_w(path)} {} - -Stdout::Stdout(const CanonicalPath& path) : Stream{File::open_w(path)} {} - -Stderr::Stderr(const std::string& path) : Stream{File::open_w(path)} {} - -Stderr::Stderr(const CanonicalPath& path) : Stream{File::open_w(path)} {} - -Stdin::Stdin(Pipe& pipe) : Stream{std::move(pipe.read_end())} { - pipe.write_end().dont_inherit(); -} - -Stdout::Stdout(Pipe& pipe) : Stream{std::move(pipe.write_end())} { - pipe.read_end().dont_inherit(); -} - -Stderr::Stderr(Pipe& pipe) : Stream{std::move(pipe.write_end())} { - pipe.read_end().dont_inherit(); -} - -} // namespace process -} // namespace winapi diff --git a/test/unit_tests/process.cpp b/test/unit_tests/process.cpp index 0a6cb27..a126f86 100644 --- a/test/unit_tests/process.cpp +++ b/test/unit_tests/process.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,7 @@ BOOST_FIXTURE_TEST_CASE(echo, WithEchoExe) { BOOST_FIXTURE_TEST_CASE(echo_stdout_to_pipe, WithEchoExe) { const CommandLine cmd_line{get_echo_exe(), {"aaa", "bbb", "ccc"}}; - Process::IO io; + process::IO io; Pipe stdout_pipe; io.std_out = Stdout{stdout_pipe}; const auto process = Process::create(cmd_line, std::move(io)); @@ -51,7 +52,7 @@ BOOST_FIXTURE_TEST_CASE(echo_stdout_to_file, WithEchoExe) { const RemoveFileGuard remove_stdout_file{stdout_path}; const CommandLine cmd_line{get_echo_exe(), {"XXX", "YYY", "ZZZ"}}; - Process::IO io; + process::IO io; io.std_out = Stdout{stdout_path}; const auto process = Process::create(cmd_line, std::move(io)); process.wait(); @@ -69,7 +70,7 @@ BOOST_FIXTURE_TEST_CASE(echo_stdin_from_file, WithEchoExe) { File::open_w(stdin_path).write(stdin16); const CommandLine cmd_line{get_echo_exe()}; - Process::IO io; + process::IO io; Pipe stdout_pipe; io.std_in = Stdin{stdin_path}; io.std_out = Stdout{stdout_pipe}; -- cgit v1.2.3