inline bool wait_for(
        child_handle &p,
        int & exit_code,
        const std::chrono::duration<Rep, Period>& rel_time)
{

    std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(rel_time);

    ::boost::detail::winapi::DWORD_ wait_code;
    wait_code = ::boost::detail::winapi::WaitForSingleObject(p.process_handle(),
                   static_cast<::boost::detail::winapi::DWORD_>(ms.count()));
    if (wait_code == ::boost::detail::winapi::wait_failed)
        throw_last_error("WaitForSingleObject() failed");
    else if (wait_code == ::boost::detail::winapi::wait_timeout)
        return false; //

    ::boost::detail::winapi::DWORD_ _exit_code;
    if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
        throw_last_error("GetExitCodeProcess() failed");

    exit_code = static_cast<int>(_exit_code);
    ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess);
    p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_;
    return true;
}
inline void wait(child_handle &p, int & exit_code)
{
    if (::boost::detail::winapi::WaitForSingleObject(p.process_handle(),
        ::boost::detail::winapi::infinite) == ::boost::detail::winapi::wait_failed)
            throw_last_error("WaitForSingleObject() failed");

    ::boost::detail::winapi::DWORD_ _exit_code;
    if (!::boost::detail::winapi::GetExitCodeProcess(p.process_handle(), &_exit_code))
        throw_last_error("GetExitCodeProcess() failed");

    ::boost::detail::winapi::CloseHandle(p.proc_info.hProcess);
    p.proc_info.hProcess = ::boost::detail::winapi::INVALID_HANDLE_VALUE_;
    exit_code = static_cast<int>(_exit_code);
}
 bool in_group() const
 {
     ::boost::detail::winapi::BOOL_ value;
     if (!::boost::detail::winapi::IsProcessInJob(proc_info.hProcess, nullptr, &value))
         throw_last_error("IsProcessinJob Failed");
     return value!=0;
 }
inline void wait(const group_handle &p)
{
    if (::boost::detail::winapi::WaitForSingleObject(p.handle(),
        ::boost::detail::winapi::infinite) == ::boost::detail::winapi::wait_failed)
            throw_last_error("WaitForSingleObject() failed");

}
Example #5
0
inline bool in_group()
{
    ::boost::winapi::BOOL_ res;
    if (!::boost::winapi::IsProcessInJob(boost::winapi::GetCurrentProcess(), nullptr, &res))
        throw_last_error("IsProcessInJob failed");

    return res!=0;
}
Example #6
0
    bool has(handle_t proc)
    {
        ::boost::winapi::BOOL_ is;
        if (!::boost::winapi::IsProcessInJob(proc, _job_object,  &is))
            throw_last_error();

        return is!=0;
    }
Example #7
0
AttributeHandleList::AttributeHandleList(std::vector<HANDLE> handle_list)
    : m_handle_store(nullptr),
      m_pAttributeList(nullptr, attribute_list_deleter)
{
    size_t size = 0;
    BOOL ok = ::InitializeProcThreadAttributeList(NULL, 1, 0, &size)
              || ::GetLastError() == ERROR_INSUFFICIENT_BUFFER;
    if (!ok) throw_last_error("InitializeProcThreadAttributeList(NULL, ...) failed");

    m_pAttributeList.reset(reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(new char[size]));
    ok = ::InitializeProcThreadAttributeList(m_pAttributeList.get(), 1, 0, &size);
    if (!ok) {
        delete[] reinterpret_cast<char*>(m_pAttributeList.release());
        throw_last_error("InitializeProcThreadAttributeList() failed");
    }

    // WARNING: O(n^2), ok for small lists:
    for (size_t i = 0; i < handle_list.size(); i++) {
        size_t next = i + 1;
        while (1) {
            auto it = std::find(handle_list.begin() + next, handle_list.end(), handle_list.at(i));
            if (it == handle_list.end())
                break;
            next = it - handle_list.begin();
            handle_list.erase(it);
        }
    }

    m_handle_store.reset(new HANDLE[handle_list.size()]);
    if (handle_list.size()) { // C++ is evil:
        // data() is not undefined behavior even if handle_list is empty,
        // however it is allowed to be nullptr in this case, while memcpy
        // requires the src to never be nullptr, even for a zero size.
        std::memcpy(m_handle_store.get(), handle_list.data(), handle_list.size() * sizeof(HANDLE));
    }

    ok = ::UpdateProcThreadAttribute(m_pAttributeList.get(),
                    0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
                    (PVOID)m_handle_store.get(),
                    handle_list.size() * sizeof(HANDLE),
                    NULL, NULL);
    if (!ok) throw_last_error("UpdateProcThreadAttribute() failed");
}
Example #8
0
basic_pipe<Char, Traits>::basic_pipe(const basic_pipe & p)
{
    auto proc = ::boost::detail::winapi::GetCurrentProcess();

    if (p._source == ::boost::detail::winapi::INVALID_HANDLE_VALUE_)
        _source = ::boost::detail::winapi::INVALID_HANDLE_VALUE_;
    else if (!::boost::detail::winapi::DuplicateHandle(
            proc, p._source, proc, &_source, 0,
            static_cast<::boost::detail::winapi::BOOL_>(true),
             ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_))
        throw_last_error("Duplicate Pipe Failed");

    if (p._sink == ::boost::detail::winapi::INVALID_HANDLE_VALUE_)
        _sink = ::boost::detail::winapi::INVALID_HANDLE_VALUE_;
    else if (!::boost::detail::winapi::DuplicateHandle(
            proc, p._sink, proc, &_sink, 0,
            static_cast<::boost::detail::winapi::BOOL_>(true),
             ::boost::detail::winapi::DUPLICATE_SAME_ACCESS_))
        throw_last_error("Duplicate Pipe Failed");

}
    explicit child_handle(pid_t pid) :
                                  proc_info{nullptr, nullptr, 0,0}
    {
        auto h = ::boost::detail::winapi::OpenProcess(
                ::boost::detail::winapi::PROCESS_ALL_ACCESS_,
                static_cast<::boost::detail::winapi::BOOL_>(0),
                 pid);

        if (h == nullptr)
            throw_last_error("OpenProcess() failed");
        proc_info.hProcess = h;
        proc_info.dwProcessId = pid;
    }
