[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