[pkg-fso-commits] [SCM] Automatic Display Manager branch, bug540201, updated. debian/0.6-1-29-g2eaffc8
Enrico Zini
enrico at enricozini.org
Tue Jul 5 12:23:51 UTC 2011
The following commit has been merged in the bug540201 branch:
commit 2eaffc835bd31cec0f2a7265843b2afbcb6d1a61
Author: Enrico Zini <enrico at enricozini.org>
Date: Tue Jul 5 14:23:47 2011 +0200
Make parse_cmdline testable, test it and fix it
diff --git a/nodm.c b/nodm.c
index ce1aaab..d987cee 100644
--- a/nodm.c
+++ b/nodm.c
@@ -198,12 +198,17 @@ void run_and_restart(const char* xsession, const char* xoptions, int mst)
struct session s;
nodm_session_init(&s);
+ int status = nodm_session_parse_cmdline(&s, xoptions);
+ if (status != E_SUCCESS)
+ exit(status);
+
/* Run the X server */
time_t begin = time(NULL);
time_t end;
- int status = nodm_x_with_session_cmdline(&s, xoptions);
+ status = nodm_x_with_session(&s);
log_info("X session exited with status %d", status);
- end = time(NULL);
+ end = time(NULL);
+ nodm_session_cleanup(&s);
/* Check if the session was too short */
if (end - begin < mst)
diff --git a/session.c b/session.c
index 76c01d2..5bf5f8a 100644
--- a/session.c
+++ b/session.c
@@ -47,19 +47,6 @@
#define STRFCPY(A,B) \
(strncpy((A), (B), sizeof(A) - 1), (A)[sizeof(A) - 1] = '\0')
-void nodm_session_init(struct session* s)
-{
- server_init(&(s->srv));
-
- s->pamh = NULL;
- s->conf_use_pam = true;
- s->conf_cleanup_xse = true;
-
- // Get the user we should run the session for
- strncpy(s->conf_run_as, getenv_with_default("NODM_USER", "root"), 128);
- s->conf_run_as[127] = 0;
-}
-
static int run_shell (const char** args, int* status);
/*
@@ -271,7 +258,7 @@ static int session_pam_setup(struct session* s)
return E_SUCCESS;
}
-static void session_pam_shutdown(struct session* s)
+void session_pam_shutdown(struct session* s)
{
if (s->pam_status == PAM_SUCCESS)
{
@@ -284,6 +271,37 @@ static void session_pam_shutdown(struct session* s)
s->pamh = 0;
}
+void nodm_session_init(struct session* s)
+{
+ server_init(&(s->srv));
+ s->pamh = NULL;
+ s->pam_status = PAM_SUCCESS;
+ s->srv_split_args = NULL;
+
+ s->conf_use_pam = true;
+ s->conf_cleanup_xse = true;
+
+ // Get the user we should run the session for
+ strncpy(s->conf_run_as, getenv_with_default("NODM_USER", "root"), 128);
+ s->conf_run_as[127] = 0;
+}
+
+void nodm_session_cleanup(struct session* s)
+{
+ // End pam session if used
+ if (s->pamh)
+ session_pam_shutdown(s);
+
+ // Deallocate parsed arguments, if used
+ if (s->srv_split_args)
+ {
+ wordexp_t* we = (wordexp_t*)s->srv_split_args;
+ wordfree(we);
+ free(we);
+ s->srv_split_args = NULL;
+ }
+}
+
/*
* Start the session, with proper autologin and pam handling
*/
@@ -360,8 +378,7 @@ int nodm_session(struct session* s)
if ((res = run_shell(args, &status)))
return res;
- if (s->pamh)
- session_pam_shutdown(s);
+ nodm_session_cleanup(s);
return status;
}
@@ -472,13 +489,10 @@ killed:
return E_SESSION_DIED;
}
-int nodm_x_with_session_argv(struct session* s, const char* argv[])
+int nodm_x_with_session(struct session* s)
{
int return_code = 0;
- s->srv.argv = argv;
- s->srv.name = argv[1];
-
return_code = server_start(&(s->srv), 5);
if (return_code != E_SUCCESS)
goto cleanup;
@@ -503,48 +517,61 @@ cleanup:
return return_code;
}
-int nodm_x_with_session_cmdline(struct session* s, const char* xcmdline)
+int nodm_session_parse_cmdline(struct session* s, const char* xcmdline)
{
+ int return_code = E_SUCCESS;
+
// tokenize xoptions
- wordexp_t toks = { .we_offs = 0 };
- switch (wordexp(xcmdline, &toks, WRDE_NOCMD))
+ wordexp_t* toks = (wordexp_t*)calloc(1, sizeof(wordexp_t));
+ switch (wordexp(xcmdline, toks, WRDE_NOCMD))
{
case 0: break;
case WRDE_NOSPACE:
- wordfree(&toks);
- return E_OS_ERROR;
+ return_code = E_OS_ERROR;
+ goto cleanup;
default:
- return E_BAD_ARG;
+ toks->we_wordv = NULL;
+ return_code = E_BAD_ARG;
+ goto cleanup;
}
unsigned in_arg = 0;
unsigned argc = 0;
- char *argv[100];
+ char **argv = (char**)malloc((toks->we_wordc + 3) * sizeof(char*));
// Server command
- if (toks.we_wordc == in_arg ||
- (toks.we_wordv[in_arg][0] != '/' && toks.we_wordv[in_arg][0] != '.'))
- argv[argc++] = toks.we_wordv[in_arg++];
+ if (in_arg < toks->we_wordc &&
+ (toks->we_wordv[in_arg][0] == '/' || toks->we_wordv[in_arg][0] == '.'))
+ argv[argc++] = toks->we_wordv[in_arg++];
else
argv[argc++] = "/usr/bin/X";
// Server name
- if (toks.we_wordc == in_arg ||
- (toks.we_wordv[in_arg][0] == ':' && isdigit(toks.we_wordv[in_arg][1])))
- argv[argc++] = toks.we_wordv[in_arg++];
+ if (in_arg < toks->we_wordc &&
+ toks->we_wordv[in_arg][0] == ':' && isdigit(toks->we_wordv[in_arg][1]))
+ argv[argc++] = toks->we_wordv[in_arg++];
else
argv[argc++] = ":0";
// Copy other args
- while (in_arg < toks.we_wordc && argc < 100)
- argv[argc++] = toks.we_wordv[in_arg++];
- argv[99] = NULL;
+ while (in_arg < toks->we_wordc)
+ argv[argc++] = toks->we_wordv[in_arg++];
+ argv[argc] = NULL;
- // Run session
- int res = nodm_x_with_session_argv(s, argv);
+ s->srv.argv = argv;
+ s->srv_split_args = toks;
+ argv = NULL;
+ toks = NULL;
- // Free arg list
- wordfree(&toks);
+cleanup:
+ if (toks != NULL)
+ {
+ if (toks->we_wordv)
+ wordfree(toks);
+ free(toks);
+ }
+ if (argv != NULL)
+ free(argv);
- return res;
+ return E_SUCCESS;
}
diff --git a/session.h b/session.h
index da75449..48a533c 100644
--- a/session.h
+++ b/session.h
@@ -52,11 +52,17 @@ struct session
/// Return code of the last PAM function called
int pam_status;
+
+ /// Storage for split server arguments used by nodm_x_cmdline_split
+ void* srv_split_args;
};
/// Initialise a session structure with default values
void nodm_session_init(struct session* s);
+/// Cleanup at the end of a session
+void nodm_session_cleanup(struct session* s);
+
/**
* nodm X session
*
@@ -69,11 +75,10 @@ int nodm_session(struct session* s);
* Start the X server using the given command line, change user to $NODM_USER
* and run $NODM_XSESSION
*/
-int nodm_x_with_session_argv(struct session* s, const char* argv[]);
+int nodm_x_with_session(struct session* s);
/**
- * Split xcmdline using wordexp shell-like expansion and run
- * nodm_x_with_session_argv().
+ * Split xcmdline using wordexp shell-like expansion and set s->srv.argv.
*
* If the first token starts with '/' or '.', it is used as the X server, else
* "X" is used as the server.
@@ -82,6 +87,6 @@ int nodm_x_with_session_argv(struct session* s, const char* argv[]);
* to the X server) looks like ":<NUMBER>", it is used as the display name,
* else ":0" is used.
*/
-int nodm_x_with_session_cmdline(struct session* s, const char* xcmdline);
+int nodm_session_parse_cmdline(struct session* s, const char* xcmdline);
#endif
diff --git a/test-internals.c b/test-internals.c
index 6909eac..c16b872 100644
--- a/test-internals.c
+++ b/test-internals.c
@@ -20,12 +20,15 @@
#include "log.h"
#include "common.h"
+#include "session.h"
#include <stdio.h>
#include <stdlib.h>
void ensure_equals(const char* a, const char* b)
{
- if (strcmp(a, b) != 0)
+ if (a == NULL && b == NULL)
+ return;
+ if (a == NULL || b == NULL || strcmp(a, b) != 0)
{
log_warn("strings differ: \"%s\" != \"%s\"", a, b);
exit(1);
@@ -48,6 +51,67 @@ int main(int argc, char* argv[])
unsetenv("FOO");
ensure_equals(getenv_with_default("FOO", "bar"), "bar");
+ struct session s;
+
+ nodm_session_init(&s);
+ nodm_session_parse_cmdline(&s, "");
+ ensure_equals(s.srv.argv[0], "/usr/bin/X");
+ ensure_equals(s.srv.argv[1], ":0");
+ ensure_equals(s.srv.argv[2], NULL);
+ nodm_session_cleanup(&s);
+
+ nodm_session_init(&s);
+ nodm_session_parse_cmdline(&s, "foo");
+ ensure_equals(s.srv.argv[0], "/usr/bin/X");
+ ensure_equals(s.srv.argv[1], ":0");
+ ensure_equals(s.srv.argv[2], "foo");
+ ensure_equals(s.srv.argv[3], NULL);
+ nodm_session_cleanup(&s);
+
+ nodm_session_init(&s);
+ nodm_session_parse_cmdline(&s, "/usr/bin/Xnest");
+ ensure_equals(s.srv.argv[0], "/usr/bin/Xnest");
+ ensure_equals(s.srv.argv[1], ":0");
+ ensure_equals(s.srv.argv[2], NULL);
+ nodm_session_cleanup(&s);
+
+ nodm_session_init(&s);
+ nodm_session_parse_cmdline(&s, ":1");
+ ensure_equals(s.srv.argv[0], "/usr/bin/X");
+ ensure_equals(s.srv.argv[1], ":1");
+ ensure_equals(s.srv.argv[2], NULL);
+ nodm_session_cleanup(&s);
+
+ nodm_session_init(&s);
+ nodm_session_parse_cmdline(&s, "/usr/bin/Xnest :1");
+ ensure_equals(s.srv.argv[0], "/usr/bin/Xnest");
+ ensure_equals(s.srv.argv[1], ":1");
+ ensure_equals(s.srv.argv[2], NULL);
+ nodm_session_cleanup(&s);
+
+ nodm_session_init(&s);
+ nodm_session_parse_cmdline(&s, "/usr/bin/Xnest foo");
+ ensure_equals(s.srv.argv[0], "/usr/bin/Xnest");
+ ensure_equals(s.srv.argv[1], ":0");
+ ensure_equals(s.srv.argv[2], "foo");
+ ensure_equals(s.srv.argv[3], NULL);
+ nodm_session_cleanup(&s);
+
+ nodm_session_init(&s);
+ nodm_session_parse_cmdline(&s, ":1 foo");
+ ensure_equals(s.srv.argv[0], "/usr/bin/X");
+ ensure_equals(s.srv.argv[1], ":1");
+ ensure_equals(s.srv.argv[2], "foo");
+ ensure_equals(s.srv.argv[3], NULL);
+ nodm_session_cleanup(&s);
+
+ nodm_session_init(&s);
+ nodm_session_parse_cmdline(&s, "/usr/bin/Xnest :1 foo");
+ ensure_equals(s.srv.argv[0], "/usr/bin/Xnest");
+ ensure_equals(s.srv.argv[1], ":1");
+ ensure_equals(s.srv.argv[2], "foo");
+ ensure_equals(s.srv.argv[3], NULL);
+ nodm_session_cleanup(&s);
log_end();
return 0;
diff --git a/test-xsession.c b/test-xsession.c
index 9900212..c5f59c5 100644
--- a/test-xsession.c
+++ b/test-xsession.c
@@ -40,9 +40,16 @@ int main(int argc, char* argv[])
struct session s;
nodm_session_init(&s);
- int res = nodm_x_with_session_cmdline(&s, xcmdline);
- fprintf("nodm_x_with_session_cmdline returned %d\n", res);
+ int res = E_SUCCESS;
+ res = nodm_session_parse_cmdline(&s, xcmdline);
+ if (res != E_SUCCESS) goto cleanup;
+
+ res = nodm_x_with_session(&s);
+ fprintf(stderr, "nodm_x_with_session_cmdline returned %d\n", res);
+ if (res != E_SUCCESS) goto cleanup;
+
+cleanup:
log_end();
return res;
}
--
Automatic Display Manager
More information about the pkg-fso-commits
mailing list