shared: add generic IPC barrier

The "Barrier" object is a simple inter-process barrier implementation. It
allows placing synchronization points and waiting for the other side to
reach it. Additionally, it has an abortion-mechanism as second-layer
synchronization to send abortion-events asynchronously to the other side.

The API is usually used to synchronize processes during fork(). However,
it can be extended to pass state through execve() so you could synchronize
beyond execve().

Usually, it's used like this (error-handling replaced by assert() for
simplicity):

    Barrier b;

    r = barrier_init(&b);
    assert_se(r >= 0);

    pid = fork();
    assert_se(pid >= 0);
    if (pid == 0) {
            barrier_set_role(&b, BARRIER_CHILD);

            ...do child post-setup...
            if (CHILD_SETUP_FAILED)
                       exit(1);
            ...child setup done...

            barrier_place(&b);
            if (!barrier_sync(&b)) {
                    /* parent setup failed */
                    exit(1);
            }

            barrier_destroy(&b); /* redundant as execve() and exit() imply this */

            /* parent & child setup successful */
            execve(...);
    }

    barrier_set_role(&b, BARRIER_PARENT);

    ...do parent post-setup...
    if (PARENT_SETUP_FAILED) {
            barrier_abort(&b);          /* send abortion event */
            barrier_wait_abortion(&b);  /* wait for child to abort (exit() implies abortion) */
            barrier_destroy(&b);
           ...bail out...
    }
    ...parent setup done...

    barrier_place(&b);
    if (!barrier_sync(&b)) {
            ...child setup failed... ;
            barrier_destroy(&b);
            ...bail out...
    }

    barrier_destroy(&b);

    ...child setup successfull...

This is the most basic API. Using barrier_place() to place barriers and
barrier_sync() to perform a full synchronization between both processes.
barrier_abort() places an abortion barrier which superceeds any other
barriers, exit() (or barrier_destroy()) places an abortion-barrier that
queues behind existing barriers (thus *not* replacing existing barriers
unlike barrier_abort()).

This example uses hard-synchronization with wait_abortion(), sync() and
friends. These are all optional. Barriers are highly dynamic and can be
used for one-way synchronization or even no synchronization at all
(postponing it for later). The sync() call performs a full two-way
synchronization.

The API is documented and should be fairly self-explanatory. A test-suite
shows some special semantics regarding abortion, wait_next() and exit().

Internally, barriers use two eventfds and a pipe. The pipe is used to
detect exit()s of the remote side as eventfds do not allow that. The
eventfds are used to place barriers, one for each side. Barriers itself
are numbered, but the numbers are reused once both sides reached the same
barrier, thus you cannot address barriers by the index. Moreover, the
numbering is implicit and we only store a counter. This makes the
implementation itself very lightweight, which is probably negligible
considering that we need 3 FDs for a barrier..

Last but not least: This barrier implementation is quite heavy. It's
definitely not meant for fast IPC synchronization. However, it's very easy
to use. And given the *HUGE* overhead of fork(), the barrier-overhead
should be negligible.
nspawn: use Barrier API instead of eventfd-util

The Barrier-API simplifies cross-fork() synchronization a lot. Replace the
hard-coded eventfd-util implementation and drop it.

Compared to the old API, Barriers also handle exit() of the remote side as
abortion. This way, segfaults will not cause the parent to deadlock.

EINTR handling is currently ignored for any barrier-waits. This can easily
be added, but it isn't needed so far so I dropped it. EINTR handling in
general is ugly, anyway. You need to deal with pselect/ppoll/... variants
and make sure not to unblock signals at the wrong times. So genrally,
there's little use in adding it.
shared: add PTY helper

This Pty API wraps the ugliness that is POSIX PTY. It takes care of:
  - edge-triggered HUP handling (avoid heavy CPU-usage on vhangup)
  - HUP vs. input-queue draining (handle HUP _after_ draining the whole
    input queue)
  - SIGCHLD vs. HUP (HUP is no reliable way to catch PTY deaths, always
    use SIGCHLD. Otherwise, vhangup() and friends will break.)
  - Output queue buffering (async EPOLLOUT handling)
  - synchronous setup (via Barrier API)

At the same time, the PTY API does not execve(). It simply fork()s and
leaves everything else to the caller. Usually, they execve() but we
support other setups, too.

This will be needed by multiple UI binaries (systemd-console, systemd-er,
...) so it's placed in src/shared/. It's not strictly related to
libsystemd-terminal, so it's not included there.
nspawn: fix barrier-destroy call

I dropped the cleanup-helper before pushing so use _cleanup_() directly.
ui/term: add line/cell/char handling for terminal pages

This commit introduces libsystemd-ui, a systemd-internal helper library
that will contain all the UI related functionality. It is going to be used
by systemd-welcomed, systemd-consoled, systemd-greeter and systemd-er.
Further use-cases may follow.

For now, this commit only adds terminal-page handling based on lines only.
Follow-up commits will add more functionality.