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:
parent
e5ce6e198f
commit
76351d2faf
|
@ -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
3
hw/xquartz/bundle/X11.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash --login
|
||||
|
||||
./X11 "${@}"
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user