File: quickstart.qbk

package info (click to toggle)
boost1.83 1.83.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 545,632 kB
  • sloc: cpp: 3,857,086; xml: 125,552; ansic: 34,414; python: 25,887; asm: 5,276; sh: 4,799; ada: 1,681; makefile: 1,629; perl: 1,212; pascal: 1,139; sql: 810; yacc: 478; ruby: 102; lisp: 24; csh: 6
file content (124 lines) | stat: -rw-r--r-- 3,566 bytes parent folder | download | duplicates (3)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
[section:quickstart Quickstart]

A process needs four things to be launched:

* an asio execution_context / executor 
* a path to an executable
* a list of arguments
* a variadic set of initializers

```
     // process(asio::any_io_executor, filesystem::path, range<string> args, AdditionalInitializers...)
    asio::io_context ctx;
    process proc(ctx, "/usr/bin/cp", {"source.txt", "target.txt"});
```
 

The started process can then be awaited or terminated.

[section:lifetime Lifetime]

If the process handle goes out of scope, it will terminate the subprocess.
You can prevent this, by calling `proc.detach()`; do however note that this 
can lead to zombie processes.

A process that completed will deliver an exit-code, 
which can be obtained by calling `.exit_code` on the exited process and which is
also returned from `.wait()`.

```
 process proc("/bin/ls", {});
 assert(proc.wait() == 0);
```

The normal exit-code is what the subprocess returned from `main`;
posix will however add additional information about the process.
This is called the `native_exit_code`.


The `.running()` function can be used to detect if the process is still active.

[endsect]

[section:signal Signalling the subprocess]

The parent process can signal the subprocess demanding certain actions.

`.terminate` will cause the subprocess to exit immediately (`SIGKILL` on posix).
This is the only reliable & portable way to end a subprocess.

```
    process proc("/bin/totally-not-a-virus", {});
    proc.terminate();
```

`.request_exit` will ask the subprocess to shutdown (`SIGTERM` on posix),
which the subprocess might ignore.

```
    process proc("/bin/bash", {});
    proc.request_exit();
    proc.wait();
```

`.interrupt` will send an SIGINT to the subprocess, which a subprocess might 
interpret as a signal to shutdown.

[warning interrupt requires the initializer `windows::create_new_process_group` to be set]

```
    process proc("/usr/bin/addr2line", {});
    proc.request_exit();
    proc.wait();
```

[endsect]

[section:execute Execute functions]

Process v2 provides  `execute` and `async_execute` functions that can be used for managed executions.

```
 assert(execute(process("/bin/ls", {}) == 0));
```

The async version supports cancellation and will forward cancellation types as follows:

- asio::cancellation_type::total    -> interrupt
- asio::cancellation_type::partial  -> request_exit
- asio::cancellation_type::terminal -> terminate

```
    asio::io_context ctx;
    asio::steady_timer timeout{ctx, std::chrono::seconds(10)};

    asio::cancellation_signal sig;
    async_execute(process("/usr/bin/g++", {"hello_world.cpp"}), 
                 asio::bind_cancellation_slot(sig.slot(), 
                                              [&](error_code ec, int exit_code)
                                              {
                                                  timeout.cancel(); // we're done earlier
                                              }));

    timeout.async_wait(
        [&](error_code ec) 
        {
            if (ec) // we were cancelled, do nothing
                return ;
            sig.emit(asio::cancellation_type::partial); 
            // request exit first, but terminate after another 10 sec
            timeout.expires_after(std::chrono::seconds(10));
            timeout.async_wait(
                [&](error_code ec)
                {
                    if (!ec)
                        sig.emit(asio::cancellation_type::terminal); 
                });
            );
        });

```

[endsect]

[endsect]