~ci-train-bot/lightdm/lightdm-ubuntu-zesty-1679

684 by Robert Ancell
Move vt code into it's own module
1
/*
2
 * Copyright (C) 2010-2011 Robert Ancell.
3
 * Author: Robert Ancell <robert.ancell@canonical.com>
2065 by Robert Ancell
Remove trailing whitespace
4
 *
684 by Robert Ancell
Move vt code into it's own module
5
 * This program is free software: you can redistribute it and/or modify it under
6
 * the terms of the GNU General Public License as published by the Free Software
7
 * Foundation, either version 3 of the License, or (at your option) any later
8
 * version. See http://www.gnu.org/copyleft/gpl.html the full text of the
9
 * license.
10
 */
11
12
#include <string.h>
13
#include <errno.h>
14
#include <unistd.h>
15
#include <glib/gstdio.h>
16
#include <sys/stat.h>
17
#include <fcntl.h>
18
#include <sys/ioctl.h>
19
#ifdef __linux__
20
#include <linux/vt.h>
21
#endif
22
23
#include "vt.h"
685 by Robert Ancell
Maintain own list of available VTs
24
#include "configuration.h"
25
26
static GList *used_vts = NULL;
684 by Robert Ancell
Move vt code into it's own module
27
687 by Robert Ancell
Make user switching work
28
static gint
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
29
open_tty (void)
687 by Robert Ancell
Make user switching work
30
{
747 by Robert Ancell
Only try and switch VTs when running as root
31
    int fd;
32
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
33
    fd = g_open ("/dev/tty0", O_RDONLY | O_NOCTTY, 0);
687 by Robert Ancell
Make user switching work
34
    if (fd < 0)
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
35
        g_warning ("Error opening /dev/tty0: %s", strerror (errno));
687 by Robert Ancell
Make user switching work
36
    return fd;
37
}
38
1798 by Michael Terry
If we aren't in a multi-seat environment, pass logind XDG_VTNR=0 instead of 1
39
gboolean
40
vt_can_multi_seat (void)
41
{
42
    /* Quick check to see if we can multi seat.  This is intentionally the
43
       same check logind does, just without actually reading from the files.
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
44
       Existence will prove whether we have CONFIG_VT built into the kernel. */
1798 by Michael Terry
If we aren't in a multi-seat environment, pass logind XDG_VTNR=0 instead of 1
45
    return access ("/dev/tty0", F_OK) == 0 &&
46
           access ("/sys/class/tty/tty0/active", F_OK) == 0;
47
}
48
684 by Robert Ancell
Move vt code into it's own module
49
gint
50
vt_get_active (void)
51
{
52
#ifdef __linux__
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
53
    gint tty_fd;
687 by Robert Ancell
Make user switching work
54
    gint active = -1;
684 by Robert Ancell
Move vt code into it's own module
55
786 by Robert Ancell
Add Plymouth tests
56
    /* Pretend always active */
57
    if (getuid () != 0)
58
        return 1;
59
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
60
    tty_fd = open_tty ();
61
    if (tty_fd >= 0)
684 by Robert Ancell
Move vt code into it's own module
62
    {
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
63
        struct vt_stat vt_state = { 0 };
64
        if (ioctl (tty_fd, VT_GETSTATE, &vt_state) < 0)
65
            g_warning ("Error using VT_GETSTATE on /dev/tty0: %s", strerror (errno));
687 by Robert Ancell
Make user switching work
66
        else
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
67
            active = vt_state.v_active;
68
        close (tty_fd);
684 by Robert Ancell
Move vt code into it's own module
69
    }
70
687 by Robert Ancell
Make user switching work
71
    return active;
684 by Robert Ancell
Move vt code into it's own module
72
#else
73
    return -1;
687 by Robert Ancell
Make user switching work
74
#endif
684 by Robert Ancell
Move vt code into it's own module
75
}
76
706 by Robert Ancell
Reorder vt.c
77
void
78
vt_set_active (gint number)
79
{
80
#ifdef __linux__
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
81
    gint tty_fd;
706 by Robert Ancell
Reorder vt.c
82
83
    g_debug ("Activating VT %d", number);
1213 by Robert Ancell
Fix whitespace
84
786 by Robert Ancell
Add Plymouth tests
85
    /* Pretend always active */
86
    if (getuid () != 0)
2065 by Robert Ancell
Remove trailing whitespace
87
        return;
706 by Robert Ancell
Reorder vt.c
88
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
89
    tty_fd = open_tty ();
90
    if (tty_fd >= 0)
706 by Robert Ancell
Reorder vt.c
91
    {
92
        int n = number;
1375 by Robert Ancell
Wait for the VT to become active when switching to avoid a suspected race condition somewhere between LightDM, X, ConsoleKit and the kernel
93
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
94
        if (ioctl (tty_fd, VT_ACTIVATE, n) < 0)
2406.1.1 by Michael Terry
Update vt ioctl usage
95
        {
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
96
            g_warning ("Error using VT_ACTIVATE %d on /dev/tty0: %s", n, strerror (errno));
2406.1.1 by Michael Terry
Update vt ioctl usage
97
            close (tty_fd);
98
            return;
99
        }
1375 by Robert Ancell
Wait for the VT to become active when switching to avoid a suspected race condition somewhere between LightDM, X, ConsoleKit and the kernel
100
101
        /* Wait for the VT to become active to avoid a suspected
102
         * race condition somewhere between LightDM, X, ConsoleKit and the kernel.
103
         * See https://bugs.launchpad.net/bugs/851612 */
2406.1.1 by Michael Terry
Update vt ioctl usage
104
        if (ioctl (tty_fd, VT_WAITACTIVE, n) < 0)
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
105
            g_warning ("Error using VT_WAITACTIVE %d on /dev/tty0: %s", n, strerror (errno));
1375 by Robert Ancell
Wait for the VT to become active when switching to avoid a suspected race condition somewhere between LightDM, X, ConsoleKit and the kernel
106
2297 by Robert Ancell
Use /dev/tty0 instead of /dev/console.
107
        close (tty_fd);
706 by Robert Ancell
Reorder vt.c
108
    }
109
#endif
110
}
111
685 by Robert Ancell
Maintain own list of available VTs
112
static gboolean
113
vt_is_used (gint number)
114
{
115
    GList *link;
116
117
    for (link = used_vts; link; link = link->next)
118
    {
119
        int n = GPOINTER_TO_INT (link->data);
120
        if (n == number)
121
            return TRUE;
122
    }
123
124
    return FALSE;
125
}
126
684 by Robert Ancell
Move vt code into it's own module
127
gint
705 by Yves-Alexis Perez
Don't replace Plymouth if it isn't running on a valid VT
128
vt_get_min (void)
684 by Robert Ancell
Move vt code into it's own module
129
{
685 by Robert Ancell
Maintain own list of available VTs
130
    gint number;
131
132
    number = config_get_integer (config_get_instance (), "LightDM", "minimum-vt");
133
    if (number < 1)
134
        number = 1;
135
705 by Yves-Alexis Perez
Don't replace Plymouth if it isn't running on a valid VT
136
    return number;
137
}
138
139
gint
140
vt_get_unused (void)
141
{
142
    gint number;
143
778 by Robert Ancell
Fix autologin
144
    if (getuid () != 0)
145
        return -1;
146
705 by Yves-Alexis Perez
Don't replace Plymouth if it isn't running on a valid VT
147
    number = vt_get_min ();
685 by Robert Ancell
Maintain own list of available VTs
148
    while (vt_is_used (number))
149
        number++;
2065 by Robert Ancell
Remove trailing whitespace
150
984 by Robert Ancell
Fix bug trying to reuse Plymouth VT on switch
151
    return number;
152
}
685 by Robert Ancell
Maintain own list of available VTs
153
984 by Robert Ancell
Fix bug trying to reuse Plymouth VT on switch
154
void
155
vt_ref (gint number)
156
{
974 by Robert Ancell
Fix VT releasing
157
    g_debug ("Using VT %d", number);
2065 by Robert Ancell
Remove trailing whitespace
158
    used_vts = g_list_append (used_vts, GINT_TO_POINTER (number));
684 by Robert Ancell
Move vt code into it's own module
159
}
160
161
void
984 by Robert Ancell
Fix bug trying to reuse Plymouth VT on switch
162
vt_unref (gint number)
684 by Robert Ancell
Move vt code into it's own module
163
{
974 by Robert Ancell
Fix VT releasing
164
    g_debug ("Releasing VT %d", number);
165
    used_vts = g_list_remove (used_vts, GINT_TO_POINTER (number));
684 by Robert Ancell
Move vt code into it's own module
166
}