# ProcessMonitor
<span class="source-link">[[Source]](src/process/process_monitor.md#L187)</span>

Forks and monitors a process. Notifies a client about STDOUT / STDERR events.


```pony
actor tag ProcessMonitor
```

## Constructors

### create
<span class="source-link">[[Source]](src/process/process_monitor.md#L221)</span>


Create infrastructure to communicate with a forked child process
and register the asio events. Fork child process and notify our
user about incoming data via the notifier.


```pony
new tag create(
  auth: (AmbientAuth val | StartProcessAuth val),
  backpressure_auth: (AmbientAuth val | ApplyReleaseBackpressureAuth val),
  notifier: ProcessNotify iso,
  filepath: FilePath val,
  args: Array[String val] val,
  vars: Array[String val] val)
: ProcessMonitor tag^
```
#### Parameters

*   auth: ([AmbientAuth](builtin-AmbientAuth) val | [StartProcessAuth](process-StartProcessAuth) val)
*   backpressure_auth: ([AmbientAuth](builtin-AmbientAuth) val | [ApplyReleaseBackpressureAuth](backpressure-ApplyReleaseBackpressureAuth) val)
*   notifier: [ProcessNotify](process-ProcessNotify) iso
*   filepath: [FilePath](files-FilePath) val
*   args: [Array](builtin-Array)\[[String](builtin-String) val\] val
*   vars: [Array](builtin-Array)\[[String](builtin-String) val\] val

#### Returns

* [ProcessMonitor](process-ProcessMonitor) tag^

---

## Public Behaviours

### print
<span class="source-link">[[Source]](src/process/process_monitor.md#L412)</span>


Print some bytes and append a newline.


```pony
be print(
  data: (String val | Array[U8 val] val))
```
#### Parameters

*   data: ([String](builtin-String) val | [Array](builtin-Array)\[[U8](builtin-U8) val\] val)

---

### write
<span class="source-link">[[Source]](src/process/process_monitor.md#L424)</span>


Write to STDIN of the child process.


```pony
be write(
  data: (String val | Array[U8 val] val))
```
#### Parameters

*   data: ([String](builtin-String) val | [Array](builtin-Array)\[[U8](builtin-U8) val\] val)

---

### printv
<span class="source-link">[[Source]](src/process/process_monitor.md#L434)</span>


Print an iterable collection of ByteSeqs.


```pony
be printv(
  data: ByteSeqIter val)
```
#### Parameters

*   data: [ByteSeqIter](builtin-ByteSeqIter) val

---

### writev
<span class="source-link">[[Source]](src/process/process_monitor.md#L442)</span>


Write an iterable collection of ByteSeqs.


```pony
be writev(
  data: ByteSeqIter val)
```
#### Parameters

*   data: [ByteSeqIter](builtin-ByteSeqIter) val

---

### done_writing
<span class="source-link">[[Source]](src/process/process_monitor.md#L454)</span>


Set the _done_writing flag to true. If the _pending is empty we can
close the _stdin_write file descriptor.


```pony
be done_writing()
```

---

### dispose
<span class="source-link">[[Source]](src/process/process_monitor.md#L465)</span>


Terminate child and close down everything.


```pony
be dispose()
```

---

## Public Functions

### expect
<span class="source-link">[[Source]](src/process/process_monitor.md#L473)</span>


A `stdout` call on the notifier must contain exactly `qty` bytes. If
`qty` is zero, the call can contain any amount of data.


```pony
fun ref expect(
  qty: USize val = seq)
: None val
```
#### Parameters

*   qty: [USize](builtin-USize) val = seq

#### Returns

* [None](builtin-None) val

---

## Private Behaviours

### _event_notify
<span class="source-link">[[Source]](src/process/process_monitor.md#L510)</span>


Handle the incoming event.


```pony
be _event_notify(
  event: Pointer[AsioEvent val] tag,
  flags: U32 val,
  arg: U32 val)
```
#### Parameters

*   event: [Pointer](builtin-Pointer)\[[AsioEvent](builtin-AsioEvent) val\] tag
*   flags: [U32](builtin-U32) val
*   arg: [U32](builtin-U32) val

---

### _read_again
<span class="source-link">[[Source]](src/process/process_monitor.md#L683)</span>


Resume reading on file descriptor.


```pony
be _read_again(
  fd: U32 val)
```
#### Parameters

*   fd: [U32](builtin-U32) val

---

## Private Functions

### _child
<span class="source-link">[[Source]](src/process/process_monitor.md#L295)</span>


We are now in the child process. We redirect STDIN, STDOUT and STDERR
to their pipes and execute the command. The command is executed via
execve which does not return on success, and the text, data, bss, and
stack of the calling process are overwritten by that of the program
loaded. We've set the FD_CLOEXEC flag on all file descriptors to ensure
that they are all closed automatically once @execve gets called.


```pony
fun box _child(
  path: String val,
  argp: Array[Pointer[U8 val] tag] ref,
  envp: Array[Pointer[U8 val] tag] ref)
: None val
```
#### Parameters

*   path: [String](builtin-String) val
*   argp: [Array](builtin-Array)\[[Pointer](builtin-Pointer)\[[U8](builtin-U8) val\] tag\] ref
*   envp: [Array](builtin-Array)\[[Pointer](builtin-Pointer)\[[U8](builtin-U8) val\] tag\] ref

#### Returns

* [None](builtin-None) val

---

### _parent
<span class="source-link">[[Source]](src/process/process_monitor.md#L319)</span>


We're now in the parent process. We setup asio events for STDOUT and STDERR
and close the file descriptors we don't need.


```pony
fun ref _parent()
: None val
```

#### Returns

* [None](builtin-None) val

---

### _make_argv
<span class="source-link">[[Source]](src/process/process_monitor.md#L336)</span>


Convert an array of String parameters into an array of
C pointers to same strings.


```pony
fun box _make_argv(
  args: Array[String val] box)
: Array[Pointer[U8 val] tag] ref
```
#### Parameters

*   args: [Array](builtin-Array)\[[String](builtin-String) val\] box

#### Returns

* [Array](builtin-Array)\[[Pointer](builtin-Pointer)\[[U8](builtin-U8) val\] tag\] ref

---

### _dup2
<span class="source-link">[[Source]](src/process/process_monitor.md#L348)</span>


Creates a copy of the file descriptor oldfd using the file
descriptor number specified in newfd. If the file descriptor newfd
was previously open, it is silently closed before being reused.
If dup2() fails because of EINTR we retry.


```pony
fun box _dup2(
  oldfd: U32 val,
  newfd: U32 val)
: None val
```
#### Parameters

*   oldfd: [U32](builtin-U32) val
*   newfd: [U32](builtin-U32) val

#### Returns

* [None](builtin-None) val

---

### _make_pipe
<span class="source-link">[[Source]](src/process/process_monitor.md#L365)</span>


Creates a pipe, an unidirectional data channel that can be used
for interprocess communication. We need to set the flag on the
two file descriptors here to prevent capturing by another thread.


```pony
fun box _make_pipe(
  fd_flags: I32 val)
: (U32 val , U32 val) ?
```
#### Parameters

*   fd_flags: [I32](builtin-I32) val

#### Returns

* ([U32](builtin-U32) val , [U32](builtin-U32) val) ?

---

### _getflags
<span class="source-link">[[Source]](src/process/process_monitor.md#L383)</span>


Get the string representation of flags set for a file descriptor


```pony
fun box _getflags(
  fd: U32 val)
: String box ?
```
#### Parameters

*   fd: [U32](builtin-U32) val

#### Returns

* [String](builtin-String) box ?

---

### _set_fd
<span class="source-link">[[Source]](src/process/process_monitor.md#L404)</span>


```pony
fun box _set_fd(
  fd: U32 val,
  flags: I32 val)
: None val ?
```
#### Parameters

*   fd: [U32](builtin-U32) val
*   flags: [I32](builtin-I32) val

#### Returns

* [None](builtin-None) val ?

---

### _set_fl
<span class="source-link">[[Source]](src/process/process_monitor.md#L408)</span>


```pony
fun box _set_fl(
  fd: U32 val,
  flags: I32 val)
: None val ?
```
#### Parameters

*   fd: [U32](builtin-U32) val
*   flags: [I32](builtin-I32) val

#### Returns

* [None](builtin-None) val ?

---

### _print_final
<span class="source-link">[[Source]](src/process/process_monitor.md#L450)</span>


```pony
fun ref _print_final(
  data: (String val | Array[U8 val] val))
: None val
```
#### Parameters

*   data: ([String](builtin-String) val | [Array](builtin-Array)\[[U8](builtin-U8) val\] val)

#### Returns

* [None](builtin-None) val

---

### _kill_child
<span class="source-link">[[Source]](src/process/process_monitor.md#L481)</span>


Terminate the child process, first trying SIGTERM and if
that fails try SIGKILL.


```pony
fun box _kill_child()
: None val
```

#### Returns

* [None](builtin-None) val

---

### _event_flags
<span class="source-link">[[Source]](src/process/process_monitor.md#L500)</span>


Return all flags of an event as a string.


```pony
fun box _event_flags(
  flags: U32 val)
: String box
```
#### Parameters

*   flags: [U32](builtin-U32) val

#### Returns

* [String](builtin-String) box

---

### _close_fd
<span class="source-link">[[Source]](src/process/process_monitor.md#L539)</span>


Close a file descriptor.  This function also handles unsubscribing
the asio event (if the file descriptor has one), the file
descriptor should always be closed _after_ unsubscribing the
event, otherwise there is the possibility of reusing the file
descriptor in another thread and then unsubscribing the reused
file descriptor here!  Unsubscribing and closing the file
descriptor should be treated as one operation, and as this
function is called from many places in this module put the
unsubscribing logic here too.


```pony
fun ref _close_fd(
  fd: U32 val)
: None val
```
#### Parameters

*   fd: [U32](builtin-U32) val

#### Returns

* [None](builtin-None) val

---

### _close
<span class="source-link">[[Source]](src/process/process_monitor.md#L576)</span>


Close all pipes wait for the child process to exit.


```pony
fun ref _close()
: None val
```

#### Returns

* [None](builtin-None) val

---

### _try_shutdown
<span class="source-link">[[Source]](src/process/process_monitor.md#L607)</span>


If neither stdout nor stderr are open we close down and exit.


```pony
fun ref _try_shutdown()
: None val
```

#### Returns

* [None](builtin-None) val

---

### _pending_reads
<span class="source-link">[[Source]](src/process/process_monitor.md#L618)</span>


Read from stdout while data is available. If we read 4 kb of data,
send ourself a resume message and stop reading, to avoid starving
other actors.
It's safe to use the same buffer for stdout and stderr because of
causal messaging. Events get processed one _after_ another.


```pony
fun ref _pending_reads(
  fd: U32 val)
: Bool val
```
#### Parameters

*   fd: [U32](builtin-U32) val

#### Returns

* [Bool](builtin-Bool) val

---

### _read_buf_size
<span class="source-link">[[Source]](src/process/process_monitor.md#L676)</span>


```pony
fun ref _read_buf_size()
: None val
```

#### Returns

* [None](builtin-None) val

---

### _write_final
<span class="source-link">[[Source]](src/process/process_monitor.md#L692)</span>


Write as much as possible to the fd. Return false if not
everything was written.


```pony
fun ref _write_final(
  data: (String val | Array[U8 val] val))
: Bool val
```
#### Parameters

*   data: ([String](builtin-String) val | [Array](builtin-Array)\[[U8](builtin-U8) val\] val)

#### Returns

* [Bool](builtin-Bool) val

---

### _pending_writes
<span class="source-link">[[Source]](src/process/process_monitor.md#L728)</span>


Send pending data. If any data can't be sent, keep it and mark fd as not
writeable. Once set to false the _stdin_writeable flag can only be cleared
here by processing the pending writes. If the _done_writing flag is set we
close the _stdin_write fd once we've processed pending writes.


```pony
fun ref _pending_writes()
: Bool val
```

#### Returns

* [Bool](builtin-Bool) val

---

