Hi there,
On Thu, 2009-08-13 at 14:29 -0700, Kok, Auke wrote:
> I've ignored g_* largely until now, I may be inclined to not do
> so from now on :)
Heh :-) It looks to me as if just doing the waitpid (0,NULL,0) may not
be enough - you presumably want to do a waitpid (xpid, NULL, WNOHANG)
after that to cleanup, at least that might de-zombify X - though, as you
can see I know nothing of this nastiness ;-) [ the API looks
fundamentally racy to me in terms of pid re-use anyway but ... ]
Anyhow - another patch attached; this adds a '-x' option to uxlauncher
- that essentially does only the user session setup pieces, rather than
the gdm replacement bits. Basically, a somewhat trivial re-arrangement
of parts of uxlaunch.
That allows us to share the nice session startup, ioprio, fast desktop
parsing (etc.), SCIM launching features - without having to throw out
gdm, and our distro X setup / init scripts.
Oh - and I also extended the locales we launch scim for, to add
Japanese & Korean, and make that slightly prettier.
Love to see it in your builds - indeed, it'd be nice to see the other
two patches merged: would it help to track them, if I file them in
bugzilla ?
Thanks,
Michael.
--- boilerplate waiver ---
The attached / included patches are submitted under the terms here:
http://bugzilla.openedhand.com/waiver.html applied to whatsoever
product to which they apply, rather than to clutter:
--
[email protected] <><, Pseudo Engineer, itinerant idiot
diff --git a/desktop.c b/desktop.c
index 73a96f7..63c0d5a 100644
--- a/desktop.c
+++ b/desktop.c
@@ -17,8 +17,10 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <dirent.h>
#include <time.h>
+#include <errno.h>
#include <glib.h>
#include "uxlaunch.h"
@@ -328,9 +330,28 @@ void start_desktop_session(void)
while (ptrs[count] && count < 255)
ptrs[++count] = strtok(NULL, " \t");
+ lprintf("Exec session '%s'", session);
ret = execv(ptrs[0], ptrs);
if (ret != EXIT_SUCCESS)
lprintf("Failed to start %s", session);
}
+void wait_for_session_exit(void)
+{
+ lprintf("wait_for_session_exit");
+ for (;;) {
+ errno = 0;
+ if (waitpid (session_pid, NULL, 0) < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else if (errno == ECHILD)
+ break; /* child already reaped */
+ else
+ lprintf("waidpid error '%s'", strerror (errno));
+ }
+ break;
+ }
+
+ lprintf("session exited");
+}
diff --git a/lib.c b/lib.c
index 9d77137..79815c0 100644
--- a/lib.c
+++ b/lib.c
@@ -24,8 +24,6 @@
#include "uxlaunch.h"
-#define LOGFILE "/var/log/uxlaunch.log"
-
extern char **environ;
static int first_time = 1;
@@ -36,10 +34,13 @@ struct timeval start;
static FILE *log;
-void open_log(void)
+void open_log(const char *logfile)
{
/* truncate log */
- log = fopen(LOGFILE, "w");
+ if (!logfile)
+ log = stdout;
+ else
+ log = fopen(logfile, "w");
if (!log)
logfile_enabled = 0;
}
diff --git a/options.c b/options.c
index 49a7245..a5760a0 100644
--- a/options.c
+++ b/options.c
@@ -29,6 +29,7 @@ char session[256] = "/usr/bin/mutter --sm-disable";
char username[256] = "moblin";
int verbose = 0;
+int x_session_only = 0;
static struct option opts[] = {
{ "user", 1, NULL, 'u' },
@@ -46,6 +47,7 @@ void usage(const char *name)
printf(" -u, --user Start session as specific username\n");
printf(" -t, --tty Start session on alternative tty number\n");
printf(" -s, --session Start a non-default session\n");
+ printf(" -x, --xsession Start X apps inside an existing X session\n");
printf(" -v, --verbose Display lots of output to the console\n");
printf(" -h, --help Display this help message\n");
}
@@ -132,7 +134,7 @@ void get_options(int argc, char **argv)
/* parse cmdline - overrides */
while (1) {
- c = getopt_long(argc, argv, "u:t:s:hv", opts, &i);
+ c = getopt_long(argc, argv, "u:t:s:hvx", opts, &i);
if (c == -1)
break;
@@ -153,6 +155,9 @@ void get_options(int argc, char **argv)
case 'v':
verbose = 1;
break;
+ case 'x':
+ x_session_only = 1;
+ break;
default:
break;
}
@@ -170,7 +175,9 @@ void get_options(int argc, char **argv)
}
}
- lprintf("uxlaunch v%s started.", VERSION);
+ open_log(!x_session_only ? LOGFILE : NULL);
+
+ lprintf("uxlaunch v%s started%s.", VERSION, x_session_only ? " for x session only" : "" );
lprintf("user \"%s\", tty #%d, session \"%s\"", username, tty, session);
pass = getpwnam(username);
diff --git a/user.c b/user.c
index 85b2801..0c5c5d1 100644
--- a/user.c
+++ b/user.c
@@ -78,12 +78,6 @@ void switch_to_user(void)
setenv("PATH", buf, 1);
snprintf(user_xauth_path, PATH_MAX, "%s/.Xauthority", pass->pw_dir);
setenv("XAUTHORITY", user_xauth_path, 1);
- snprintf(buf, PATH_MAX, "%s/.cache", pass->pw_dir);
- mkdir(buf, 0700);
- setenv("XDG_CACHE_HOME", buf, 0);
- snprintf(buf, PATH_MAX, "%s/.config", pass->pw_dir);
- setenv("XDG_CONFIG_HOME", buf, 0);
- setenv("OOO_FORCE_DESKTOP","gnome", 0);
set_i18n();
@@ -143,10 +137,6 @@ void set_i18n(void)
* and other user stuff we don't care for now */
if (!strcmp(key, "LANG")) {
setenv(key, val, 1);
- if (strstr(val, "zh_")) {
- setenv("GTK_IM_MODULE", "scim-bridge", 0);
- setenv("CLUTTER_IM_MODULE","scim-bridge", 0);
- }
}
if (!strcmp(key, "SYSFONT"))
setenv(key, val, 1);
@@ -156,3 +146,31 @@ void set_i18n(void)
log_environment();
}
+
+void setup_user_environment (void)
+{
+ int i;
+ char buf[PATH_MAX];
+ const char *lang;
+ static const char *scim_langs[] = {
+ "zh_", "ko_", "ja_", NULL
+ };
+
+ /* launch scim only where it makes sense */
+ lang = getenv ("LANG");
+ for (i = 0; lang && scim_langs[i]; i++) {
+ if (strstr (lang, scim_langs[i])) {
+ setenv("GTK_IM_MODULE", "scim-bridge", 0);
+ setenv("CLUTTER_IM_MODULE","scim-bridge", 0);
+ break;
+ }
+ }
+
+ /* setup misc. user directories and variables */
+ snprintf(buf, PATH_MAX, "%s/.cache", pass->pw_dir);
+ mkdir(buf, 0700);
+ setenv("XDG_CACHE_HOME", buf, 0);
+ snprintf(buf, PATH_MAX, "%s/.config", pass->pw_dir);
+ setenv("XDG_CONFIG_HOME", buf, 0);
+ setenv("OOO_FORCE_DESKTOP","gnome", 0);
+}
diff --git a/uxlaunch.c b/uxlaunch.c
index 2375525..1a7d5e5 100644
--- a/uxlaunch.c
+++ b/uxlaunch.c
@@ -19,11 +19,37 @@
#include "uxlaunch.h"
+/*
+ * Launch apps that form the user's X session
+ */
+static void
+launch_user_session(void)
+{
+ setup_user_environment ();
+
+ start_ssh_agent();
+
+ /* dbus needs the CK env var */
+ if (!x_session_only)
+ setup_consolekit_session();
+
+ start_dbus_session_bus();
+
+ /* gconf needs dbus */
+ start_gconf();
+
+ maybe_start_screensaver();
+
+ start_desktop_session();
+
+ get_session_type();
+ autostart_panels();
+ autostart_desktop_files();
+ do_autostart();
+}
int main(int argc, char **argv)
{
- open_log();
-
/*
* General objective:
* Do the things that need root privs first,
@@ -49,6 +75,13 @@ int main(int argc, char **argv)
*/
get_options(argc, argv);
+
+ if (x_session_only) {
+ launch_user_session();
+ wait_for_session_exit();
+ return 0;
+ }
+
set_tty();
setup_pam_session();
@@ -57,7 +90,6 @@ int main(int argc, char **argv)
switch_to_user();
-
start_X_server();
/*
@@ -68,24 +100,7 @@ int main(int argc, char **argv)
wait_for_X_signal();
- start_ssh_agent();
-
- setup_consolekit_session();
-
- /* dbus needs the CK env var */
- start_dbus_session_bus();
-
- /* gconf needs dbus */
- start_gconf();
-
- maybe_start_screensaver();
-
- start_desktop_session();
-
- get_session_type();
- autostart_panels();
- autostart_desktop_files();
- do_autostart();
+ launch_user_session();
wait_for_X_exit();
diff --git a/uxlaunch.h b/uxlaunch.h
index 7e4d689..a23bad2 100644
--- a/uxlaunch.h
+++ b/uxlaunch.h
@@ -3,6 +3,7 @@
#include <X11/Xauth.h>
+#define LOGFILE "/var/log/uxlaunch.log"
/*
* Target user information
@@ -22,12 +23,14 @@ extern char username[];
extern int session_pid;
extern int verbose;
+extern int x_session_only;
extern void get_options(int argc, char **argv);
extern void set_i18n(void);
extern void setup_pam_session(void);
extern void close_pam_session(void);
extern void switch_to_user(void);
+extern void setup_user_environment (void);
extern void set_tty(void);
extern void setup_xauth(void);
extern void start_X_server(void);
@@ -44,11 +47,12 @@ extern void autostart_panels(void);
extern void autostart_desktop_files(void);
extern void do_autostart(void);
extern void start_desktop_session(void);
+extern void wait_for_session_exit(void);
extern void start_bash(void);
extern void wait_for_X_exit(void);
extern void set_text_mode(void);
-extern void open_log(void);
+extern void open_log(const char *);
extern void lprintf(const char *, ...);
extern void log_environment(void);
_______________________________________________
Moblin dev Mailing List
[email protected]
To manage or unsubscribe from this mailing list visit:
http://lists.moblin.org/listinfo/dev or your user account on http://moblin.org
once logged in.
For more information on the Moblin Developer Mailing lists visit:
http://moblin.org/community/mailing-lists