uvtd: remove
authorDavid Herrmann <dh.herrmann@gmail.com>
Wed, 23 Oct 2013 13:15:50 +0000 (15:15 +0200)
committerDavid Herrmann <dh.herrmann@gmail.com>
Wed, 23 Oct 2013 13:15:50 +0000 (15:15 +0200)
Remove uvtd. The idea is outdated and not really needed. With recent
systemd-logind changes, all we need is a shim between legacy-programs
(like XServer) and logind. We can easily do that via libuvt without
requiring a huge daemon like uvtd.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
.gitignore
Makefile.am
configure.ac
src/uvtd_ctx.c [deleted file]
src/uvtd_ctx.h [deleted file]
src/uvtd_main.c [deleted file]
src/uvtd_seat.c [deleted file]
src/uvtd_seat.h [deleted file]
src/uvtd_vt.c [deleted file]
src/uvtd_vt.h [deleted file]

index e258ddb..0aa8fc4 100644 (file)
@@ -40,7 +40,6 @@ docs/reference/kmscon.????*
 docs/reference/*.stamp
 docs/reference/version.xml
 docs/reference/*/
-uvtd
 docs/man/*.1
 docs/man/*.3
 docs/man/*.5
index 7eddd69..70ff37f 100644 (file)
@@ -686,32 +686,6 @@ kmscon_LDADD += $(FUSE_LIBS)
 endif
 
 #
-# uvtd
-#
-
-if BUILD_ENABLE_UVTD
-bin_PROGRAMS += uvtd
-endif
-
-uvtd_SOURCES = \
-       src/uvtd_main.c \
-       src/uvtd_ctx.h \
-       src/uvtd_ctx.c \
-       src/uvtd_vt.h \
-       src/uvtd_vt.c \
-       src/uvtd_seat.h \
-       src/uvtd_seat.c
-uvtd_CPPFLAGS = \
-       $(AM_CPPFLAGS) \
-       $(XKBCOMMON_CFLAGS)
-uvtd_LDADD = \
-       $(XKBCOMMON_LIBS) \
-       libeloop.la \
-       libshl.la \
-       libuterm.la \
-       libuvt.la
-
-#
 # Tests
 #
 
index 393f52b..dd3d4d3 100644 (file)
@@ -197,18 +197,6 @@ elif test "x$enable_kmscon" = "x" ; then
 fi
 AC_MSG_RESULT([$enable_kmscon])
 
-# uvtd
-AC_MSG_CHECKING([whether user wants uvtd])
-AC_ARG_ENABLE([uvtd],
-              [AS_HELP_STRING([--enable-uvtd],
-                              [build uvtd])])
-if test "x$enable_all" = "xyes" ; then
-        enable_uvtd="yes"
-elif test "x$enable_uvtd" = "x" ; then
-        enable_uvtd="no (default)"
-fi
-AC_MSG_RESULT([$enable_uvtd])
-
 # debug
 AC_MSG_CHECKING([whether to build with debugging on])
 AC_ARG_ENABLE([debug],
@@ -821,30 +809,6 @@ else
         kmscon_missing="enable-kmscon"
 fi
 
-# uvtd
-uvtd_avail=no
-uvtd_missing=""
-if test ! "x$enable_uvtd" = "xno" ; then
-        uvtd_avail=yes
-        if test "x$uvt_avail" = "xno" ; then
-                uvtd_avail=no
-                uvtd_missing="$uvt_missing,$uvtd_missing"
-        fi
-
-        if test "x$eloop_avail" = "xno" ; then
-                uvtd_avail=no
-                uvtd_missing="$eloop_missing,$uvtd_missing"
-        fi
-
-        if test "x$uvtd_avail" = "xno" ; then
-                if test "x$enable_uvtd" = "xyes" ; then
-                        AC_ERROR([missing for uvtd: $uvtd_missing])
-                fi
-        fi
-else
-        uvtd_missing="enable-uvtd"
-fi
-
 #
 # Enable all required modules
 # We now know which modules can be built by checking the *_avail variables set
@@ -853,16 +817,6 @@ fi
 # needs them. This is done top-down of course.
 #
 
-# uvtd
-uvtd_enabled=no
-if test "x$uvtd_avail" = "xyes" ; then
-        if test "x${enable_uvtd% *}" = "xyes" ; then
-                uvtd_enabled=yes
-                enable_eloop=yes
-                enable_uvt=yes
-        fi
-fi
-
 # kmscon
 kmscon_enabled=no
 if test "x$kmscon_avail" = "xyes" ; then
@@ -1231,10 +1185,6 @@ AM_CONDITIONAL([BUILD_ENABLE_SESSION_CDEV],
 AM_CONDITIONAL([BUILD_ENABLE_KMSCON],
                [test "x$kmscon_enabled" = "xyes"])
 
-# uvtd
-AM_CONDITIONAL([BUILD_ENABLE_UVTD],
-               [test "x$uvtd_enabled" = "xyes"])
-
 #
 # Miscellaneous Checks
 # All checks below are independent of module checking or depend on the results
@@ -1318,7 +1268,6 @@ AC_MSG_NOTICE([Build configuration:
 
   Applications and Libraries:
                kmscon: $kmscon_enabled ($kmscon_avail: $kmscon_missing)
-                 uvtd: $uvtd_enabled ($uvtd_avail: $uvtd_missing)
                 uterm: $uterm_enabled ($uterm_avail: $uterm_missing)
                   tsm: $tsm_enabled ($tsm_avail: $tsm_missing)
                   uvt: $uvt_enabled ($uvt_avail: $uvt_missing)
diff --git a/src/uvtd_ctx.c b/src/uvtd_ctx.c
deleted file mode 100644 (file)
index 20a9220..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * uvtd - User-space VT daemon
- *
- * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Contexts
- * A context manages a single UVT seat. It creates the seat object, allocates
- * the VTs and provides all the bookkeeping for the sessions. It's the main
- * entry point after the seat selectors in uvtd-main.
- *
- * For each seat we create two different kinds of character-devices:
- *   /dev/ttyFC<seat>:
- *     This is the control-node. It's the preferred way to open new VTs. It
- *     provides a fully-backwards compatible VT API so legacy apps should be
- *     able to make use of it. Each open-file is associated to a different VT so
- *     you cannot share these easily, anymore. You need to pass the FD instead.
- *     This avoids problems with multiple users on the same VT that we had in
- *     the past.
- *   /dev/ttyFD<seat>/tty<num>:
- *     These are legacy VTs. They are put into a subdirectory and provide full
- *     backwards compatibility to real VTs. They are preallocated and there is
- *     only a limited number of them. You can control how many of these are
- *     allocated via the configuration options.
- *     These VTs can be shared between processes easily as all open-files on a
- *     single node share the same VT.
- * All character devices share the MAJOR number that is also used by real VTs.
- * However, the minor numbers use a relatively high offset (default: 2^14) so
- * they don't clash with real VTs.
- * If you need backwards-compatible symlinks, you can use the minor number of a
- * VT node in /dev/ttyFD<seat>/tty<num> and create a symlink:
- *   /dev/tty<minor> -> /dev/ttyFD<seat>/tty<num>
- * As the minors are globally unique, they won't clash with other tty nodes in
- * /dev. However, you loose the ability to see which seat a node is associated
- * to. So you normally look into /dev/ttyFD<seat>/, choose a node, look at the
- * minor and then open /dev/tty<minor> respectively.
- * This provides full backwards compatibility for applications that require
- * /dev/tty<num> paths (like old xservers).
- *
- * The VT logic is found in uvtd-vt subsystem. This file only provides the
- * character-device control nodes and links them to the right VTs.
- */
-
-#include <errno.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "eloop.h"
-#include "shl_dlist.h"
-#include "shl_log.h"
-#include "uvt.h"
-#include "uvtd_ctx.h"
-#include "uvtd_seat.h"
-#include "uvtd_vt.h"
-
-#define LOG_SUBSYSTEM "ctx"
-
-struct ctx_legacy {
-       struct shl_dlist list;
-       struct uvtd_ctx *ctx;
-       unsigned int minor;
-       unsigned int id;
-       struct uvt_cdev *cdev;
-       struct uvtd_vt *vt;
-};
-
-struct uvtd_ctx {
-       struct ev_eloop *eloop;
-       struct uvt_ctx *uctx;
-       struct uvtd_seat *seat;
-       char *seatname;
-
-       unsigned int main_cdev_minor;
-       struct uvt_cdev *main_cdev;
-
-       struct shl_dlist legacy_list;
-       unsigned int legacy_num;
-};
-
-static int ctx_legacy_init_vt(struct ctx_legacy *legacy);
-
-static void ctx_legacy_vt_event(void *vt, struct uvt_vt_event *ev, void *data)
-{
-       struct ctx_legacy *legacy = data;
-
-       switch (ev->type) {
-       case UVT_VT_TTY:
-               if (ev->tty.type != UVT_TTY_HUP)
-                       break;
-
-               /* fallthrough */
-       case UVT_VT_HUP:
-               log_debug("HUP on legacy VT %p", legacy);
-
-               uvtd_vt_unregister_cb(legacy->vt, ctx_legacy_vt_event, legacy);
-               uvtd_vt_unref(legacy->vt);
-               legacy->vt = NULL;
-               break;
-       }
-}
-
-static void ctx_legacy_cdev_event(struct uvt_cdev *cdev,
-                                 struct uvt_cdev_event *ev, void *data)
-{
-       struct ctx_legacy *legacy = data;
-       int ret;
-
-       switch (ev->type) {
-       case UVT_CDEV_HUP:
-               log_warning("HUP on legacy cdev %p", cdev);
-               uvt_cdev_unregister_cb(legacy->cdev, ctx_legacy_cdev_event,
-                                      legacy);
-               uvt_cdev_unref(legacy->cdev);
-               legacy->cdev = NULL;
-               break;
-       case UVT_CDEV_OPEN:
-               /* A legacy VT might get closed by the seat/session-scheduler at
-                * any time. We want to avoid respawning it right away to avoid
-                * error-throttling, so instead we respawn it when the next
-                * client opens the underlying cdev. */
-               if (!legacy->vt) {
-                       log_debug("reinitializing VT on legacy cdev %p",
-                                 legacy);
-                       ret = ctx_legacy_init_vt(legacy);
-                       if (ret) {
-                               log_warning("cannot reinitialize VT on legacy cdev %p",
-                                           legacy);
-                               uvt_client_kill(ev->client);
-                               break;
-                       }
-               }
-
-               ret = uvt_client_set_vt(ev->client, &uvtd_vt_ops, legacy->vt);
-               if (ret) {
-                       log_warning("cannot assign VT to new client: %d",
-                                   ret);
-                       uvt_client_kill(ev->client);
-               }
-               break;
-       }
-}
-
-static int ctx_legacy_init_vt(struct ctx_legacy *legacy)
-{
-       int ret;
-
-       ret = uvtd_vt_new(&legacy->vt, legacy->ctx->uctx, legacy->id,
-                         legacy->ctx->seat, true);
-       if (ret)
-               return ret;
-
-       ret = uvtd_vt_register_cb(legacy->vt, ctx_legacy_vt_event, legacy);
-       if (ret) {
-               uvtd_vt_unref(legacy->vt);
-               legacy->vt = NULL;
-               return ret;
-       }
-
-       return 0;
-}
-
-static int ctx_legacy_init_cdev(struct ctx_legacy *legacy)
-{
-       char *name;
-       int ret;
-
-       ret = asprintf(&name, "ttyFD%s!tty%u", legacy->ctx->seatname,
-                      legacy->minor);
-       if (ret <= 0)
-               return -ENOMEM;
-
-       ret = uvt_cdev_new(&legacy->cdev, legacy->ctx->uctx, name,
-                          uvt_ctx_get_major(legacy->ctx->uctx),
-                          legacy->minor);
-       free(name);
-
-       if (ret)
-               return ret;
-
-       ret = uvt_cdev_register_cb(legacy->cdev, ctx_legacy_cdev_event,
-                                  legacy);
-       if (ret) {
-               uvt_cdev_unref(legacy->cdev);
-               legacy->cdev = NULL;
-               return ret;
-       }
-
-       return 0;
-}
-
-static int ctx_legacy_init(struct uvtd_ctx *ctx, unsigned int id)
-{
-       struct ctx_legacy *legacy;
-       int ret;
-
-       legacy = malloc(sizeof(*legacy));
-       if (!legacy)
-               return -ENOMEM;
-
-       log_debug("new legacy cdev %p on ctx %p", legacy, ctx);
-
-       memset(legacy, 0, sizeof(*legacy));
-       legacy->id = id;
-       legacy->ctx = ctx;
-
-       ret = uvt_ctx_new_minor(ctx->uctx, &legacy->minor);
-       if (ret)
-               goto err_free;
-
-       ret = ctx_legacy_init_cdev(legacy);
-       if (ret)
-               goto err_minor;
-
-       ret = ctx_legacy_init_vt(legacy);
-       if (ret)
-               goto err_cdev;
-
-       shl_dlist_link(&ctx->legacy_list, &legacy->list);
-       return 0;
-
-err_cdev:
-       uvt_cdev_unregister_cb(legacy->cdev, ctx_legacy_cdev_event, legacy);
-       uvt_cdev_unref(legacy->cdev);
-err_minor:
-       uvt_ctx_free_minor(ctx->uctx, legacy->minor);
-err_free:
-       free(legacy);
-       return ret;
-}
-
-static void ctx_legacy_destroy(struct ctx_legacy *legacy)
-{
-       log_debug("free legacy cdev %p", legacy);
-
-       shl_dlist_unlink(&legacy->list);
-       uvtd_vt_unregister_cb(legacy->vt, ctx_legacy_vt_event, legacy);
-       uvtd_vt_unref(legacy->vt);
-       uvt_cdev_unregister_cb(legacy->cdev, ctx_legacy_cdev_event, legacy);
-       uvt_cdev_unref(legacy->cdev);
-       uvt_ctx_free_minor(legacy->ctx->uctx, legacy->minor);
-       free(legacy);
-}
-
-static void ctx_legacy_reconf(struct uvtd_ctx *ctx, unsigned int num)
-{
-       struct ctx_legacy *l;
-       struct shl_dlist *iter;
-       unsigned int i;
-       int ret;
-
-       /* If a legacy cdev received a HUP or some other error and got closed,
-        * we try to reinitialize it whenever the context is reconfigured. This
-        * avoids implementing any error-throttling while at the same time users
-        * can trigger a reinitialization with a reconfiguration.
-        * This doesn't touch running cdevs, but only HUP'ed cdevs. */
-       shl_dlist_for_each(iter, &ctx->legacy_list) {
-               l = shl_dlist_entry(iter, struct ctx_legacy, list);
-               if (l->cdev)
-                       continue;
-
-               log_debug("reinitialize legacy cdev %p", l);
-
-               ret = ctx_legacy_init_cdev(l);
-               if (ret)
-                       log_warning("cannot reinitialize legacy cdev %p: %d",
-                                   l, ret);
-       }
-
-       if (num == ctx->legacy_num)
-               return;
-
-       log_debug("changing #num of legacy cdevs on ctx %p from %u to %u",
-                 ctx, ctx->legacy_num, num);
-
-       if (num > ctx->legacy_num) {
-               for (i = ctx->legacy_num; i < num; ++i) {
-                       ret = ctx_legacy_init(ctx, i);
-                       if (ret)
-                               break;
-               }
-
-               ctx->legacy_num = i;
-       } else {
-               for (i = num; i < ctx->legacy_num; ++i) {
-                       l = shl_dlist_last(&ctx->legacy_list,
-                                          struct ctx_legacy, list);
-                       ctx_legacy_destroy(l);
-               }
-
-               ctx->legacy_num = num;
-       }
-}
-
-static void ctx_main_cdev_event(struct uvt_cdev *cdev,
-                               struct uvt_cdev_event *ev,
-                               void *data)
-{
-       struct uvtd_ctx *ctx = data;
-       struct uvtd_vt *vt;
-       int ret;
-
-       switch (ev->type) {
-       case UVT_CDEV_HUP:
-               log_warning("HUP on main cdev on ctx %p", ctx);
-               uvt_cdev_unregister_cb(ctx->main_cdev, ctx_main_cdev_event,
-                                      ctx);
-               uvt_cdev_unref(ctx->main_cdev);
-               ctx->main_cdev = NULL;
-               break;
-       case UVT_CDEV_OPEN:
-               ret = uvtd_vt_new(&vt, ctx->uctx, 0, ctx->seat, false);
-               if (ret)
-                       break;
-
-               uvt_client_set_vt(ev->client, &uvtd_vt_ops, vt);
-               uvtd_vt_unref(vt);
-               break;
-       }
-}
-
-static int ctx_init_cdev(struct uvtd_ctx *ctx)
-{
-       int ret;
-       char *name;
-
-       ret = asprintf(&name, "ttyFC%s", ctx->seatname);
-       if (ret <= 0)
-               return -ENOMEM;
-
-       ret = uvt_cdev_new(&ctx->main_cdev, ctx->uctx, name,
-                          uvt_ctx_get_major(ctx->uctx), ctx->main_cdev_minor);
-       free(name);
-
-       if (ret)
-               return ret;
-
-       ret = uvt_cdev_register_cb(ctx->main_cdev, ctx_main_cdev_event, ctx);
-       if (ret) {
-               uvt_cdev_unref(ctx->main_cdev);
-               ctx->main_cdev = NULL;
-               return ret;
-       }
-
-       return 0;
-}
-
-static bool has_real_vts(const char *seatname)
-{
-       return !strcmp(seatname, "seat0") &&
-              !access("/dev/tty0", F_OK);
-}
-
-int uvtd_ctx_new(struct uvtd_ctx **out, const char *seatname,
-                struct ev_eloop *eloop, struct uvt_ctx *uctx)
-{
-       struct uvtd_ctx *ctx;
-       int ret;
-
-       if (!out || !seatname || !eloop || !uctx)
-               return -EINVAL;
-
-       if (has_real_vts(seatname))
-               return -EEXIST;
-
-       ctx = malloc(sizeof(*ctx));
-       if (!ctx)
-               return -ENOMEM;
-
-       log_debug("new ctx %p on seat %s", ctx, seatname);
-
-       memset(ctx, 0, sizeof(*ctx));
-       ctx->eloop = eloop;
-       ctx->uctx = uctx;
-       shl_dlist_init(&ctx->legacy_list);
-
-       ctx->seatname = strdup(seatname);
-       if (!ctx->seatname) {
-               ret = -ENOMEM;
-               goto err_free;
-       }
-
-       ret = uvtd_seat_new(&ctx->seat, seatname, ctx->eloop, NULL, NULL);
-       if (ret)
-               goto err_name;
-
-       ret = uvt_ctx_new_minor(ctx->uctx, &ctx->main_cdev_minor);
-       if (ret)
-               goto err_seat;
-
-       ret = ctx_init_cdev(ctx);
-       if (ret)
-               goto err_minor;
-
-       ev_eloop_ref(ctx->eloop);
-       uvt_ctx_ref(ctx->uctx);
-       *out = ctx;
-
-       ctx_legacy_reconf(ctx, 8);
-
-       return 0;
-
-err_minor:
-       uvt_ctx_free_minor(ctx->uctx, ctx->main_cdev_minor);
-err_seat:
-       uvtd_seat_free(ctx->seat);
-err_name:
-       free(ctx->seatname);
-err_free:
-       free(ctx);
-       return ret;
-}
-
-void uvtd_ctx_free(struct uvtd_ctx *ctx)
-{
-       if (!ctx)
-               return;
-
-       log_debug("free ctx %p", ctx);
-
-       ctx_legacy_reconf(ctx, 0);
-       uvt_cdev_unregister_cb(ctx->main_cdev, ctx_main_cdev_event, ctx);
-       uvt_cdev_unref(ctx->main_cdev);
-       uvt_ctx_free_minor(ctx->uctx, ctx->main_cdev_minor);
-       uvtd_seat_free(ctx->seat);
-       free(ctx->seatname);
-       uvt_ctx_unref(ctx->uctx);
-       ev_eloop_unref(ctx->eloop);
-       free(ctx);
-}
-
-void uvtd_ctx_reconf(struct uvtd_ctx *ctx, unsigned int legacy_num)
-{
-       int ret;
-
-       if (!ctx)
-               return;
-
-       ctx_legacy_reconf(ctx, legacy_num);
-
-       /* Lets recreate the control node if it got busted during runtime. We do
-        * not recreate it right away after receiving a HUP signal to avoid
-        * trapping into the same error that caused the HUP.
-        * Instead we recreate the node on reconfiguration so users can control
-        * when to recreate them. */
-       if (!ctx->main_cdev) {
-               log_debug("recreating main cdev on ctx %p", ctx);
-               ret = ctx_init_cdev(ctx);
-               if (ret)
-                       log_warning("cannot recreate main cdev on ctx %p",
-                                   ctx);
-       }
-}
diff --git a/src/uvtd_ctx.h b/src/uvtd_ctx.h
deleted file mode 100644 (file)
index 78e3f0b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * uvtd - User-space VT daemon
- *
- * Copyright (c) 2013 David Herrmann <dh.herrmann@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Contexts
- * A context manages a single UVT seat. It creates the seat object, allocates
- * the VTs and provides all the bookkeeping for the sessions. It's the main
- * entry point after the seat selectors in uvtd-main.
- */
-
-#ifndef UVTD_CTX_H
-#define UVTD_CTX_H
-
-#include <stdlib.h>
-#include "eloop.h"
-#include "uvt.h"
-
-struct uvtd_ctx;
-
-int uvtd_ctx_new(struct uvtd_ctx **out, const char *seatname,
-                struct ev_eloop *eloop, struct uvt_ctx *uctx);
-void uvtd_ctx_free(struct uvtd_ctx *ctx);
-
-void uvtd_ctx_reconf(struct uvtd_ctx *ctx, unsigned int legacy_num);
-
-#endif /* UVTD_CTX_H */
diff --git a/src/uvtd_main.c b/src/uvtd_main.c
deleted file mode 100644 (file)
index d4b70ff..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * uvtd - User-space VT daemon
- *
- * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@googlemail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <errno.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/signalfd.h>
-#include "eloop.h"
-#include "shl_dlist.h"
-#include "shl_log.h"
-#include "uterm_input.h"
-#include "uterm_monitor.h"
-#include "uvt.h"
-#include "uvtd_ctx.h"
-
-struct app_seat {
-       struct shl_dlist list;
-       struct uvtd_app *app;
-       struct uterm_monitor_seat *useat;
-       struct uvtd_ctx *ctx;
-};
-
-struct uvtd_app {
-       struct ev_eloop *eloop;
-       struct uterm_monitor *mon;
-       struct uvt_ctx *ctx;
-       struct ev_fd *ctx_fd;
-       struct shl_dlist seats;
-};
-
-static int app_seat_new(struct uvtd_app *app, const char *sname,
-                       struct uterm_monitor_seat *useat)
-{
-       struct app_seat *seat;
-       int ret;
-
-       seat = malloc(sizeof(*seat));
-       if (!seat)
-               return -ENOMEM;
-
-       log_debug("new seat %p on %s", seat, sname);
-
-       memset(seat, 0, sizeof(*seat));
-       seat->app = app;
-       seat->useat = useat;
-
-       ret = uvtd_ctx_new(&seat->ctx, sname, app->eloop, app->ctx);
-       if (ret == -EEXIST) {
-               log_debug("ignoring seat %s as it has real VTs", sname);
-               goto err_free;
-       } else if (ret) {
-               goto err_free;
-       }
-
-       uterm_monitor_set_seat_data(seat->useat, seat);
-       shl_dlist_link(&app->seats, &seat->list);
-       return 0;
-
-err_free:
-       free(seat);
-       return ret;
-}
-
-static void app_seat_free(struct app_seat *seat)
-{
-       log_debug("free seat %p", seat);
-
-       shl_dlist_unlink(&seat->list);
-       uterm_monitor_set_seat_data(seat->useat, NULL);
-       uvtd_ctx_free(seat->ctx);
-       free(seat);
-}
-
-static void app_monitor_event(struct uterm_monitor *mon,
-                             struct uterm_monitor_event *ev,
-                             void *data)
-{
-       struct uvtd_app *app = data;
-       struct app_seat *seat;
-       int ret;
-
-       switch (ev->type) {
-       case UTERM_MONITOR_NEW_SEAT:
-               ret = app_seat_new(app, ev->seat_name, ev->seat);
-               if (ret)
-                       return;
-               break;
-       case UTERM_MONITOR_FREE_SEAT:
-               if (ev->seat_data)
-                       app_seat_free(ev->seat_data);
-               break;
-       case UTERM_MONITOR_NEW_DEV:
-               seat = ev->seat_data;
-               if (!seat)
-                       return;
-
-               switch (ev->dev_type) {
-               case UTERM_MONITOR_INPUT:
-                       log_debug("new input device %s on seat %p",
-                                 ev->dev_node, seat);
-                       break;
-               }
-               break;
-       case UTERM_MONITOR_FREE_DEV:
-               seat = ev->seat_data;
-               if (!seat)
-                       return;
-
-               switch (ev->dev_type) {
-               case UTERM_MONITOR_INPUT:
-                       log_debug("free input device %s on seat %p",
-                                 ev->dev_node, seat);
-                       break;
-               }
-               break;
-       }
-}
-
-static void app_sig_generic(struct ev_eloop *eloop,
-                           struct signalfd_siginfo *info,
-                           void *data)
-{
-       struct uvtd_app *app = data;
-
-       log_info("terminating due to caught signal %d", info->ssi_signo);
-       ev_eloop_exit(app->eloop);
-}
-
-static void app_sig_ignore(struct ev_eloop *eloop,
-                          struct signalfd_siginfo *info,
-                          void *data)
-{
-}
-
-static void app_ctx_event(struct ev_fd *fd, int mask, void *data)
-{
-       struct uvtd_app *app = data;
-
-       uvt_ctx_dispatch(app->ctx);
-
-       if (!(mask & EV_READABLE) && mask & (EV_HUP | EV_ERR)) {
-               log_error("HUP on UVT ctx fd");
-               ev_eloop_rm_fd(fd);
-               app->ctx_fd = NULL;
-       }
-}
-
-static void destroy_app(struct uvtd_app *app)
-{
-       ev_eloop_rm_fd(app->ctx_fd);
-       uvt_ctx_unref(app->ctx);
-       uterm_monitor_unref(app->mon);
-       ev_eloop_unregister_signal_cb(app->eloop, SIGPIPE, app_sig_ignore,
-                                     app);
-       ev_eloop_unregister_signal_cb(app->eloop, SIGINT, app_sig_generic,
-                                     app);
-       ev_eloop_unregister_signal_cb(app->eloop, SIGTERM, app_sig_generic,
-                                     app);
-       ev_eloop_unref(app->eloop);
-}
-
-static int setup_app(struct uvtd_app *app)
-{
-       int ret, fd;
-
-       shl_dlist_init(&app->seats);
-
-       ret = ev_eloop_new(&app->eloop, log_llog, NULL);
-       if (ret) {
-               log_error("cannot create eloop object: %d", ret);
-               goto err_app;
-       }
-
-       ret = ev_eloop_register_signal_cb(app->eloop, SIGTERM,
-                                         app_sig_generic, app);
-       if (ret) {
-               log_error("cannot register SIGTERM signal handler: %d", ret);
-               goto err_app;
-       }
-
-       ret = ev_eloop_register_signal_cb(app->eloop, SIGINT,
-                                         app_sig_generic, app);
-       if (ret) {
-               log_error("cannot register SIGINT signal handler: %d", ret);
-               goto err_app;
-       }
-
-       ret = ev_eloop_register_signal_cb(app->eloop, SIGPIPE,
-                                         app_sig_ignore, app);
-       if (ret) {
-               log_error("cannot register SIGPIPE signal handler: %d", ret);
-               goto err_app;
-       }
-
-       ret = uterm_monitor_new(&app->mon, app->eloop, app_monitor_event, app);
-       if (ret) {
-               log_error("cannot create device monitor: %d", ret);
-               goto err_app;
-       }
-
-       ret = uvt_ctx_new(&app->ctx, log_llog, NULL);
-       if (ret) {
-               log_error("cannot create UVT context: %d", ret);
-               goto err_app;
-       }
-
-       fd = uvt_ctx_get_fd(app->ctx);
-       if (fd >= 0) {
-               ret = ev_eloop_new_fd(app->eloop, &app->ctx_fd, fd,
-                                     EV_READABLE, app_ctx_event, app);
-               if (ret) {
-                       log_error("cannot create UVT ctx efd: %d", ret);
-                       goto err_app;
-               }
-       }
-
-       log_debug("scanning for devices...");
-       uterm_monitor_scan(app->mon);
-
-       return 0;
-
-err_app:
-       destroy_app(app);
-       return ret;
-}
-
-int main(int argc, char **argv)
-{
-       int ret;
-       struct uvtd_app app;
-
-       log_set_config(&LOG_CONFIG_INFO(1, 1));
-       log_print_init("uvtd");
-
-       memset(&app, 0, sizeof(app));
-
-       ret = setup_app(&app);
-       if (ret)
-               goto err_out;
-
-       ev_eloop_run(app.eloop, -1);
-
-       ret = 0;
-       destroy_app(&app);
-err_out:
-       if (ret)
-               log_err("cannot initialize uvtd, errno %d: %s",
-                       ret, strerror(-ret));
-       log_info("exiting");
-       return -ret;
-}
diff --git a/src/uvtd_seat.c b/src/uvtd_seat.c
deleted file mode 100644 (file)
index 0a1d71c..0000000
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * uvtd - User-space VT daemon
- *
- * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Seats
- * Each set of input+output devices form a single seat. Each seat is independent
- * of each other and there can be exactly one user per seat interacting with the
- * system.
- * Per seat, we have multiple sessions. But only one session can be active at a
- * time per seat. We allow external sessions, so session activation/deactivation
- * may be asynchronous.
- *
- * A seat object manages all the sessions for a single seat. As long as a seat
- * is asleep, no session is active. If you wake it up, the seat manager
- * automatically schedules a session. You can then request other sessions to be
- * scheduled and the seat manager will try to deactivate the current session and
- * reactivate the new session.
- *
- * Note that session deactivation may be asynchronous (unless forced). So some
- * calls might return -EINPROGRESS if the session-deactivation is pending. This
- * shouldn't bother the user as the session will notify back soon that the
- * deactivation was successfull. However, if it doesn't the user can chose to
- * perform any other action and we will retry the operation. As a last resort,
- * you can always kill the session by unregistering it or forcing a
- * deactivation.
- * "async_schedule" tracks the task that requested the deactivation of a
- * session. So when the session notifies us that it got deactivated, we know
- * what the user wanted and can perform the requested task now.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include "eloop.h"
-#include "shl_dlist.h"
-#include "shl_log.h"
-#include "uvtd_seat.h"
-
-#define LOG_SUBSYSTEM "seat"
-
-struct uvtd_session {
-       struct shl_dlist list;
-       unsigned long ref;
-       struct uvtd_seat *seat;
-       unsigned int id;
-
-       bool enabled;
-       bool deactivating;
-
-       uvtd_session_cb_t cb;
-       void *data;
-};
-
-/* task that requested the pending session-deactivation */
-enum uvtd_async_schedule {
-       SCHEDULE_NONE,                  /* default, causes a reschedule */
-       SCHEDULE_SWITCH,                /* causes a reschedule */
-       SCHEDULE_SLEEP,                 /* puts the seat asleep */
-       SCHEDULE_UNREGISTER,            /* unregisters the session */
-};
-
-struct uvtd_seat {
-       struct ev_eloop *eloop;
-       char *name;
-
-       size_t session_count;
-       struct shl_dlist sessions;
-
-       bool awake;
-       struct uvtd_session *current_sess;
-       struct uvtd_session *scheduled_sess;
-       struct uvtd_session *dummy_sess;
-
-       unsigned int async_schedule;
-
-       uvtd_seat_cb_t cb;
-       void *data;
-};
-
-static int session_call(struct uvtd_session *sess, unsigned int event)
-{
-       if (!sess->cb)
-               return 0;
-
-       return sess->cb(sess, event, sess->data);
-}
-
-static int session_call_activate(struct uvtd_session *sess)
-{
-       log_debug("activate session %p", sess);
-       return session_call(sess, UVTD_SESSION_ACTIVATE);
-}
-
-static int session_call_deactivate(struct uvtd_session *sess)
-{
-       log_debug("deactivate session %p", sess);
-       return session_call(sess, UVTD_SESSION_DEACTIVATE);
-}
-
-/* drop the current session as if it was successfully deactivated */
-static void seat_yield(struct uvtd_seat *seat)
-{
-       if (!seat->current_sess)
-               return;
-
-       seat->current_sess->deactivating = false;
-       seat->current_sess = NULL;
-       seat->async_schedule = SCHEDULE_NONE;
-}
-
-static int seat_go_asleep(struct uvtd_seat *seat, bool force)
-{
-       int ret = 0;
-
-       if (!seat->awake)
-               return 0;
-
-       if (seat->current_sess) {
-               ret = -EBUSY;
-               if (!force)
-                       return ret;
-
-               seat_yield(seat);
-       }
-
-       seat->awake = false;
-
-       if (seat->cb)
-               seat->cb(seat, UVTD_SEAT_SLEEP, seat->data);
-
-       return ret;
-}
-
-static void seat_go_awake(struct uvtd_seat *seat)
-{
-       if (seat->awake)
-               return;
-
-       seat->awake = true;
-}
-
-static int seat_run(struct uvtd_seat *seat)
-{
-       int ret;
-       struct uvtd_session *session;
-
-       if (!seat->awake)
-               return -EBUSY;
-       if (seat->current_sess)
-               return 0;
-
-       if (!seat->scheduled_sess) {
-               log_debug("no session scheduled to run (num: %zu)",
-                         seat->session_count);
-               return -ENOENT;
-       }
-       session = seat->scheduled_sess;
-
-       /* TODO: unregister session and try next on failure */
-       ret = session_call_activate(session);
-       if (ret) {
-               log_warning("cannot activate session %p: %d", session, ret);
-               return ret;
-       }
-
-       seat->current_sess = session;
-
-       return 0;
-}
-
-static int seat_pause(struct uvtd_seat *seat, bool force, unsigned int async)
-{
-       int ret;
-
-       if (!seat->current_sess)
-               return 0;
-
-       /* TODO: pass \force to the session */
-       seat->current_sess->deactivating = true;
-       ret = session_call_deactivate(seat->current_sess);
-       if (ret) {
-               if (!force && ret == -EINPROGRESS) {
-                       seat->async_schedule = async;
-                       log_debug("pending deactivation for session %p",
-                                 seat->current_sess);
-               } else {
-                       log_warning("cannot deactivate session %p (%d): %d",
-                                   seat->current_sess, force, ret);
-               }
-
-               if (!force)
-                       return ret;
-       }
-
-       seat_yield(seat);
-       return ret;
-}
-
-static void seat_reschedule(struct uvtd_seat *seat)
-{
-       struct shl_dlist *iter, *start;
-       struct uvtd_session *sess;
-
-       if (seat->scheduled_sess && seat->scheduled_sess->enabled)
-               return;
-
-       if (seat->current_sess && seat->current_sess->enabled) {
-               seat->scheduled_sess = seat->current_sess;
-               return;
-       }
-
-       if (seat->current_sess)
-               start = &seat->current_sess->list;
-       else
-               start = &seat->sessions;
-
-       shl_dlist_for_each_but_one(iter, start, &seat->sessions) {
-               sess = shl_dlist_entry(iter, struct uvtd_session, list);
-
-               if (sess != seat->dummy_sess && sess->enabled) {
-                       seat->scheduled_sess = sess;
-                       return;
-               }
-       }
-
-       if (seat->dummy_sess && seat->dummy_sess->enabled)
-               seat->scheduled_sess = seat->dummy_sess;
-       else
-               seat->scheduled_sess = NULL;
-}
-
-static bool seat_has_schedule(struct uvtd_seat *seat)
-{
-       return seat->scheduled_sess &&
-              seat->scheduled_sess != seat->current_sess;
-}
-
-static int seat_switch(struct uvtd_seat *seat)
-{
-       int ret;
-
-       ret = seat_pause(seat, false, SCHEDULE_SWITCH);
-       if (ret)
-               return ret;
-
-       return seat_run(seat);
-}
-
-static void seat_schedule(struct uvtd_seat *seat, struct uvtd_session *sess)
-{
-       seat->scheduled_sess = sess;
-       seat_reschedule(seat);
-       if (seat_has_schedule(seat))
-               seat_switch(seat);
-}
-
-static void seat_next(struct uvtd_seat *seat, bool reverse)
-{
-       struct shl_dlist *cur, *iter;
-       struct uvtd_session *s, *next;
-
-       if (seat->current_sess)
-               cur = &seat->current_sess->list;
-       else if (seat->session_count)
-               cur = &seat->sessions;
-       else
-               return;
-
-       next = NULL;
-       if (!seat->current_sess && seat->dummy_sess &&
-           seat->dummy_sess->enabled)
-               next = seat->dummy_sess;
-
-       if (reverse) {
-               shl_dlist_for_each_reverse_but_one(iter, cur,
-                                                  &seat->sessions) {
-                       s = shl_dlist_entry(iter, struct uvtd_session, list);
-
-                       if (s->enabled && seat->dummy_sess != s) {
-                               next = s;
-                               break;
-                       }
-               }
-       } else {
-               shl_dlist_for_each_but_one(iter, cur, &seat->sessions) {
-                       s = shl_dlist_entry(iter, struct uvtd_session, list);
-
-                       if (s->enabled && seat->dummy_sess != s) {
-                               next = s;
-                               break;
-                       }
-               }
-       }
-
-       if (!next)
-               return;
-
-       seat_schedule(seat, next);
-}
-
-int uvtd_seat_new(struct uvtd_seat **out, const char *seatname,
-                 struct ev_eloop *eloop, uvtd_seat_cb_t cb, void *data)
-{
-       struct uvtd_seat *seat;
-       int ret;
-
-       if (!out || !eloop || !seatname)
-               return -EINVAL;
-
-       seat = malloc(sizeof(*seat));
-       if (!seat)
-               return -ENOMEM;
-       memset(seat, 0, sizeof(*seat));
-       seat->eloop = eloop;
-       seat->cb = cb;
-       seat->data = data;
-       shl_dlist_init(&seat->sessions);
-
-       seat->name = strdup(seatname);
-       if (!seat->name) {
-               ret = -ENOMEM;
-               goto err_free;
-       }
-
-       ev_eloop_ref(seat->eloop);
-       *out = seat;
-       return 0;
-
-err_free:
-       free(seat);
-       return ret;
-}
-
-void uvtd_seat_free(struct uvtd_seat *seat)
-{
-       struct uvtd_session *s;
-       int ret;
-
-       if (!seat)
-               return;
-
-       ret = seat_pause(seat, true, SCHEDULE_NONE);
-       if (ret)
-               log_warning("destroying seat %s while session %p is active",
-                           seat->name, seat->current_sess);
-
-       ret = seat_go_asleep(seat, true);
-       if (ret)
-               log_warning("destroying seat %s while still awake: %d",
-                           seat->name, ret);
-
-       while (!shl_dlist_empty(&seat->sessions)) {
-               s = shl_dlist_entry(seat->sessions.next, struct uvtd_session,
-                                   list);
-               uvtd_session_unregister(s);
-       }
-
-       free(seat->name);
-       ev_eloop_unref(seat->eloop);
-       free(seat);
-}
-
-const char *uvtd_seat_get_name(struct uvtd_seat *seat)
-{
-       return seat ? seat->name : NULL;
-}
-
-struct ev_eloop *uvtd_seat_get_eloop(struct uvtd_seat *seat)
-{
-       return seat ? seat->eloop : NULL;
-}
-
-int uvtd_seat_sleep(struct uvtd_seat *seat, bool force)
-{
-       int ret, err = 0;
-
-       if (!seat)
-               return -EINVAL;
-
-       ret = seat_pause(seat, force, SCHEDULE_SLEEP);
-       if (ret) {
-               if (force)
-                       err = ret;
-               else
-                       return ret;
-       }
-
-       ret = seat_go_asleep(seat, force);
-       if (ret) {
-               if (force)
-                       err = ret;
-               else
-                       return ret;
-       }
-
-       return err;
-}
-
-void uvtd_seat_wake_up(struct uvtd_seat *seat)
-{
-       if (!seat)
-               return;
-
-       seat_go_awake(seat);
-       seat_run(seat);
-}
-
-void uvtd_seat_schedule(struct uvtd_seat *seat, unsigned int id)
-{
-       struct shl_dlist *iter;
-       struct uvtd_session *session;
-       unsigned int i;
-
-       if (!seat || !id)
-               return;
-
-       session = NULL;
-       i = id;
-       shl_dlist_for_each(iter, &seat->sessions) {
-               session = shl_dlist_entry(iter, struct uvtd_session, list);
-               if (!--i)
-                       break;
-               if (session->id >= id)
-                       break;
-       }
-
-       if (session)
-               seat_schedule(seat, session);
-}
-
-int uvtd_seat_register_session(struct uvtd_seat *seat,
-                              struct uvtd_session **out,
-                              unsigned int id, uvtd_session_cb_t cb,
-                              void *data)
-{
-       struct uvtd_session *sess, *s;
-       struct shl_dlist *iter;
-
-       if (!seat || !out)
-               return -EINVAL;
-
-       sess = malloc(sizeof(*sess));
-       if (!sess)
-               return -ENOMEM;
-
-       log_debug("register session %p with id %u on seat %p",
-                 sess, id, seat);
-
-       memset(sess, 0, sizeof(*sess));
-       sess->ref = 1;
-       sess->seat = seat;
-       sess->cb = cb;
-       sess->data = data;
-       sess->id = id;
-
-       ++seat->session_count;
-       *out = sess;
-
-       if (sess->id) {
-               shl_dlist_for_each(iter, &seat->sessions) {
-                       s = shl_dlist_entry(iter, struct uvtd_session, list);
-                       if (!s->id || s->id > sess->id) {
-                               shl_dlist_link_tail(iter, &sess->list);
-                               return 0;
-                       }
-
-                       if (s->id == sess->id)
-                               log_warning("session %p shadowed by %p",
-                                           sess, s);
-               }
-       }
-
-       shl_dlist_link_tail(&seat->sessions, &sess->list);
-       return 0;
-}
-
-void uvtd_session_ref(struct uvtd_session *sess)
-{
-       if (!sess || !sess->ref)
-               return;
-
-       ++sess->ref;
-}
-
-void uvtd_session_unref(struct uvtd_session *sess)
-{
-       if (!sess || !sess->ref || --sess->ref)
-               return;
-
-       uvtd_session_unregister(sess);
-       free(sess);
-}
-
-void uvtd_session_unregister(struct uvtd_session *sess)
-{
-       struct uvtd_seat *seat;
-       int ret;
-       bool forced = false;
-
-       if (!sess || !sess->seat)
-               return;
-
-       log_debug("unregister session %p", sess);
-
-       seat = sess->seat;
-       sess->enabled = false;
-       if (seat->dummy_sess == sess)
-               seat->dummy_sess = NULL;
-       seat_reschedule(seat);
-
-       if (seat->current_sess == sess) {
-               ret = seat_pause(seat, true, SCHEDULE_NONE);
-               if (ret) {
-                       forced = true;
-                       log_warning("unregistering active session %p; skipping automatic session-switch",
-                                   sess);
-               }
-       }
-
-       shl_dlist_unlink(&sess->list);
-       --seat->session_count;
-       sess->seat = NULL;
-
-       session_call(sess, UVTD_SESSION_UNREGISTER);
-       uvtd_session_unref(sess);
-
-       /* If this session was active and we couldn't deactivate it, then it
-        * might still have resources allocated that couldn't get freed. In this
-        * case we should not automatically switch to the next session as it is
-        * very likely that it will not be able to start.
-        * Instead, we stay inactive and wait for user/external input to switch
-        * to another session. This delay will then hopefully be long enough so
-        * all resources got freed. */
-       if (!forced)
-               seat_run(seat);
-}
-
-bool uvtd_session_is_registered(struct uvtd_session *sess)
-{
-       return sess && sess->seat;
-}
-
-bool uvtd_session_is_active(struct uvtd_session *sess)
-{
-       return sess && sess->seat && sess->seat->current_sess == sess;
-}
-
-void uvtd_session_schedule(struct uvtd_session *sess)
-{
-       if (!sess || !sess->seat)
-               return;
-
-       seat_schedule(sess->seat, sess);
-}
-
-void uvtd_session_enable(struct uvtd_session *sess)
-{
-       if (!sess || sess->enabled)
-               return;
-
-       log_debug("enable session %p", sess);
-       sess->enabled = true;
-
-       if (sess->seat &&
-           (!sess->seat->current_sess ||
-            sess->seat->current_sess == sess->seat->dummy_sess))
-               seat_schedule(sess->seat, sess);
-}
-
-void uvtd_session_disable(struct uvtd_session *sess)
-{
-       if (!sess || !sess->enabled)
-               return;
-
-       log_debug("disable session %p", sess);
-       sess->enabled = false;
-}
-
-bool uvtd_session_is_enabled(struct uvtd_session *sess)
-{
-       return sess && sess->enabled;
-}
-
-void uvtd_session_notify_deactivated(struct uvtd_session *sess)
-{
-       struct uvtd_seat *seat;
-       unsigned int sched;
-
-       if (!sess || !sess->seat)
-               return;
-
-       seat = sess->seat;
-       if (seat->current_sess != sess)
-               return;
-
-       sched = seat->async_schedule;
-       log_debug("session %p notified core about deactivation (schedule: %u)",
-                 sess, sched);
-       seat_yield(seat);
-       seat_reschedule(seat);
-
-       if (sched == SCHEDULE_SLEEP)
-               seat_go_asleep(seat, false);
-       else if (sched == SCHEDULE_UNREGISTER)
-               uvtd_session_unregister(sess);
-       else
-               seat_run(seat);
-}
diff --git a/src/uvtd_seat.h b/src/uvtd_seat.h
deleted file mode 100644 (file)
index 534d773..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * uvtd - User-space VT daemon
- *
- * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Seats
- * Each set of input+output devices form a single seat. Each seat is independent
- * of each other and there can be exactly one user per seat interacting with the
- * system.
- * Per seat, we have multiple sessions. But only one session can be active at a
- * time per seat. We allow external sessions, so session activation/deactivation
- * may be asynchronous.
- */
-
-#ifndef UVTD_SEAT_H
-#define UVTD_SEAT_H
-
-#include <stdlib.h>
-#include "eloop.h"
-
-/* sessions */
-
-struct uvtd_session;
-
-enum uvtd_session_event_type {
-       UVTD_SESSION_ACTIVATE,
-       UVTD_SESSION_DEACTIVATE,
-       UVTD_SESSION_UNREGISTER,
-};
-
-typedef int (*uvtd_session_cb_t) (struct uvtd_session *session,
-                                 unsigned int event,
-                                 void *data);
-
-void uvtd_session_ref(struct uvtd_session *sess);
-void uvtd_session_unref(struct uvtd_session *sess);
-void uvtd_session_unregister(struct uvtd_session *sess);
-bool uvtd_session_is_registered(struct uvtd_session *sess);
-
-bool uvtd_session_is_active(struct uvtd_session *sess);
-void uvtd_session_schedule(struct uvtd_session *sess);
-
-void uvtd_session_enable(struct uvtd_session *sess);
-void uvtd_session_disable(struct uvtd_session *sess);
-bool uvtd_session_is_enabled(struct uvtd_session *sess);
-
-void uvtd_session_notify_deactivated(struct uvtd_session *sess);
-
-/* seats */
-
-struct uvtd_seat;
-
-enum uvtd_seat_event {
-       UVTD_SEAT_SLEEP,
-};
-
-typedef void (*uvtd_seat_cb_t) (struct uvtd_seat *seat, unsigned int event,
-                               void *data);
-
-int uvtd_seat_new(struct uvtd_seat **out, const char *seatname,
-                 struct ev_eloop *eloop, uvtd_seat_cb_t cb, void *data);
-void uvtd_seat_free(struct uvtd_seat *seat);
-
-const char *uvtd_seat_get_name(struct uvtd_seat *seat);
-struct ev_eloop *uvtd_seat_get_eloop(struct uvtd_seat *seat);
-int uvtd_seat_sleep(struct uvtd_seat *seat, bool force);
-void uvtd_seat_wake_up(struct uvtd_seat *seat);
-void uvtd_seat_schedule(struct uvtd_seat *seat, unsigned int id);
-
-int uvtd_seat_register_session(struct uvtd_seat *seat,
-                              struct uvtd_session **out,
-                              unsigned int id, uvtd_session_cb_t cb,
-                              void *data);
-
-#endif /* UVTD_SEAT_H */
diff --git a/src/uvtd_vt.c b/src/uvtd_vt.c
deleted file mode 100644 (file)
index 50eac8e..0000000
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * uvtd - User-space VT daemon
- *
- * Copyright (c) 2012-2013 David Herrmann <dh.herrmann@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Virtual Terminals
- * Every virtual terminal forms a session inside of uvtd. Sessions are scheduled
- * by the seat/session-scheduler and notified whenever they get active/inactive.
- */
-
-#include <errno.h>
-#include <inttypes.h>
-#include <linux/kd.h>
-#include <linux/vt.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termio.h>
-#include <termios.h>
-#include <unistd.h>
-#include "shl_hook.h"
-#include "shl_log.h"
-#include "uvt.h"
-#include "uvtd_seat.h"
-#include "uvtd_vt.h"
-
-#define LOG_SUBSYSTEM "vt"
-
-struct uvtd_vt {
-       unsigned long ref;
-       struct uvt_ctx *uctx;
-       struct shl_hook *hook;
-       struct uvtd_session *session;
-       struct uvtd_seat *seat;
-       bool is_legacy;
-
-       unsigned int mode;
-       unsigned int kbmode;
-       struct vt_mode vtmode;
-       pid_t vtpid;
-};
-
-static void vt_hup(struct uvtd_vt *vt)
-{
-       struct uvt_vt_event ev;
-
-       memset(&ev, 0, sizeof(ev));
-       ev.type = UVT_VT_HUP;
-
-       shl_hook_call(vt->hook, vt, &ev);
-}
-
-static int vt_session_event(struct uvtd_session *session, unsigned int event,
-                           void *data)
-{
-       struct uvtd_vt *vt = data;
-
-       switch (event) {
-       case UVTD_SESSION_UNREGISTER:
-               vt->session = NULL;
-               vt->seat = NULL;
-               vt_hup(vt);
-               break;
-       case UVTD_SESSION_ACTIVATE:
-               log_debug("activate %p", vt);
-               break;
-       case UVTD_SESSION_DEACTIVATE:
-               log_debug("deactivate %p", vt);
-               break;
-       }
-
-       return 0;
-}
-
-int uvtd_vt_new(struct uvtd_vt **out, struct uvt_ctx *uctx, unsigned int id,
-               struct uvtd_seat *seat, bool is_legacy)
-{
-       struct uvtd_vt *vt;
-       int ret;
-
-       if (!out || !uctx)
-               return -EINVAL;
-
-       vt = malloc(sizeof(*vt));
-       if (!vt)
-               return -ENOMEM;
-
-       memset(vt, 0, sizeof(*vt));
-       vt->ref = 1;
-       vt->uctx = uctx;
-       vt->seat = seat;
-       vt->is_legacy = is_legacy;
-       vt->mode = KD_TEXT;
-       vt->kbmode = K_UNICODE;
-       vt->vtmode.mode = VT_AUTO;
-
-       ret = shl_hook_new(&vt->hook);
-       if (ret)
-               goto err_free;
-
-       ret = uvtd_seat_register_session(seat, &vt->session, id,
-                                        vt_session_event, vt);
-       if (ret)
-               goto err_hook;
-
-       uvt_ctx_ref(vt->uctx);
-       *out = vt;
-       return 0;
-
-err_hook:
-       shl_hook_free(vt->hook);
-err_free:
-       free(vt);
-       return ret;
-}
-
-void uvtd_vt_ref(struct uvtd_vt *vt)
-{
-       if (!vt || !vt->ref)
-               return;
-
-       ++vt->ref;
-}
-
-void uvtd_vt_unref(struct uvtd_vt *vt)
-{
-       if (!vt || !vt->ref || --vt->ref)
-               return;
-
-       uvtd_session_unregister(vt->session);
-       shl_hook_free(vt->hook);
-       uvt_ctx_unref(vt->uctx);
-       free(vt);
-}
-
-int uvtd_vt_register_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data)
-{
-       if (!vt)
-               return -EINVAL;
-
-       return shl_hook_add_cast(vt->hook, cb, data, false);
-}
-
-void uvtd_vt_unregister_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data)
-{
-       if (!vt)
-               return;
-
-       shl_hook_rm_cast(vt->hook, cb, data);
-}
-
-int uvtd_vt_read(struct uvtd_vt *vt, uint8_t *mem, size_t len)
-{
-       if (!vt || !vt->seat)
-               return -ENODEV;
-
-       return -EAGAIN;
-}
-
-int uvtd_vt_write(struct uvtd_vt *vt, const uint8_t *mem, size_t len)
-{
-       if (!vt || !vt->seat)
-               return -ENODEV;
-
-       return len;
-}
-
-unsigned int uvtd_vt_poll(struct uvtd_vt *vt)
-{
-       if (!vt || !vt->seat)
-               return UVT_TTY_HUP | UVT_TTY_READ | UVT_TTY_WRITE;
-
-       return UVT_TTY_WRITE;
-}
-
-static int vt_ioctl_TCFLSH(void *data, unsigned long arg)
-{
-       switch (arg) {
-       case TCIFLUSH:
-       case TCOFLUSH:
-       case TCIOFLUSH:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int vt_ioctl_VT_ACTIVATE(void *data, unsigned long arg)
-{
-       struct uvtd_vt *vt = data;
-
-       if (!vt->seat)
-               return -ENODEV;
-
-       return -EINVAL;
-}
-
-static int vt_ioctl_VT_WAITACTIVE(void *data, unsigned long arg)
-{
-       struct uvtd_vt *vt = data;
-
-       if (!vt->seat)
-               return -ENODEV;
-
-       return -EINVAL;
-}
-
-static int vt_ioctl_VT_GETSTATE(void *data, struct vt_stat *arg)
-{
-       struct uvtd_vt *vt = data;
-
-       if (!vt->seat)
-               return -ENODEV;
-
-       return -EINVAL;
-}
-
-static int vt_ioctl_VT_OPENQRY(void *data, unsigned int *arg)
-{
-       struct uvtd_vt *vt = data;
-
-       if (!vt->seat)
-               return -ENODEV;
-
-       return -EINVAL;
-}
-
-static int vt_ioctl_VT_GETMODE(void *data, struct vt_mode *arg)
-{
-       struct uvtd_vt *vt = data;
-
-       memcpy(arg, &vt->vtmode, sizeof(*arg));
-       return 0;
-}
-
-static int vt_ioctl_VT_SETMODE(void *data, const struct vt_mode *arg,
-                              pid_t pid)
-{
-       struct uvtd_vt *vt = data;
-
-       /* TODO: implement waitv logic (hang on write if not active) */
-       if (arg->waitv)
-               return -EOPNOTSUPP;
-
-       if (arg->frsig)
-               return -EINVAL;
-       if (arg->relsig > SIGRTMAX || arg->relsig < 0)
-               return -EINVAL;
-       if (arg->acqsig > SIGRTMAX || arg->acqsig < 0)
-               return -EINVAL;
-
-       switch (arg->mode) {
-       case VT_AUTO:
-               if (arg->acqsig || arg->relsig)
-                       return -EINVAL;
-               vt->vtpid = 0;
-               break;
-       case VT_PROCESS:
-               vt->vtpid = pid;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       memcpy(&vt->vtmode, arg, sizeof(*arg));
-       return 0;
-}
-
-static int vt_ioctl_VT_RELDISP(void *data, unsigned long arg)
-{
-       struct uvtd_vt *vt = data;
-
-       if (!vt->seat)
-               return -ENODEV;
-
-       return -EINVAL;
-}
-
-static int vt_ioctl_KDGETMODE(void *data, unsigned int *arg)
-{
-       struct uvtd_vt *vt = data;
-
-       *arg = vt->mode;
-       return 0;
-}
-
-static int vt_ioctl_KDSETMODE(void *data, unsigned int arg)
-{
-       struct uvtd_vt *vt = data;
-
-       switch (arg) {
-       case KD_TEXT0:
-       case KD_TEXT1:
-               arg = KD_TEXT;
-               /* fallthrough */
-       case KD_TEXT:
-       case KD_GRAPHICS:
-               vt->mode = arg;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int vt_ioctl_KDGKBMODE(void *data, unsigned int *arg)
-{
-       struct uvtd_vt *vt = data;
-
-       *arg = vt->kbmode;
-       return 0;
-}
-
-static int vt_ioctl_KDSKBMODE(void *data, unsigned int arg)
-{
-       struct uvtd_vt *vt = data;
-
-       switch (arg) {
-       case K_RAW:
-               /* TODO: what does K_RAW do? */
-       case K_UNICODE:
-       case K_OFF:
-               vt->kbmode = arg;
-               break;
-       case K_XLATE:
-       case K_MEDIUMRAW:
-               /* TODO: do we need these? */
-               return -EOPNOTSUPP;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/* compatibility to UVT-VT ops */
-
-static void vt_ref(void *vt)
-{
-       uvtd_vt_ref(vt);
-}
-
-static void vt_unref(void *vt)
-{
-       uvtd_vt_unref(vt);
-}
-
-static int vt_register_cb(void *vt, uvt_vt_cb cb, void *data)
-{
-       return uvtd_vt_register_cb(vt, cb, data);
-}
-
-static void vt_unregister_cb(void *vt, uvt_vt_cb cb, void *data)
-{
-       uvtd_vt_register_cb(vt, cb, data);
-}
-
-static int vt_read(void *vt, uint8_t *mem, size_t len)
-{
-       return uvtd_vt_read(vt, mem, len);
-}
-
-static int vt_write(void *vt, const uint8_t *mem, size_t len)
-{
-       return uvtd_vt_write(vt, mem, len);
-}
-
-static unsigned int vt_poll(void *vt)
-{
-       return uvtd_vt_poll(vt);
-}
-
-struct uvt_vt_ops uvtd_vt_ops = {
-       .ref = vt_ref,
-       .unref = vt_unref,
-       .register_cb = vt_register_cb,
-       .unregister_cb = vt_unregister_cb,
-       .read = vt_read,
-       .write = vt_write,
-       .poll = vt_poll,
-
-       .ioctl_TCFLSH = vt_ioctl_TCFLSH,
-
-       .ioctl_VT_ACTIVATE = vt_ioctl_VT_ACTIVATE,
-       .ioctl_VT_WAITACTIVE = vt_ioctl_VT_WAITACTIVE,
-       .ioctl_VT_GETSTATE = vt_ioctl_VT_GETSTATE,
-       .ioctl_VT_OPENQRY = vt_ioctl_VT_OPENQRY,
-       .ioctl_VT_GETMODE = vt_ioctl_VT_GETMODE,
-       .ioctl_VT_SETMODE = vt_ioctl_VT_SETMODE,
-       .ioctl_VT_RELDISP = vt_ioctl_VT_RELDISP,
-       .ioctl_KDGETMODE = vt_ioctl_KDGETMODE,
-       .ioctl_KDSETMODE = vt_ioctl_KDSETMODE,
-       .ioctl_KDGKBMODE = vt_ioctl_KDGKBMODE,
-       .ioctl_KDSKBMODE = vt_ioctl_KDSKBMODE,
-};
diff --git a/src/uvtd_vt.h b/src/uvtd_vt.h
deleted file mode 100644 (file)
index fe83671..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * uvtd - User-space VT daemon
- *
- * Copyright (c) 2013 David Herrmann <dh.herrmann@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Virtual Terminals
- * Every virtual terminal forms a session inside of uvtd. Sessions are scheduled
- * by the seat/session-scheduler and notified whenever they get active/inactive.
- */
-
-#ifndef UVTD_VT_H
-#define UVTD_VT_H
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include "uvt.h"
-
-struct uvtd_vt;
-extern struct uvt_vt_ops uvtd_vt_ops;
-
-int uvtd_vt_new(struct uvtd_vt **out, struct uvt_ctx *uctx, unsigned int id,
-               struct uvtd_seat *seat, bool is_legacy);
-void uvtd_vt_ref(struct uvtd_vt *vt);
-void uvtd_vt_unref(struct uvtd_vt *vt);
-
-int uvtd_vt_register_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data);
-void uvtd_vt_unregister_cb(struct uvtd_vt *vt, uvt_vt_cb cb, void *data);
-
-int uvtd_vt_read(struct uvtd_vt *vt, uint8_t *mem, size_t len);
-int uvtd_vt_write(struct uvtd_vt *vt, const uint8_t *mem, size_t len);
-unsigned int uvtd_vt_poll(struct uvtd_vt *vt);
-
-#endif /* UVTD_VT_H */