diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2020-10-16 10:09:55 +0300 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2020-10-16 10:12:47 +0300 |
commit | a632bb8e796be52929f1541d305910d704e55076 (patch) | |
tree | 6a03b50fcb16ef1713f6cbbe5f2377b2fdc10990 /include/winapi | |
parent | echo: make it really UTF-16 (diff) | |
download | winapi-common-a632bb8e796be52929f1541d305910d704e55076.tar.gz winapi-common-a632bb8e796be52929f1541d305910d704e55076.zip |
Process: support pipe redirection
Diffstat (limited to 'include/winapi')
-rw-r--r-- | include/winapi/file.hpp | 28 | ||||
-rw-r--r-- | include/winapi/handle.hpp | 51 | ||||
-rw-r--r-- | include/winapi/pipe.hpp | 26 | ||||
-rw-r--r-- | include/winapi/process.hpp | 12 | ||||
-rw-r--r-- | include/winapi/stream.hpp | 42 |
5 files changed, 137 insertions, 22 deletions
diff --git a/include/winapi/file.hpp b/include/winapi/file.hpp new file mode 100644 index 0000000..60a8f1d --- /dev/null +++ b/include/winapi/file.hpp @@ -0,0 +1,28 @@ +// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com> +// 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 <string> +#include <utility> + +namespace winapi { + +class File : private Handle { +public: + explicit File(Handle&& handle) : Handle{std::move(handle)} {} + + static Handle open_for_reading(const std::string&); + static Handle open_for_writing(const std::string&); + + using Handle::close; + + using Handle::read; + using Handle::write; +}; + +} // namespace winapi diff --git a/include/winapi/handle.hpp b/include/winapi/handle.hpp index 9714db3..af37424 100644 --- a/include/winapi/handle.hpp +++ b/include/winapi/handle.hpp @@ -5,50 +5,57 @@ #pragma once -#include "workarounds.hpp" - #include <boost/config.hpp> #include <windows.h> -#include <cassert> +#include <cstddef> #include <memory> #include <utility> +#include <vector> namespace winapi { class Handle { public: Handle() = default; + explicit Handle(HANDLE); + + Handle(Handle&& other) BOOST_NOEXCEPT_OR_NOTHROW; + Handle& operator=(Handle other) BOOST_NOEXCEPT_OR_NOTHROW; + + void swap(Handle& other) BOOST_NOEXCEPT_OR_NOTHROW; + + explicit operator HANDLE() const { return m_impl.get(); } + + bool is_invalid() const; + + void close(); + + bool is_std() const; + static Handle std_in(); + static Handle std_out(); + static Handle std_err(); - explicit Handle(HANDLE raw) : impl{raw} {} + typedef std::vector<unsigned char> Buffer; - Handle(Handle&& other) BOOST_NOEXCEPT_OR_NOTHROW { swap(other); } + Buffer read() const; - Handle& operator=(Handle other) BOOST_NOEXCEPT_OR_NOTHROW { - swap(other); - return *this; - } + BOOST_STATIC_CONSTEXPR std::size_t max_chunk_size = 16 * 1024; + bool read_chunk(Buffer& read_chunk) const; - void swap(Handle& other) BOOST_NOEXCEPT_OR_NOTHROW { - using std::swap; - swap(impl, other.impl); - } + void write(const void*, std::size_t nb) const; + void write(const Buffer& buffer) const; - explicit operator HANDLE() const { return impl.get(); } + void inherit(bool yes = true) const; + void dont_inherit() const { inherit(false); } private: struct Close { - void operator()(HANDLE raw) const { - if (raw == NULL || raw == INVALID_HANDLE_VALUE) - return; - const auto ret = ::CloseHandle(raw); - assert(ret); - WINAPI_UNUSED_PARAMETER(ret); - } + void operator()(HANDLE) const; }; - std::unique_ptr<void, Close> impl; + std::unique_ptr<void, Close> m_impl; Handle(const Handle&) = delete; }; diff --git a/include/winapi/pipe.hpp b/include/winapi/pipe.hpp new file mode 100644 index 0000000..ebd99e8 --- /dev/null +++ b/include/winapi/pipe.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com> +// 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" + +namespace winapi { + +class Pipe { +public: + Pipe(); + + Handle& read_end() { return m_read_end; } + const Handle& read_end() const { return m_read_end; } + Handle& write_end() { return m_write_end; } + const Handle& write_end() const { return m_write_end; } + +private: + Handle m_read_end; + Handle m_write_end; +}; + +} // namespace winapi diff --git a/include/winapi/process.hpp b/include/winapi/process.hpp index d20ac38..22317ca 100644 --- a/include/winapi/process.hpp +++ b/include/winapi/process.hpp @@ -3,8 +3,11 @@ // For details, see https://github.com/egor-tensin/winapi-common. // Distributed under the MIT License. +#pragma once + #include "cmd_line.hpp" #include "handle.hpp" +#include "stream.hpp" #include <utility> @@ -12,7 +15,16 @@ namespace winapi { class Process { public: + struct IO { + process::Stdin std_in; + process::Stdout std_out; + process::Stderr std_err; + + void close(); + }; + static Process create(const CommandLine&); + static Process create(const CommandLine&, IO); void wait(); diff --git a/include/winapi/stream.hpp b/include/winapi/stream.hpp new file mode 100644 index 0000000..cf85508 --- /dev/null +++ b/include/winapi/stream.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com> +// 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 "pipe.hpp" + +#include <string> +#include <utility> + +namespace winapi { +namespace process { + +struct Stream { + Stream(Handle&& handle) : handle{std::move(handle)} {} + + Handle handle; +}; + +struct Stdin : Stream { + Stdin(); + explicit Stdin(const std::string& file); + explicit Stdin(Pipe&); +}; + +struct Stdout : Stream { + Stdout(); + explicit Stdout(const std::string& file); + explicit Stdout(Pipe&); +}; + +struct Stderr : Stream { + Stderr(); + explicit Stderr(const std::string& file); + explicit Stderr(Pipe&); +}; + +} // namespace process +} // namespace winapi |