review: ProcessHandle + minor changes
This commit is contained in:
parent
438886b425
commit
17318fdd4e
@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <uv.h>
|
||||
#include "event.hpp"
|
||||
#include "handle.hpp"
|
||||
@ -70,7 +72,13 @@ public:
|
||||
using Process = details::UVProcessFlags;
|
||||
using StdIO = details::UVStdIOFlags;
|
||||
|
||||
using Handle::Handle;
|
||||
ProcessHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref)
|
||||
: Handle{std::move(ca), std::move(ref)}
|
||||
{
|
||||
auto ignore = static_cast<uv_stdio_flags>(StdIO::IGNORE_STREAM);
|
||||
auto stdin = uv_stdio_container_t{ignore};
|
||||
poFdStdio.push_back(std::move(stdin));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables inheritance for file descriptors/handles.
|
||||
@ -130,11 +138,20 @@ public:
|
||||
po.env = env;
|
||||
po.cwd = poCwd.empty() ? nullptr : poCwd.data();
|
||||
po.flags = poFlags;
|
||||
po.stdio_count = poStdio.size();
|
||||
po.stdio = poStdio.data();
|
||||
po.uid = poUid;
|
||||
po.gid = poGid;
|
||||
|
||||
/**
|
||||
* See the constructor, poFdStdio[0] is stdin. It must be poStdio[0] by
|
||||
* convention. From the official documentation:
|
||||
*
|
||||
* > The convention is that stdio[0] points to stdin, fd 1 is used
|
||||
* > for stdout, and fd 2 is stderr.
|
||||
*/
|
||||
std::vector<uv_stdio_container_t> poStdio{poFdStdio.size() + poStreamStdio.size()};
|
||||
poStdio.insert(poStdio.begin(), poStreamStdio.cbegin(), poStreamStdio.cend());
|
||||
poStdio.insert(poStdio.begin(), poFdStdio.cbegin(), poFdStdio.cend());
|
||||
|
||||
invoke(&uv_spawn, parent(), get(), &po);
|
||||
}
|
||||
|
||||
@ -206,17 +223,17 @@ public:
|
||||
* [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_stdio_flags)
|
||||
* for further details.
|
||||
*
|
||||
* @param flags A valid set of flags.
|
||||
* @param stream A valid `stdio` handle.
|
||||
* @param flags A valid set of flags.
|
||||
* @return A reference to this process handle.
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
ProcessHandle& stdio(Flags<StdIO> flags, StreamHandle<T, U> &stream) {
|
||||
ProcessHandle& stdio(StreamHandle<T, U> &stream, Flags<StdIO> flags) {
|
||||
uv_stdio_container_t container;
|
||||
Flags<StdIO>::Type fgs = flags;
|
||||
container.flags = static_cast<uv_stdio_flags>(fgs);
|
||||
container.data.stream = get<uv_stream_t>(stream);
|
||||
poStdio.push_back(std::move(container));
|
||||
poStreamStdio.push_back(std::move(container));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -232,20 +249,42 @@ public:
|
||||
* * `ProcessHandle::StdIO::READABLE_PIPE`
|
||||
* * `ProcessHandle::StdIO::WRITABLE_PIPE`
|
||||
*
|
||||
* Default file descriptors are:
|
||||
* * `uvw::StdIN` for `stdin`
|
||||
* * `uvw::StdOUT` for `stdout`
|
||||
* * `uvw::StdERR` for `stderr`
|
||||
*
|
||||
* See the official
|
||||
* [documentation](http://docs.libuv.org/en/v1.x/process.html#c.uv_stdio_flags)
|
||||
* for further details.
|
||||
*
|
||||
* @param flags A valid set of flags.
|
||||
* @param fd A valid file descriptor.
|
||||
* @param flags A valid set of flags.
|
||||
* @return A reference to this process handle.
|
||||
*/
|
||||
ProcessHandle& stdio(Flags<StdIO> flags, FileHandle fd) {
|
||||
uv_stdio_container_t container;
|
||||
Flags<StdIO>::Type fgs = flags;
|
||||
container.flags = static_cast<uv_stdio_flags>(fgs);
|
||||
container.data.fd = fd;
|
||||
poStdio.push_back(std::move(container));
|
||||
ProcessHandle& stdio(FileHandle fd, Flags<StdIO> flags) {
|
||||
auto fgs = static_cast<uv_stdio_flags>(Flags<StdIO>::Type{flags});
|
||||
|
||||
auto actual = FileHandle::Type{fd};
|
||||
|
||||
if(actual == FileHandle::Type{StdIN}) {
|
||||
poFdStdio[0].flags = fgs;
|
||||
} else {
|
||||
auto it = std::find_if(poFdStdio.begin(), poFdStdio.end(), [actual](auto &&container){
|
||||
return container.data.fd == actual;
|
||||
});
|
||||
|
||||
if(it == poFdStdio.cend()) {
|
||||
uv_stdio_container_t container;
|
||||
container.flags = fgs;
|
||||
container.data.fd = actual;
|
||||
poFdStdio.push_back(std::move(container));
|
||||
} else {
|
||||
it->flags = fgs;
|
||||
it->data.fd = actual;
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -272,7 +311,8 @@ public:
|
||||
private:
|
||||
std::string poCwd;
|
||||
Flags<Process> poFlags;
|
||||
std::vector<uv_stdio_container_t> poStdio;
|
||||
std::vector<uv_stdio_container_t> poFdStdio;
|
||||
std::vector<uv_stdio_container_t> poStreamStdio;
|
||||
Uid poUid;
|
||||
Gid poGid;
|
||||
};
|
||||
|
||||
@ -41,9 +41,9 @@ enum class UVTTYModeT: std::underlying_type_t<uv_tty_mode_t> {
|
||||
* To create a `TTYHandle` through a `Loop`, arguments follow:
|
||||
*
|
||||
* * A valid FileHandle. Usually the file descriptor will be:
|
||||
* * `0` = `stdin`
|
||||
* * `1` = `stdout`
|
||||
* * `2` = `stderr`
|
||||
* * `uvw::StdIN` or `0` for `stdin`
|
||||
* * `uvw::StdOUT` or `1` for `stdout`
|
||||
* * `uvw::StdERR` or `2` for `stderr`
|
||||
* * A boolean value that specifies the plan on calling `read()` with this
|
||||
* stream. Remember that `stdin` is readable, `stdout` is not.
|
||||
*
|
||||
|
||||
@ -186,6 +186,10 @@ using FileHandle = details::UVTypeWrapper<uv_file>;
|
||||
using OSSocketHandle = details::UVTypeWrapper<uv_os_sock_t>;
|
||||
using OSFileDescriptor = details::UVTypeWrapper<uv_os_fd_t>;
|
||||
|
||||
constexpr FileHandle StdIN{0}; /*!< Placeholder for stdin descriptor. */
|
||||
constexpr FileHandle StdOUT{1}; /*!< Placeholder for stdout descriptor. */
|
||||
constexpr FileHandle StdERR{2}; /*!< Placeholder for stderr descriptor. */
|
||||
|
||||
using TimeSpec = uv_timespec_t;
|
||||
using Stat = uv_stat_t;
|
||||
using Uid = uv_uid_t;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user