Example #10
0
inline void associate_completion_port(::boost::winapi::HANDLE_ job,
                                      ::boost::winapi::HANDLE_ io_port)
{
    workaround::JOBOBJECT_ASSOCIATE_COMPLETION_PORT_ port;
    port.CompletionKey  = job;
    port.CompletionPort = io_port;

    if (!workaround::set_information_job_object(
            job,
            workaround::JobObjectAssociateCompletionPortInformation_,
            static_cast<void*>(&port),
            sizeof(port)))
        throw_last_error("SetInformationJobObject() failed");
}
Example #11
0
inline bool break_away_enabled(::boost::winapi::HANDLE_ h)
{
    workaround::JOBOBJECT_EXTENDED_LIMIT_INFORMATION_ info;

    if (!workaround::query_information_job_object(
                    h,
                    workaround::JobObjectExtendedLimitInformation_,
                    static_cast<void*>(&info),
                    sizeof(info),
                    nullptr))
        throw_last_error("QueryInformationJobObject() failed");

    return (info.BasicLimitInformation.LimitFlags & workaround::JOB_OBJECT_LIMIT_BREAKAWAY_OK_) != 0;
}
Example #12
0
static HANDLE open_inheritable_nul(bool output)
{
    SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE };
    HANDLE hret = ::CreateFileA("nul",
                                output ? GENERIC_WRITE : GENERIC_READ,
                                FILE_SHARE_READ | FILE_SHARE_WRITE,
                                &sec_attr,
                                OPEN_EXISTING,
                                0,
                                NULL);
    if (hret == NULL || hret == INVALID_HANDLE_VALUE)
        throw_last_error("CreateFile(\"nul\",...) failed");
    return hret;
}
inline bool wait_for(
        const group_handle &p,
        const std::chrono::duration<Rep, Period>& rel_time)
{

    std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(rel_time);

    ::boost::detail::winapi::DWORD_ wait_code;
    wait_code = ::boost::detail::winapi::WaitForSingleObject(p.handle(), ms.count());
    if (wait_code == ::boost::detail::winapi::wait_failed)
        throw_last_error("WaitForSingleObject() failed");
    else if (wait_code == ::boost::detail::winapi::wait_timeout)
        return false; //

    return true;
}
inline bool wait_until(
        const group_handle &p,
        const std::chrono::time_point<Clock, Duration>& timeout_time)
{
    std::chrono::milliseconds ms =
            std::chrono::duration_cast<std::chrono::milliseconds>(
                    timeout_time - std::chrono::system_clock::now());

    ::boost::detail::winapi::DWORD_ wait_code;
    wait_code = ::boost::detail::winapi::WaitForSingleObject(p.handle(), ms.count());

    if (wait_code == ::boost::detail::winapi::wait_failed)
        throw_last_error("WaitForSingleObject() failed");

    else if (wait_code == ::boost::detail::winapi::wait_timeout)
        return false; //

    return true;
}
Example #15
0
 void add(handle_t proc)
 {
     if (!::boost::winapi::AssignProcessToJobObject(_job_object, proc))
         throw_last_error();
 }
Example #16
0
    basic_pipe()
    {
        if (!::boost::detail::winapi::CreatePipe(&_source, &_sink, nullptr, 0))
            throw_last_error("CreatePipe() failed");

    }