summaryrefslogtreecommitdiff
authorJeremy Huddleston <jeremyhu@freedesktop.org>2008-12-10 07:47:32 (GMT)
committer Jeremy Huddleston <jeremyhu@freedesktop.org>2008-12-10 23:07:49 (GMT)
commitfdf64256127b2661bd6aa81ac694350028d36c43 (patch) (side-by-side diff)
tree9a62a1d8f2bce8230537ddf1e3311e48193627a9
parent9cbed0a325175e7ddb751db54fe6c0f5a5cedd16 (diff)
downloadxserver-fdf64256127b2661bd6aa81ac694350028d36c43.zip
xserver-fdf64256127b2661bd6aa81ac694350028d36c43.tar.gz
XQuartz: Avoid using login /bin/sh blech. Just use a bash script to start the app, so it will inherit the right environment
(cherry picked from commit f4b7ad9cc6b0c99fc7ee8516c4bf858ece938148)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--hw/xquartz/X11Controller.m122
-rwxr-xr-xhw/xquartz/bundle/X11.sh3
-rwxr-xr-xhw/xquartz/bundle/mk_bundke.sh3
-rw-r--r--hw/xquartz/mach-startup/bundle-main.c43
4 files changed, 104 insertions, 67 deletions
diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m
index 67a80d3..7222f46 100644
--- a/hw/xquartz/X11Controller.m
+++ b/hw/xquartz/X11Controller.m
@@ -314,65 +314,79 @@ BOOL xquartz_resetenv_display = NO;
- (void) launch_client:(NSString *)filename
{
- const char *command = [filename UTF8String];
- const char *argv[7];
- int child1, child2 = 0;
- int status;
-
- argv[0] = "/usr/bin/login";
- argv[1] = "-fp";
- argv[2] = getlogin();
- argv[3] = [X11App prefs_get_string:@PREFS_LOGIN_SHELL default:"/bin/sh"];
- argv[4] = "-c";
- argv[5] = command;
- argv[6] = NULL;
-
- /* Do the fork-twice trick to avoid having to reap zombies */
+ const char *command = [filename UTF8String];
+ int child1, child2 = 0;
+ int status;
+ char newcommand[1024];
+ char *newargv[1024];
+ char buf[128];
+ size_t newargc;
+ char *s;
- child1 = fork();
+ if(strlen(command) > 1023) {
+ fprintf(stderr, "Error: command is too long: %s\n", command);
+ return;
+ }
+
+ strlcpy(newcommand, command, 1024);
- switch (child1) {
- case -1: /* error */
- break;
+ for(newargc=0, s=newcommand; *s; newargc++) {
+ for(; *s && *s == ' '; s++);
+ if(!*s)
+ break;
+
+ newargv[newargc] = s;
+ for(; *s && *s != ' '; s++);
+
+ if(*s) {
+ *s='\0';
+ s++;
+ }
+ }
+ newargv[newargc] = NULL;
+
+ s = getenv("DISPLAY");
+ if (xquartz_resetenv_display || s == NULL || s[0] == 0) {
+ snprintf(buf, sizeof(buf), ":%s", display);
+ setenv("DISPLAY", buf, TRUE);
+ }
+
+ /* Do the fork-twice trick to avoid having to reap zombies */
+ child1 = fork();
+ switch (child1) {
+ case -1: /* error */
+ break;
- case 0: /* child1 */
- child2 = fork();
+ case 0: /* child1 */
+ child2 = fork();
- switch (child2) {
- int max_files, i;
- char buf[1024], *temp;
-
- case -1: /* error */
- _exit(1);
-
- case 0: /* child2 */
- /* close all open files except for standard streams */
- max_files = sysconf(_SC_OPEN_MAX);
- for (i = 3; i < max_files; i++) close(i);
-
- /* ensure stdin is on /dev/null */
- close(0);
- open("/dev/null", O_RDONLY);
-
- /* Setup environment */
- temp = getenv("DISPLAY");
- if (xquartz_resetenv_display || temp == NULL || temp[0] == 0) {
- snprintf(buf, sizeof(buf), ":%s", display);
- setenv("DISPLAY", buf, TRUE);
- }
-
- execvp(argv[0], (char **const) argv);
-
- _exit(2);
-
- default: /* parent (child1) */
- _exit(0);
- }
- break;
+ switch (child2) {
+ int max_files, i;
+
+ case -1: /* error */
+ _exit(1);
+
+ case 0: /* child2 */
+ /* close all open files except for standard streams */
+ max_files = sysconf(_SC_OPEN_MAX);
+ for(i = 3; i < max_files; i++)
+ close(i);
+
+ /* ensure stdin is on /dev/null */
+ close(0);
+ open("/dev/null", O_RDONLY);
+
+ execvp(newargv[0], (char **const) newargv);
+ _exit(2);
+
+ default: /* parent (child1) */
+ _exit(0);
+ }
+ break;
- default: /* parent */
- waitpid(child1, &status, 0);
- }
+ default: /* parent */
+ waitpid(child1, &status, 0);
+ }
}
- (void) app_selected:sender
diff --git a/hw/xquartz/bundle/X11.sh b/hw/xquartz/bundle/X11.sh
new file mode 100755
index 0000000..5e00a82
--- a/dev/null
+++ b/hw/xquartz/bundle/X11.sh
@@ -0,0 +1,3 @@
+#!/bin/bash --login
+
+./X11 "${@}"
diff --git a/hw/xquartz/bundle/mk_bundke.sh b/hw/xquartz/bundle/mk_bundke.sh
index 0b2a144..5c5733a 100755
--- a/hw/xquartz/bundle/mk_bundke.sh
+++ b/hw/xquartz/bundle/mk_bundke.sh
@@ -20,6 +20,9 @@ install -m 644 Resources/X11.icns ${BUNDLE_ROOT}/Contents/Resources
install -m 644 Info.plist ${BUNDLE_ROOT}/Contents
install -m 644 PkgInfo ${BUNDLE_ROOT}/Contents
+mkdir -p ${BUNDLE_ROOT}/Contents/MacOS
+install -m 755 X11.sh ${BUNDLE_ROOT}/Contents/MacOS
+
if [[ $(id -u) == 0 ]] ; then
chown -R root:admin ${BUNDLE_ROOT}
fi
diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index 6b48c13..7677a9a 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -529,22 +529,39 @@ int main(int argc, char **argv, char **envp) {
return EXIT_SUCCESS;
}
-
-static int execute(const char *command) {
- const char *newargv[7];
- const char **s;
- newargv[0] = "/usr/bin/login";
- newargv[1] = "-fp";
- newargv[2] = getlogin();
- newargv[3] = command_from_prefs("login_shell", DEFAULT_SHELL);
- newargv[4] = "-c";
- newargv[5] = command;
- newargv[6] = NULL;
+static int execute(const char *command) {
+ char newcommand[1024];
+ char *newargv[1024];
+ size_t newargc;
+ char *s;
+ char **p;
+
+ if(strlen(command) > 1023) {
+ fprintf(stderr, "Error: command is too long: %s\n", command);
+ return 1;
+ }
+
+ strlcpy(newcommand, command, 1024);
+
+ for(newargc=0, s=newcommand; *s; newargc++) {
+ for(; *s && *s == ' '; s++);
+ if(!*s)
+ break;
+
+ newargv[newargc] = s;
+ for(; *s && *s != ' '; s++);
+
+ if(*s) {
+ *s='\0';
+ s++;
+ }
+ }
+ newargv[newargc] = NULL;
fprintf(stderr, "X11.app: Launching %s:\n", command);
- for(s=newargv; *s; s++) {
- fprintf(stderr, "\targv[%ld] = %s\n", (long int)(s - newargv), *s);
+ for(p=newargv; *p; p++) {
+ fprintf(stderr, "\targv[%ld] = %s\n", (long int)(p - newargv), *p);
}
execvp (newargv[0], (char * const *) newargv);