aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/include
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2020-10-16 10:09:55 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2020-10-16 10:12:47 +0300
commita632bb8e796be52929f1541d305910d704e55076 (patch)
tree6a03b50fcb16ef1713f6cbbe5f2377b2fdc10990 /include
parentecho: make it really UTF-16 (diff)
downloadwinapi-common-a632bb8e796be52929f1541d305910d704e55076.tar.gz
winapi-common-a632bb8e796be52929f1541d305910d704e55076.zip
Process: support pipe redirection
Diffstat (limited to 'include')
-rw-r--r--include/winapi/file.hpp28
-rw-r--r--include/winapi/handle.hpp51
-rw-r--r--include/winapi/pipe.hpp26
-rw-r--r--include/winapi/process.hpp12
-rw-r--r--include/winapi/stream.hpp42
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