[pkg-fso-commits] [SCM] Automatic Display Manager branch, bug540201, updated. debian/0.6-1-43-g57ac67b
Enrico Zini
enrico at enricozini.org
Wed Jul 6 11:01:00 UTC 2011
The following commit has been merged in the bug540201 branch:
commit 57ac67b7bb9e3effcf0cab7ab23e541bf30bfe01
Author: Enrico Zini <enrico at enricozini.org>
Date: Wed Jul 6 13:00:56 2011 +0200
Cleaned up VT allocation code
diff --git a/Makefile.am b/Makefile.am
index a59bba1..84016ef 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,9 +6,9 @@ ACLOCAL_AMFLAGS = -I m4
sbin_PROGRAMS = nodm
-dist_noinst_HEADERS = common.h dm.h log.h test.h xserver.h xsession.h xsession-child.h
+dist_noinst_HEADERS = common.h dm.h log.h test.h vt.h xserver.h xsession.h xsession-child.h
-libsources = common.c log.c xsession-child.c xserver.c xsession.c dm.c
+libsources = common.c log.c vt.c xsession-child.c xserver.c xsession.c dm.c
testlibsources = $(libsources) test.c
AM_CPPFLAGS = $(X11_CFLAGS)
diff --git a/common.c b/common.c
index 656af4b..897f90c 100644
--- a/common.c
+++ b/common.c
@@ -20,6 +20,13 @@
#include "common.h"
#include <stdlib.h>
+#include <string.h>
+
+const char* basename (const char* str)
+{
+ const char *cp = strrchr (str, '/');
+ return cp ? cp + 1 : str;
+}
const char* getenv_with_default(const char* envname, const char* def)
{
diff --git a/common.h b/common.h
index 63f791a..fad3de6 100644
--- a/common.h
+++ b/common.h
@@ -38,11 +38,15 @@
#define E_PAM_ERROR 201 ///< something wrong talking with PAM
#define E_OS_ERROR 202 ///< something wrong talking with the Operating System
#define E_XLIB_ERROR 203 ///< Xlib error
+#define E_VT_ALLOC_ERROR 204 ///< VT allocation error
#define E_X_SERVER_DIED 210 ///< Server died
#define E_X_SERVER_TIMEOUT 211 ///< Server not ready before timeout
#define E_X_SERVER_CONNECT 212 ///< Could not connect to X server
#define E_SESSION_DIED 220 ///< X session died
+/// Return the basename of a path, as a pointer inside \a str
+const char* basename (const char* str);
+
/**
* Like getenv, but if the variable is not defined it returns \a def
*/
diff --git a/dm.c b/dm.c
index 54e6a36..0c25874 100644
--- a/dm.c
+++ b/dm.c
@@ -1,5 +1,5 @@
/*
- * session - nodm X display manager
+ * dm - nodm X display manager
*
* Copyright 2011 Enrico Zini <enrico at enricozini.org>
*
@@ -27,12 +27,14 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
+#include <stdio.h>
void nodm_display_manager_init(struct nodm_display_manager* dm)
{
- nodm_xserver_init(&(dm->srv));
- nodm_xsession_init(&(dm->session));
+ nodm_xserver_init(&dm->srv);
+ nodm_xsession_init(&dm->session);
+ nodm_vt_init(&dm->vt);
dm->_srv_split_args = NULL;
dm->_srv_split_argv = NULL;
}
@@ -57,7 +59,21 @@ void nodm_display_manager_cleanup(struct nodm_display_manager* dm)
int nodm_display_manager_start(struct nodm_display_manager* dm)
{
- int res = nodm_xserver_start(&dm->srv);
+ int res = nodm_vt_start(&dm->vt);
+ if (res != E_SUCCESS) return res;
+
+ if (dm->vt.num != -1)
+ {
+ // Create the vtN argument
+ snprintf(dm->_vtarg, sizeof(dm->_vtarg), "vt%d", dm->vt.num);
+ // Append it to srv args
+ const char** s = dm->srv.argv;
+ while (*s) ++s;
+ *s++ = dm->_vtarg;
+ *s = NULL;
+ }
+
+ res = nodm_xserver_start(&dm->srv);
if (res != E_SUCCESS) return res;
res = nodm_xsession_start(&dm->session, &dm->srv);
@@ -74,10 +90,12 @@ int nodm_display_manager_stop(struct nodm_display_manager* dm)
res = nodm_xserver_stop(&dm->srv);
if (res != E_SUCCESS) return res;
+ nodm_vt_stop(&dm->vt);
+
return E_SUCCESS;
}
-int nodm_display_manager_wait(struct nodm_display_manager* dm)
+int nodm_display_manager_wait(struct nodm_display_manager* dm, int* session_status)
{
while (true)
{
@@ -103,7 +121,8 @@ int nodm_display_manager_wait(struct nodm_display_manager* dm)
} else if (child == dm->session.pid) {
// Session died
log_warn("X session died with status %d", status);
- return status;
+ *session_status = status;
+ return E_SESSION_DIED;
}
}
}
@@ -128,7 +147,9 @@ int nodm_display_manager_parse_xcmdline(struct nodm_display_manager* s, const ch
unsigned in_arg = 0;
unsigned argc = 0;
- char **argv = (char**)malloc((toks->we_wordc + 3) * sizeof(char*));
+ // +1 for the X server pathname, +1 for the display name,
+ // +1 for the VT number, +1 for the trailing NULL
+ char **argv = (char**)malloc((toks->we_wordc + 4) * sizeof(char*));
if (argv == NULL)
{
return_code = E_OS_ERROR;
@@ -159,7 +180,13 @@ int nodm_display_manager_parse_xcmdline(struct nodm_display_manager* s, const ch
// Copy other args
while (in_arg < toks->we_wordc)
+ {
+ int vtn;
+ if (sscanf(toks->we_wordv[in_arg], "vt%d", &vtn) == 1)
+ // if vtN has been provided by the caller, disable VT allocation
+ s->vt.conf_initial_vt = -1;
argv[argc++] = toks->we_wordv[in_arg++];
+ }
argv[argc] = NULL;
s->srv.argv = (const char**)argv;
diff --git a/dm.h b/dm.h
index 04deaa7..e10d504 100644
--- a/dm.h
+++ b/dm.h
@@ -1,5 +1,5 @@
/*
- * session - nodm X display manager
+ * dm - nodm X display manager
*
* Copyright 2011 Enrico Zini <enrico at enricozini.org>
*
@@ -23,6 +23,7 @@
#include "xserver.h"
#include "xsession.h"
+#include "vt.h"
struct nodm_display_manager
{
@@ -32,10 +33,15 @@ struct nodm_display_manager
/// X session supervision
struct nodm_xsession session;
+ /// VT allocation
+ struct nodm_vt vt;
/// Storage for split server arguments used by nodm_x_cmdline_split
char** _srv_split_argv;
void* _srv_split_args;
+
+ /// Storage for vtN argument from dynamic VT allocation
+ char _vtarg[10];
};
/// Initialise a display_manager structure with default values
@@ -48,7 +54,9 @@ void nodm_display_manager_cleanup(struct nodm_display_manager* dm);
int nodm_display_manager_start(struct nodm_display_manager* dm);
/// Wait for X or the X session to end
-int nodm_display_manager_wait(struct nodm_display_manager* dm);
+int nodm_display_manager_wait(struct nodm_display_manager* dm, int* session_status);
+
+// TODO: int nodm_display_manager_restart(struct nodm_display_manager* dm);
/// Stop X and the X session
int nodm_display_manager_stop(struct nodm_display_manager* dm);
diff --git a/nodm.c b/nodm.c
index 46f61d8..9b95a3e 100644
--- a/nodm.c
+++ b/nodm.c
@@ -1,49 +1,22 @@
/*
- * Copyright 1989 - 1994, Julianne Frances Haugh
- * Copyright 2009, Enrico Zini
- * All rights reserved.
+ * nodm - nodm X display manager
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
+ * Copyright 2009--2011 Enrico Zini <enrico at enricozini.org>
*
- * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-/* Some parts substantially derived from an ancestor of: */
-/* su for GNU. Run a shell with substitute user and group IDs.
- Copyright (C) 1992-2003 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define NAME "nodm"
@@ -63,105 +36,15 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/wait.h>
-#include <sys/ioctl.h>
#include <time.h>
#include <unistd.h>
-#include <fcntl.h>
-#include <sys/vt.h>
#define _(...) (__VA_ARGS__)
-/*
- * Assorted #defines to control su's behavior
- */
-/*
- * Global variables
- */
-
/* Program name used in error messages */
-static char *Prog;
-
-/*
- * External identifiers
- */
-
-extern char **newenvp;
-extern char **environ;
-extern size_t newenvc;
-
-/* local function prototypes */
-
-static char *Basename (char *str)
-{
- char *cp = strrchr (str, '/');
-
- return cp ? cp + 1 : str;
-}
-
-
-static int try_vtstate(const char* dev, struct vt_stat* vtstat)
-{
- int res = 0;
- int fd = open(dev, O_WRONLY | O_NOCTTY, 0);
- if (fd < 0)
- goto cleanup;
- if (ioctl (fd, VT_GETSTATE, vtstat) < 0)
- goto cleanup;
- res = 1;
-
-cleanup:
- if (fd >= 0) close(fd);
- return res;
-}
-
-static int get_vtstate(struct vt_stat* vtstat)
-{
- if (try_vtstate("/dev/tty", vtstat)) return 1;
- if (try_vtstate("/dev/tty0", vtstat)) return 1;
- if (try_vtstate("/dev/console", vtstat)) return 1;
- return 0;
-}
-
-/*
- * Allocate a new vt, open it and return the file descriptor and the vt number.
- *
- * Searching the vt starts at the initial value of vtnum.
- */
-int open_vt(int *vtnum)
-{
- char vtname[15];
- int res = -1;
- struct vt_stat vtstat;
- unsigned short vtmask;
-
- if (!get_vtstate(&vtstat))
- {
- fprintf (stderr, _("%s: cannot find or open the console\n"), Prog);
- goto cleanup;
- }
-
- for (vtmask = 1 << *vtnum; vtstat.v_state & vtmask; ++*vtnum, vtmask <<= 1)
- ;
- if (!vtmask) {
- fprintf (stderr, _("%s: all VTs seem to be busy\n"), Prog);
- goto cleanup;
- }
-
- snprintf(vtname, 15, "/dev/tty%d", *vtnum);
-
- res = open(vtname, O_RDWR | O_NOCTTY, 0);
- if (res < 0) {
- fprintf (stderr, _("%s: cannot open %s: %m\n"), Prog, vtname);
- goto cleanup;
- }
-
-cleanup:
- return res;
-}
+static const char *Prog;
/*
* Run the X session
@@ -273,11 +156,8 @@ static int nodm_monitor(int argc, char **argv)
};
const char* opt_session = NODM_SESSION;
char xoptions[BUFSIZ];
- char xoptions1[BUFSIZ];
char* cp;
int mst;
- int vt_fd = -1;
- int vt_num;
/* Parse command line options */
while (1)
@@ -315,31 +195,13 @@ static int nodm_monitor(int argc, char **argv)
log_info("starting nodm monitor");
- {
- char startvt[BUFSIZ];
- string_from_env(startvt, "NODM_FIRST_VT", "7");
- vt_num = strtoul(startvt, NULL, 10);
- }
- if ((vt_fd = open_vt(&vt_num)) == -1)
- {
- fprintf (stderr, _("%s: cannot allocate a virtual terminal\n"), Prog);
- return 1;
- }
-
/* Read the configuration from the environment */
cp = getenv("NODM_MIN_SESSION_TIME");
mst = cp ? atoi(cp) : 60;
string_from_env(xoptions, "NODM_X_OPTIONS", "");
- if (xoptions[0] == 0)
- snprintf(xoptions1, BUFSIZ, "vt%d", vt_num);
- else
- snprintf(xoptions1, BUFSIZ, "vt%d %s", vt_num, xoptions);
-
setenv("NODM_RUN_SESSION", "1", 1);
- run_and_restart(opt_session, xoptions1, mst);
-
- close(vt_fd);
+ run_and_restart(opt_session, xoptions, mst);
return 0;
}
@@ -359,7 +221,7 @@ int main (int argc, char **argv)
* Get the program name. The program name is used as a prefix to
* most error messages.
*/
- Prog = Basename (argv[0]);
+ Prog = basename(argv[0]);
// TODO: move these after command line parsing, so we can implement
// --verbose --no-syslog --no-stderr and the like
diff --git a/test-internals.c b/test-internals.c
index 1ddadb5..59a3c26 100644
--- a/test-internals.c
+++ b/test-internals.c
@@ -44,6 +44,7 @@ int main(int argc, char* argv[])
ensure_equals(s.srv.argv[1], ":0");
ensure_equals(s.srv.argv[2], NULL);
ensure_equals(s.srv.name, ":0");
+ ensure_equali(s.vt.conf_initial_vt, 7);
nodm_display_manager_cleanup(&s);
nodm_display_manager_init(&s);
@@ -53,6 +54,7 @@ int main(int argc, char* argv[])
ensure_equals(s.srv.argv[2], "foo");
ensure_equals(s.srv.argv[3], NULL);
ensure_equals(s.srv.name, ":0");
+ ensure_equali(s.vt.conf_initial_vt, 7);
nodm_display_manager_cleanup(&s);
nodm_display_manager_init(&s);
@@ -61,6 +63,7 @@ int main(int argc, char* argv[])
ensure_equals(s.srv.argv[1], ":0");
ensure_equals(s.srv.argv[2], NULL);
ensure_equals(s.srv.name, ":0");
+ ensure_equali(s.vt.conf_initial_vt, 7);
nodm_display_manager_cleanup(&s);
nodm_display_manager_init(&s);
@@ -69,6 +72,7 @@ int main(int argc, char* argv[])
ensure_equals(s.srv.argv[1], ":1");
ensure_equals(s.srv.argv[2], NULL);
ensure_equals(s.srv.name, ":1");
+ ensure_equali(s.vt.conf_initial_vt, 7);
nodm_display_manager_cleanup(&s);
nodm_display_manager_init(&s);
@@ -77,6 +81,7 @@ int main(int argc, char* argv[])
ensure_equals(s.srv.argv[1], ":1");
ensure_equals(s.srv.argv[2], NULL);
ensure_equals(s.srv.name, ":1");
+ ensure_equali(s.vt.conf_initial_vt, 7);
nodm_display_manager_cleanup(&s);
nodm_display_manager_init(&s);
@@ -86,6 +91,7 @@ int main(int argc, char* argv[])
ensure_equals(s.srv.argv[2], "foo");
ensure_equals(s.srv.argv[3], NULL);
ensure_equals(s.srv.name, ":0");
+ ensure_equali(s.vt.conf_initial_vt, 7);
nodm_display_manager_cleanup(&s);
nodm_display_manager_init(&s);
@@ -95,6 +101,7 @@ int main(int argc, char* argv[])
ensure_equals(s.srv.argv[2], "foo");
ensure_equals(s.srv.argv[3], NULL);
ensure_equals(s.srv.name, ":1");
+ ensure_equali(s.vt.conf_initial_vt, 7);
nodm_display_manager_cleanup(&s);
nodm_display_manager_init(&s);
@@ -104,6 +111,28 @@ int main(int argc, char* argv[])
ensure_equals(s.srv.argv[2], "foo");
ensure_equals(s.srv.argv[3], NULL);
ensure_equals(s.srv.name, ":1");
+ ensure_equali(s.vt.conf_initial_vt, 7);
+ nodm_display_manager_cleanup(&s);
+
+ nodm_display_manager_init(&s);
+ nodm_display_manager_parse_xcmdline(&s, "vt2");
+ ensure_equals(s.srv.argv[0], "/usr/bin/X");
+ ensure_equals(s.srv.argv[1], ":0");
+ ensure_equals(s.srv.argv[2], "vt2");
+ ensure_equals(s.srv.argv[3], NULL);
+ ensure_equals(s.srv.name, ":0");
+ ensure_equali(s.vt.conf_initial_vt, -1);
+ nodm_display_manager_cleanup(&s);
+
+ nodm_display_manager_init(&s);
+ nodm_display_manager_parse_xcmdline(&s, "/usr/bin/Xnest :1 vt42 foo");
+ ensure_equals(s.srv.argv[0], "/usr/bin/Xnest");
+ ensure_equals(s.srv.argv[1], ":1");
+ ensure_equals(s.srv.argv[2], "vt42");
+ ensure_equals(s.srv.argv[3], "foo");
+ ensure_equals(s.srv.argv[4], NULL);
+ ensure_equals(s.srv.name, ":1");
+ ensure_equali(s.vt.conf_initial_vt, -1);
nodm_display_manager_cleanup(&s);
test_ok();
diff --git a/test-xsession.c b/test-xsession.c
index 41eae06..149814f 100644
--- a/test-xsession.c
+++ b/test-xsession.c
@@ -61,9 +61,12 @@ void test_trivial_session()
dm.session.conf_use_pam = false;
dm.session.conf_cleanup_xse = false;
dm.session.conf_run_as[0] = 0;
+ dm.vt.conf_initial_vt = -1;
dm.session.child_body = test_session;
ensure_succeeds(nodm_display_manager_start(&dm));
- ensure_succeeds(nodm_display_manager_wait(&dm));
+ int sstatus;
+ ensure_succeeds(nodm_display_manager_wait(&dm, &sstatus));
+ ensure_equali(sstatus, E_SUCCESS);
ensure_succeeds(nodm_display_manager_stop(&dm));
nodm_display_manager_cleanup(&dm);
}
@@ -77,6 +80,7 @@ void test_bad_x_server()
dm.session.conf_use_pam = false;
dm.session.conf_cleanup_xse = false;
dm.session.conf_run_as[0] = 0;
+ dm.vt.conf_initial_vt = -1;
dm.session.child_body = test_session;
ensure_equali(nodm_display_manager_start(&dm), E_X_SERVER_DIED);
@@ -101,10 +105,13 @@ void test_failing_x_session()
dm.session.conf_use_pam = false;
dm.session.conf_cleanup_xse = false;
dm.session.conf_run_as[0] = 0;
+ dm.vt.conf_initial_vt = -1;
dm.session.child_body = test_session_bad;
ensure_succeeds(nodm_display_manager_start(&dm));
- ensure_succeeds(nodm_display_manager_wait(&dm));
+ int sstatus;
+ ensure_succeeds(nodm_display_manager_wait(&dm, &sstatus));
+ ensure_equali(sstatus, E_SUCCESS);
ensure_succeeds(nodm_display_manager_stop(&dm));
nodm_display_manager_cleanup(&dm);
}
@@ -118,10 +125,13 @@ void test_dying_x_server()
dm.session.conf_use_pam = false;
dm.session.conf_cleanup_xse = false;
dm.session.conf_run_as[0] = 0;
+ dm.vt.conf_initial_vt = -1;
dm.session.child_body = test_session_x_killer;
ensure_succeeds(nodm_display_manager_start(&dm));
- ensure_succeeds(nodm_display_manager_wait(&dm));
+ int sstatus;
+ ensure_succeeds(nodm_display_manager_wait(&dm, &sstatus));
+ ensure_equali(sstatus, E_SUCCESS);
ensure_succeeds(nodm_display_manager_stop(&dm));
nodm_display_manager_cleanup(&dm);
}
diff --git a/vt.c b/vt.c
new file mode 100644
index 0000000..b82f201
--- /dev/null
+++ b/vt.c
@@ -0,0 +1,116 @@
+/*
+ * vt - VT allocation
+ *
+ * Copyright 2009--2011 Enrico Zini <enrico at enricozini.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "vt.h"
+#include "common.h"
+#include "log.h"
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/vt.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/**
+ * Issue a VT_GETSTATE ioctl on the given device, if it supports it.
+ *
+ * @return true if it succeeded, false otherwise
+ */
+static bool try_vtstate(const char* dev, struct vt_stat* vtstat)
+{
+ bool res = false;
+ int fd = open(dev, O_WRONLY | O_NOCTTY, 0);
+ if (fd < 0)
+ goto cleanup;
+ if (ioctl (fd, VT_GETSTATE, vtstat) < 0)
+ goto cleanup;
+ res = true;
+
+cleanup:
+ if (fd >= 0) close(fd);
+ return res;
+}
+
+// Find a device that supports the VT_GETSTATE ioctl
+static bool get_vtstate(struct vt_stat* vtstat)
+{
+ if (try_vtstate("/dev/tty", vtstat)) return true;
+ if (try_vtstate("/dev/tty0", vtstat)) return true;
+ if (try_vtstate("/dev/console", vtstat)) return true;
+ return false;
+}
+
+void nodm_vt_init(struct nodm_vt* vt)
+{
+ vt->conf_initial_vt = strtol(getenv_with_default("NODM_FIRST_VT", "7"), NULL, 10);
+ vt->fd = -1;
+ vt->num = -1;
+}
+
+int nodm_vt_start(struct nodm_vt* vt)
+{
+ if (vt->conf_initial_vt == -1)
+ return E_SUCCESS;
+
+ int vtnum = vt->conf_initial_vt;
+
+ struct vt_stat vtstat;
+ if (!get_vtstate(&vtstat))
+ {
+ log_err("cannot find or open the console");
+ return E_VT_ALLOC_ERROR;
+ }
+
+ unsigned short vtmask;
+ for (vtmask = 1 << vtnum; vtstat.v_state & vtmask; ++vtnum, vtmask <<= 1)
+ ;
+ if (!vtmask)
+ {
+ log_err("all VTs seem to be busy");
+ return E_VT_ALLOC_ERROR;
+ }
+
+ char vtname[15];
+ snprintf(vtname, 15, "/dev/tty%d", vtnum);
+
+ vt->fd = open(vtname, O_RDWR | O_NOCTTY, 0);
+ if (vt->fd < 0)
+ {
+ log_err("cannot open %s: %m", vtname);
+ return E_OS_ERROR;
+ }
+
+ vt->num = vtnum;
+
+ return E_SUCCESS;
+}
+
+void nodm_vt_stop(struct nodm_vt* vt)
+{
+ if (vt->fd != -1)
+ {
+ close(vt->fd);
+ vt->fd = -1;
+ vt->num = -1;
+ }
+}
diff --git a/vt.h b/vt.h
new file mode 100644
index 0000000..a397274
--- /dev/null
+++ b/vt.h
@@ -0,0 +1,48 @@
+/*
+ * vt - VT allocation
+ *
+ * Copyright 2009--2011 Enrico Zini <enrico at enricozini.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef NODM_VT_H
+#define NODM_VT_H
+
+/// VT allocation state
+struct nodm_vt
+{
+ /**
+ * First VT to try to allocate. -1 means 'no VT allocation'
+ */
+ int conf_initial_vt;
+
+ /// Number of the VT that has been allocated (-1 for none)
+ int num;
+
+ /// File decriptor pointing to the open VT (-1 for none)
+ int fd;
+};
+
+/// Initialise a vt structure with default values
+void nodm_vt_init(struct nodm_vt* vt);
+
+/// Allocate a virtual terminal and keep it open
+int nodm_vt_start(struct nodm_vt* vt);
+
+/// Release the virtual terminal
+void nodm_vt_stop(struct nodm_vt* vt);
+
+#endif
diff --git a/xsession-child.c b/xsession-child.c
index f5ef518..b472e43 100644
--- a/xsession-child.c
+++ b/xsession-child.c
@@ -1,7 +1,7 @@
/*
* xsession-child - child side of X session
*
- * Copyright 2011 Enrico Zini <enrico at enricozini.org>
+ * Copyright 2009--2011 Enrico Zini <enrico at enricozini.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,6 +17,53 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+/*
+ * Some parts are taken from su(1) which is:
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * With some parts substantially derived from an ancestor of:
+ * su for GNU. Run a shell with substitute user and group IDs.
+ * Copyright (C) 1992-2003 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
#include "xsession-child.h"
#include "xserver.h"
--
Automatic Display Manager
More information about the pkg-fso-commits
mailing list