common: Add cockpit_pipe_spawn() function to create process pipe

This is more general than cockpit_pipe_transport_spawn(). Once we
migrate to libssh then cockpit_pipe_transpown_spawn() should be
rewritten to use cockpit_pipe_spawn().

Since we'd like to use this as a cockpit_pipe_transport_spawn()
constructor, allow passing the gtype. In theory we would make all
these arguments be constructor arguments of CockpitPipe and then
pass it all in that way. But man that's tiring and less readable.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
common: Close failed CockpitPipe in right thread context

CockpitPipe is not thread-safe, so it's close-on-fail-during-init
idle handler needs to be called in the thread main context for
the thread in which it was created.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
common: Add cockpit_pipe_get_pid() function

We're needing to check on the pid, and whether a pipe has a pid
in a few places. So make this a real function instead of forcing
use of g_object_get (pipe, "pid", ...);

In addition guarantee that cockpit_pipe_get_pid() will still return
the pid after 'close' has fired.

Also add some testing infrastructure to test-pipe. This will be
used further in later commits.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
common: Rename CockpitPipe 'closed' signal to 'close'

It was conflicting with CockpitTransport's 'closed' signal and
CockpitPipeTransport ended up with both overlapping.

The 'close' name matches the other method and signal names in
CockpitPipe better as well.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
common: Split exit status handling out of CockpitPipe

The exit status handling in CockpitPipe was very specific to
the launch code in cockpit_pipe_transport_spawn(). Move this
logic into CockpitPipeTransport instead.

We want to use CockpitPipe for arbitrary processes and need
clean exit code handling.

Add cockpit_pipe_exit_status() function for retrieving the
exit status of the reaped child process.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
agent: Add cockpit_channel_get_bool_option() function

And implement it using cockpit_json_get_bool() which does the usual
checks for the correct member type.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
common: Tweak test output a bit

For more visibility in CI. Also remove unnecessary init
from test-pipe.c

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
agent: Implement text-stream channel with spawn argument

This launches a process and connects the channel to the standard
input and standard output of the spawned process. Standard error
goes to the same output as the agent's unless redirected.

The command is not passed to the shell, it should be a full
executable path.

The doc/protocol.md documentation has some details on how
to call this.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
common: Properly handle case where pipe closing both in/out

When pipe is asked to close output, but not a socket and the
input file descriptor is equal to the output fd, then we have
to close both. This means we stop reading input as well.

Previously this case would cause a critical warning and reading
from an invalid file descriptor.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
cockpit: Implement cockpit_pipe_pty() function

This opens up a pipe with a pty provided by forkpty() and lets
us communicate with that pty.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
agent: Implement pty option for CockpitTextStream

This lets us open a pty by specifying 'pty': true in the channel
options.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
web: Implement a proper terminal on rescue terminal page

Use a proper terminal from term.js on the terminal page.

Fixes #434
Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
web: Resize terminal DIV to contents

This is a simple fix to resize terminal DIV to the contents. It
helps mouse coordinate detection in term.js work correctly. We
probably should resize the black area behind, but this isn't done
here yet.

Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
test: Update check-terminal.

Closes #472
agent: Add cockpit_channel_get_generator() function

Returns a cached generator from the channel, which can be shared by
both implementations and the channel itself for efficiency.
agent: Add the cockpit_channel_close_option() function

This adds an string option to the close message for the channel.
It must be called before the channel close message is sent.
agent: Add the cockpit_channel_close_int_option() function

This adds an integer option to the close message for the channel.
It must be called before the channel close message is sent.
web: Expose channel close options in Channel.on("close")

Instead of having a reason argument to the event, there's now the
full options, so handlers can access any field of the close message.
This is symettrical with the Channel(@options) constructor.

In addition accept @options instead of a @reason in Channel.close()
agent: Send exit-status and exit-signal in text-stream

If a text-stream is a spawn type text-stream then send the
exit-status and/or exit-signal in the close options.
web: Implement $cockpit.spawn() method

This creates a deferred jQuery object on which you can listen for
output from a process, send data to the proces, etc...

Internally uses the text-stream channel with a "spawn" open
option.

Documentation in spawn.js