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 f4b7ad9cc6)
This commit is contained in:
Jeremy Huddleston 2008-12-09 23:47:32 -08:00
parent e5ce6e198f
commit 76351d2faf
4 changed files with 106 additions and 69 deletions

View File

@ -315,22 +315,44 @@ BOOL xquartz_resetenv_display = NO;
- (void) launch_client:(NSString *)filename - (void) launch_client:(NSString *)filename
{ {
const char *command = [filename UTF8String]; const char *command = [filename UTF8String];
const char *argv[7];
int child1, child2 = 0; int child1, child2 = 0;
int status; int status;
char newcommand[1024];
char *newargv[1024];
char buf[128];
size_t newargc;
char *s;
argv[0] = "/usr/bin/login"; if(strlen(command) > 1023) {
argv[1] = "-fp"; fprintf(stderr, "Error: command is too long: %s\n", command);
argv[2] = getlogin(); return;
argv[3] = [X11App prefs_get_string:@PREFS_LOGIN_SHELL default:"/bin/sh"]; }
argv[4] = "-c";
argv[5] = command; strlcpy(newcommand, command, 1024);
argv[6] = NULL;
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 */ /* Do the fork-twice trick to avoid having to reap zombies */
child1 = fork(); child1 = fork();
switch (child1) { switch (child1) {
case -1: /* error */ case -1: /* error */
break; break;
@ -340,7 +362,6 @@ BOOL xquartz_resetenv_display = NO;
switch (child2) { switch (child2) {
int max_files, i; int max_files, i;
char buf[1024], *temp;
case -1: /* error */ case -1: /* error */
_exit(1); _exit(1);
@ -348,21 +369,14 @@ BOOL xquartz_resetenv_display = NO;
case 0: /* child2 */ case 0: /* child2 */
/* close all open files except for standard streams */ /* close all open files except for standard streams */
max_files = sysconf(_SC_OPEN_MAX); max_files = sysconf(_SC_OPEN_MAX);
for (i = 3; i < max_files; i++) close(i); for(i = 3; i < max_files; i++)
close(i);
/* ensure stdin is on /dev/null */ /* ensure stdin is on /dev/null */
close(0); close(0);
open("/dev/null", O_RDONLY); open("/dev/null", O_RDONLY);
/* Setup environment */ execvp(newargv[0], (char **const) newargv);
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); _exit(2);
default: /* parent (child1) */ default: /* parent (child1) */

3
hw/xquartz/bundle/X11.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash --login
./X11 "${@}"

View File

@ -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 Info.plist ${BUNDLE_ROOT}/Contents
install -m 644 PkgInfo ${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 if [[ $(id -u) == 0 ]] ; then
chown -R root:admin ${BUNDLE_ROOT} chown -R root:admin ${BUNDLE_ROOT}
fi fi

View File

@ -531,20 +531,37 @@ int main(int argc, char **argv, char **envp) {
} }
static int execute(const char *command) { static int execute(const char *command) {
const char *newargv[7]; char newcommand[1024];
const char **s; char *newargv[1024];
size_t newargc;
char *s;
char **p;
newargv[0] = "/usr/bin/login"; if(strlen(command) > 1023) {
newargv[1] = "-fp"; fprintf(stderr, "Error: command is too long: %s\n", command);
newargv[2] = getlogin(); return 1;
newargv[3] = command_from_prefs("login_shell", DEFAULT_SHELL); }
newargv[4] = "-c";
newargv[5] = command; strlcpy(newcommand, command, 1024);
newargv[6] = NULL;
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); fprintf(stderr, "X11.app: Launching %s:\n", command);
for(s=newargv; *s; s++) { for(p=newargv; *p; p++) {
fprintf(stderr, "\targv[%ld] = %s\n", (long int)(s - newargv), *s); fprintf(stderr, "\targv[%ld] = %s\n", (long int)(p - newargv), *p);
} }
execvp (newargv[0], (char * const *) newargv); execvp (newargv[0], (char * const *) newargv);