aboutsummaryrefslogtreecommitdiff
path: root/butl/process
blob: 52aad41e654fbf881473b7b48bc546cb9b64146c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// file      : butl/process -*- C++ -*-
// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

#ifndef BUTL_PROCESS
#define BUTL_PROCESS

#ifndef _WIN32
#  include <sys/types.h> // pid_t
#endif

#include <cassert>
#include <system_error>

namespace butl
{
  struct process_error: std::system_error
  {
    process_error (int e, bool child)
        : system_error (e, std::system_category ()), child_ (child) {}

    bool
    child () const {return child_;}

  private:
    bool child_;
  };

  struct process
  {
    // Start another process using the specified command line. Connect the
    // newly created process' stdin to out_fd. Also if connect_* are true,
    // connect the created process' stdout and stderr to in_*fd. Throw
    // process_error if anything goes wrong.
    //
    // Note that some of the exceptions (e.g., if exec() failed) can be
    // thrown in the child version of us.
    //
    process (char const* args[],
             bool connect_stdin = false,
             bool connect_stderr = false,
             bool connect_stdout = false);

    // Wait for the process to terminate. Return true if the process
    // terminated normally and with the zero exit status. Throw
    // process_error if anything goes wrong.
    //
    bool
    wait ();

    ~process () {if (id != 0) wait ();}

#ifndef _WIN32
    typedef pid_t id_type;
#else
    typedef void* id_type; // Win32 HANDLE.
#endif

    id_type id;
    int out_fd; // Write to this fd to send to the new process' stdin.
    int in_efd; // Read from this fd to receive from the new process' stderr.
    int in_ofd; // Read from this fd to receive from the new process' stdout.
  };
}

#endif // BUTL_PROCESS