XQuartz: Avoid using login /bin/sh blech. Just use a bash script to start the app, so it will inherit the right environment

This commit is contained in:
Jeremy Huddleston 2008-12-09 23:47:32 -08:00
parent b959727f38
commit f4b7ad9cc6
4 changed files with 106 additions and 69 deletions

View File

@ -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();
switch (child1) {
case -1: /* error */
break;
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);
if(strlen(command) > 1023) {
fprintf(stderr, "Error: command is too long: %s\n", command);
return;
}
break;
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;
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;
default: /* parent */
waitpid(child1, &status, 0);
}
case 0: /* child1 */
child2 = fork();
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);
}
}
- (void) app_selected:sender

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 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

View File

@ -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);