about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-09-15 14:07:46 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-09-15 14:07:46 +0200
commit21c56e78988e424ef027985312b4e376a84c15f9 (patch)
treefb7e9d8ab5f0ea72b705ccd8e2d15238da070558 /src
parent7c74e7be35d9f235b4c308aac2ab8c32bdd40f90 (diff)
downloadbox64-21c56e78988e424ef027985312b4e376a84c15f9.tar.gz
box64-21c56e78988e424ef027985312b4e376a84c15f9.zip
Improved usage of x86_64 bash with BOX64_BASH env var
Diffstat (limited to 'src')
-rwxr-xr-xsrc/box64context.c1
-rwxr-xr-xsrc/include/box64context.h1
-rwxr-xr-xsrc/include/debug.h1
-rwxr-xr-xsrc/main.c56
-rwxr-xr-xsrc/wrapped/wrappedlibc.c78
5 files changed, 93 insertions, 44 deletions
diff --git a/src/box64context.c b/src/box64context.c
index 355d4c68..9a522748 100755
--- a/src/box64context.c
+++ b/src/box64context.c
@@ -260,6 +260,7 @@ void FreeBox64Context(box64context_t** context)
 
     box_free(ctx->fullpath);
     box_free(ctx->box64path);
+    box_free(ctx->bashpath);
 
     FreeBridge(&ctx->system);
 
diff --git a/src/include/box64context.h b/src/include/box64context.h
index 79560227..5dc2399d 100755
--- a/src/include/box64context.h
+++ b/src/include/box64context.h
@@ -89,6 +89,7 @@ typedef struct box64context_s {
     char*               fullpath;
     char*               box64path;      // path of current box64 executable
     char*               box86path;      // path of box86 executable (if present)
+    char*               bashpath;       // path of x86_64 bash (defined with BOX64_BASH or by running bash directly)
 
     uint64_t            stacksz;
     size_t              stackalign;
diff --git a/src/include/debug.h b/src/include/debug.h
index 057d7898..5f228f58 100755
--- a/src/include/debug.h
+++ b/src/include/debug.h
@@ -41,7 +41,6 @@ extern int box64_prefer_wrapped;
 extern int box64_prefer_emulated;
 extern int box64_steam;
 extern int box64_wine;
-extern int box64_bash;
 extern int box64_musl;
 extern int box64_nopulse;   // disabling the use of wrapped pulseaudio
 extern int box64_nogtk; // disabling the use of wrapped gtk
diff --git a/src/main.c b/src/main.c
index ac04917c..6db4830f 100755
--- a/src/main.c
+++ b/src/main.c
@@ -84,7 +84,6 @@ int box64_mapclean = 0;
 int box64_zoom = 0;
 int box64_steam = 0;
 int box64_wine = 0;
-int box64_bash = 0;
 int box64_musl = 0;
 int box64_nopulse = 0;
 int box64_nogtk = 0;
@@ -556,7 +555,7 @@ void LoadLogEnv()
         printf_log(LOG_INFO, "BOX64 using \"%s\" as libGL.so.1\n", p);
     }
     p = getenv("BOX64_ALLOWMISSINGLIBS");
-        if(p) {
+    if(p) {
         if(strlen(p)==1) {
             if(p[0]>='0' && p[0]<='0'+1)
                 allow_missing_libs = p[0]-'0';
@@ -565,7 +564,7 @@ void LoadLogEnv()
             printf_log(LOG_INFO, "Allow missing needed libs\n");
     }
     p = getenv("BOX64_NOPULSE");
-        if(p) {
+    if(p) {
         if(strlen(p)==1) {
             if(p[0]>='0' && p[0]<='0'+1)
                 box64_nopulse = p[0]-'0';
@@ -574,7 +573,7 @@ void LoadLogEnv()
             printf_log(LOG_INFO, "Disable the use of pulseaudio libs\n");
     }
     p = getenv("BOX64_NOGTK");
-        if(p) {
+    if(p) {
         if(strlen(p)==1) {
             if(p[0]>='0' && p[0]<='0'+1)
                 box64_nogtk = p[0]-'0';
@@ -583,7 +582,7 @@ void LoadLogEnv()
             printf_log(LOG_INFO, "Disable the use of wrapped gtk libs\n");
     }
     p = getenv("BOX64_NOVULKAN");
-        if(p) {
+    if(p) {
         if(strlen(p)==1) {
             if(p[0]>='0' && p[0]<='0'+1)
                 box64_novulkan = p[0]-'0';
@@ -592,7 +591,7 @@ void LoadLogEnv()
             printf_log(LOG_INFO, "Disable the use of wrapped vulkan libs\n");
     }
     p = getenv("BOX64_FIX_64BIT_INODES");
-        if(p) {
+    if(p) {
         if(strlen(p)==1) {
             if(p[0]>='0' && p[0]<='0'+1)
                 fix_64bit_inodes = p[0]-'0';
@@ -601,7 +600,7 @@ void LoadLogEnv()
             printf_log(LOG_INFO, "Fix 64bit inodes\n");
     }
     p = getenv("BOX64_JITGDB");
-        if(p) {
+    if(p) {
         if(strlen(p)==1) {
             if(p[0]>='0' && p[0]<='0'+2)
                 jit_gdb = p[0]-'0';
@@ -1044,6 +1043,18 @@ int main(int argc, const char **argv, char **env) {
 
     // check BOX64_LOG debug level
     LoadLogEnv();
+    char* bashpath = NULL;
+    {
+        char* p = getenv("BOX64_BASH");
+        if(p) {
+            if(FileIsX64ELF(p)) {
+                bashpath = p;
+                printf_log(LOG_INFO, "Using bash \"%s\"\n", bashpath);
+            } else {
+                printf_log(LOG_INFO, "the x86_64 bash \"%s\" is not an x86_64 binary\n", p);
+            }
+        }
+    }
     
     const char* prog = argv[1];
     int nextarg = 1;
@@ -1239,12 +1250,18 @@ int main(int argc, const char **argv, char **env) {
     // special case for bash (add BOX86_NOBANNER=1 if not there)
     if(!strcmp(prgname, "bash")) {
         printf_log(LOG_INFO, "bash detected, disabling banner\n");
-        box64_bash = 1;
         if (!box64_nobanner) {
             setenv("BOX86_NOBANNER", "1", 0);
             setenv("BOX64_NOBANNER", "1", 0);
         }
+        if (!bashpath) {
+            bashpath = (char*)prog;
+            setenv("BOX64_BASH", prog, 1);
+        }
     }
+    if(bashpath)
+        my_context->bashpath = box_strdup(bashpath);
+
     if(strstr(prgname, "pressure-vessel-wrap")==prgname) {
         printf_log(LOG_INFO, "pressure-vessel-wrap detected, disabling GTK\n");
         box64_nogtk = 1;
@@ -1290,26 +1307,35 @@ int main(int argc, const char **argv, char **env) {
     elfheader_t *elf_header = LoadAndCheckElfHeader(f, my_context->argv[0], 1);
     if(!elf_header) {
         int x86 = my_context->box86path?FileIsX86ELF(my_context->argv[0]):0;
-        printf_log(LOG_NONE, "Error: reading elf header of %s, try to launch %s instead\n", my_context->argv[0], x86?"using box86":"natively");
+        int script = my_context->bashpath?FileIsShell(my_context->argv[0]):0;
+        printf_log(LOG_NONE, "Error: reading elf header of %s, try to launch %s instead\n", my_context->argv[0], x86?"using box86":(script?"using bash":"natively"));
         fclose(f);
-        free_contextargv();
         FreeCollection(&ld_preload);
+        int ret;
         if(x86) {
             // duplicate the array and insert 1st arg as box86
             const char** newargv = (const char**)box_calloc(my_context->argc+2, sizeof(char*));
             newargv[0] = my_context->box86path;
             for(int i=0; i<my_context->argc; ++i)
                 newargv[i+1] = my_context->argv[i];
-            FreeBox64Context(&my_context);
-            return execvp(newargv[0], (char * const*)newargv);
+            ret = execvp(newargv[0], (char * const*)newargv);
+        } else if (script) {
+            // duplicate the array and insert 1st arg as box64, 2nd is bash
+            const char** newargv = (const char**)box_calloc(my_context->argc+3, sizeof(char*));
+            newargv[0] = my_context->box64path;
+            newargv[1] = my_context->bashpath;
+            for(int i=0; i<my_context->argc; ++i)
+                newargv[i+2] = my_context->argv[i];
+            ret = execvp(newargv[0], (char * const*)newargv);
         } else {
             const char** newargv = (const char**)box_calloc(my_context->argc+1, sizeof(char*));
             for(int i=0; i<my_context->argc; ++i)
                 newargv[i] = my_context->argv[i];
-            FreeBox64Context(&my_context);
-            return execvp(newargv[0], (char * const*)newargv);
+            ret = execvp(newargv[0], (char * const*)newargv);
         }
-        printf_log(LOG_NONE, "Failed to execvp: error is %s\n", strerror(errno));
+        free_contextargv();
+        FreeBox64Context(&my_context);
+        return ret;
     }
     AddElfHeader(my_context, elf_header);
 
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index effef36c..df4e120b 100755
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -1687,18 +1687,21 @@ EXPORT int32_t my_execv(x64emu_t* emu, const char* path, char* const argv[])
     int self = isProcSelf(path, "exe");
     int x64 = FileIsX64ELF(path);
     int x86 = my_context->box86path?FileIsX86ELF(path):0;
-    printf_log(LOG_DEBUG, "execv(\"%s\", %p) is x64=%d x86=%d self=%d\n", path, argv, x64, x86, self);
+    int script = (my_context->bashpath && FileIsShell(path))?1:0;
+    printf_log(LOG_DEBUG, "execv(\"%s\", %p) is x64=%d x86=%d script=%d self=%d\n", path, argv, x64, x86, script, self);
     #if 1
-    if (x64 || x86 || self) {
+    if (x64 || x86 || script || self) {
         int skip_first = 0;
         if(strlen(path)>=strlen("wine64-preloader") && strcmp(path+strlen(path)-strlen("wine64-preloader"), "wine64-preloader")==0)
             skip_first++;
         // count argv...
         int n=skip_first;
         while(argv[n]) ++n;
-        const char** newargv = (const char**)box_calloc(n+2, sizeof(char*));
+        int toadd = script?2:1;
+        const char** newargv = (const char**)box_calloc(n+toadd+1, sizeof(char*));
         newargv[0] = x86?emu->context->box86path:emu->context->box64path;
-        memcpy(newargv+1, argv+skip_first, sizeof(char*)*(n+1));
+        if(script) newargv[1] = emu->context->bashpath; // script needs to be launched with bash
+        memcpy(newargv+toadd, argv+skip_first, sizeof(char*)*(n+toadd));
         if(self) newargv[1] = emu->context->fullpath; else newargv[1] = skip_first?argv[skip_first]:path;
         printf_log(LOG_DEBUG, " => execv(\"%s\", %p [\"%s\", \"%s\", \"%s\"...:%d])\n", newargv[0], newargv, newargv[0], n?newargv[1]:"", (n>1)?newargv[2]:"",n);
         char** envv = NULL;
@@ -1722,7 +1725,7 @@ EXPORT int32_t my_execve(x64emu_t* emu, const char* path, char* const argv[], ch
     int self = isProcSelf(path, "exe");
     int x64 = FileIsX64ELF(path);
     int x86 = my_context->box86path?FileIsX86ELF(path):0;
-    int script = (box64_bash && FileIsShell(path))?1:0;
+    int script = (my_context->bashpath && FileIsShell(path))?1:0;
     printf_log(LOG_DEBUG, "execve(\"%s\", %p, %p) is x64=%d x86=%d script=%d (my_context->envv=%p, environ=%p\n", path, argv, envp, x64, x86, script, my_context->envv, environ);
     // hack to update the environ var if needed
     if(envp == my_context->envv && environ) {
@@ -1739,7 +1742,7 @@ EXPORT int32_t my_execve(x64emu_t* emu, const char* path, char* const argv[], ch
         int toadd = script?2:1;
         const char** newargv = (const char**)box_calloc(n+1+toadd, sizeof(char*));
         newargv[0] = x86?emu->context->box86path:emu->context->box64path;
-        if(script) newargv[1] = emu->context->fullpath; // script needs to be launched with bash
+        if(script) newargv[1] = emu->context->bashpath; // script needs to be launched with bash
         memcpy(newargv+toadd, argv+skip_first, sizeof(char*)*(n+toadd));
         if(self) newargv[toadd] = emu->context->fullpath;
         printf_log(LOG_DEBUG, " => execve(\"%s\", %p [\"%s\", \"%s\", \"%s\"...:%d], %p)\n", newargv[0], newargv, newargv[0], (n+toadd)?newargv[1]:"", ((n+toadd)>1)?newargv[2]:"",n, envp);
@@ -1768,18 +1771,21 @@ EXPORT int32_t my_execvp(x64emu_t* emu, const char* path, char* const argv[])
     // use fullpath...
     int self = isProcSelf(fullpath, "exe");
     int x64 = FileIsX64ELF(fullpath);
-    int x86 = my_context->box86path?FileIsX86ELF(path):0;
+    int x86 = my_context->box86path?FileIsX86ELF(fullpath):0;
+    int script = (my_context->bashpath && FileIsShell(fullpath))?1:0;
     printf_log(LOG_DEBUG, "execvp(\"%s\", %p), IsX86=%d / fullpath=\"%s\"\n", path, argv, x64, fullpath);
-    box_free(fullpath);
-    if (x64 || x86 || self) {
+    if (x64 || x86 || script || self) {
         // count argv...
         int i=0;
         while(argv[i]) ++i;
-        char** newargv = (char**)box_calloc(i+2, sizeof(char*));
+        int toadd = script?2:1;
+        char** newargv = (char**)box_calloc(i+toadd+1, sizeof(char*));
         newargv[0] = x86?emu->context->box86path:emu->context->box64path;
+        if(script) newargv[1] = emu->context->bashpath; // script needs to be launched with bash
         for (int j=0; j<i; ++j)
-            newargv[j+1] = argv[j];
+            newargv[j+toadd] = argv[j];
         if(self) newargv[1] = emu->context->fullpath;
+        if(script) newargv[2] = fullpath;
         printf_log(LOG_DEBUG, " => execvp(\"%s\", %p [\"%s\", \"%s\"...:%d])\n", newargv[0], newargv, newargv[1], i?newargv[2]:"", i);
         char** envv = NULL;
         if(my_environ!=my_context->envv) envv = my_environ;
@@ -1791,6 +1797,7 @@ EXPORT int32_t my_execvp(x64emu_t* emu, const char* path, char* const argv[])
         else
             ret = execvp(newargv[0], newargv);
         box_free(newargv);
+    box_free(fullpath);
         return ret;
     }
     if((!strcmp(path + strlen(path) - strlen("/uname"), "/uname") || !strcmp(path, "uname"))
@@ -1812,14 +1819,17 @@ EXPORT int32_t my_execl(x64emu_t* emu, const char* path)
     int self = isProcSelf(path, "exe");
     int x64 = FileIsX64ELF(path);
     int x86 = my_context->box86path?FileIsX86ELF(path):0;
+    int script = (my_context->bashpath && FileIsShell(path))?1:0;
     printf_log(LOG_DEBUG, "execl(\"%s\", ...), IsX86=%d, self=%d\n", path, x64, self);
     // count argv...
     int i=0;
     while(getVargN(emu, i+1)) ++i;
-    char** newargv = (char**)box_calloc(i+((x64 || self)?2:1), sizeof(char*));
+    int toadd = script?2:((x64||self)?1:0);
+    char** newargv = (char**)box_calloc(i+toadd+1, sizeof(char*));
     int j=0;
-    if ((x64 || x86 || self))
+    if ((x64 || x86 || script || self))
         newargv[j++] = x86?emu->context->box86path:emu->context->box64path;
+    if(script) newargv[j++] = emu->context->bashpath;
     for (int k=0; k<i; ++k)
         newargv[j++] = getVargN(emu, k+1);
     if(self) newargv[1] = emu->context->fullpath;
@@ -1836,19 +1846,22 @@ EXPORT int32_t my_execlp(x64emu_t* emu, const char* path)
     // use fullpath...
     int self = isProcSelf(fullpath, "exe");
     int x64 = FileIsX64ELF(fullpath);
-    int x86 = my_context->box86path?FileIsX86ELF(path):0;
+    int x86 = my_context->box86path?FileIsX86ELF(fullpath):0;
+    int script = (my_context->bashpath && FileIsShell(fullpath))?1:0;
     printf_log(LOG_DEBUG, "execlp(\"%s\", ...), IsX86=%d / fullpath=\"%s\"\n", path, x64, fullpath);
-    box_free(fullpath);
     // count argv...
     int i=0;
     while(getVargN(emu, i+1)) ++i;
-    char** newargv = (char**)box_calloc(i+((x64 || self)?2:1), sizeof(char*));
+    int toadd = script?2:((x64||self)?1:0);
+    char** newargv = (char**)box_calloc(i+toadd+1, sizeof(char*));
     int j=0;
-    if ((x64 || x86 || self))
+    if ((x64 || x86 || script || self))
         newargv[j++] = x86?emu->context->box86path:emu->context->box64path;
+    if(script) newargv[j++] = emu->context->bashpath;
     for (int k=0; k<i; ++k)
         newargv[j++] = getVargN(emu, k+1);
     if(self) newargv[1] = emu->context->fullpath;
+    if(script) newargv[2] = fullpath;
     printf_log(LOG_DEBUG, " => execlp(\"%s\", %p [\"%s\", \"%s\"...:%d])\n", newargv[0], newargv, newargv[1], i?newargv[2]:"", i);
     char** envv = NULL;
     if(my_environ!=my_context->envv) envv = my_environ;
@@ -1860,6 +1873,7 @@ EXPORT int32_t my_execlp(x64emu_t* emu, const char* path)
     else
         ret = execvp(newargv[0], newargv);
     box_free(newargv);
+    box_free(fullpath);
     return ret;
 }
 
@@ -1869,15 +1883,18 @@ EXPORT int32_t my_posix_spawn(x64emu_t* emu, pid_t* pid, const char* fullpath,
     int self = isProcSelf(fullpath, "exe");
     int x64 = FileIsX64ELF(fullpath);
     int x86 = my_context->box86path?FileIsX86ELF(fullpath):0;
+    int script = (my_context->bashpath && FileIsShell(fullpath))?1:0;
     printf_log(/*LOG_DEBUG*/LOG_INFO, "posix_spawn(%p, \"%s\", %p, %p, %p, %p), IsX86=%d\n", pid, fullpath, actions, attrp, argv, envp, x64);
-    if (x64 || x86 || self) {
+    if (x64 || x86 || script || self) {
         // count argv...
         int i=0;
         while(argv[i]) ++i;
-        char** newargv = (char**)box_calloc(i+2, sizeof(char*));
+        int toadd = script?2:1;
+        char** newargv = (char**)box_calloc(i+toadd+1, sizeof(char*));
         newargv[0] = x86?emu->context->box86path:emu->context->box64path;
+        if(script) newargv[1] = emu->context->bashpath; // script needs to be launched with bash
         for (int j=0; j<i; ++j)
-            newargv[j+1] = argv[j];
+            newargv[j+toadd] = argv[j];
         if(self) newargv[1] = emu->context->fullpath;
         printf_log(/*LOG_DEBUG*/LOG_INFO, " => posix_spawn(%p, \"%s\", %p, %p, %p [\"%s\", \"%s\"...:%d], %p)\n", pid, newargv[0], actions, attrp, newargv, newargv[1], i?newargv[2]:"", i, envp);
         int ret = posix_spawn(pid, newargv[0], actions, attrp, newargv, envp);
@@ -1899,25 +1916,30 @@ EXPORT int32_t my_posix_spawnp(x64emu_t* emu, pid_t* pid, const char* path,
     int self = isProcSelf(fullpath, "exe");
     int x64 = FileIsX64ELF(fullpath);
     int x86 = my_context->box86path?FileIsX86ELF(path):0;
+    int script = (my_context->bashpath && FileIsShell(fullpath))?1:0;
+    int ret;
     printf_log(/*LOG_DEBUG*/LOG_INFO, "posix_spawnp(%p, \"%s\", %p, %p, %p, %p), IsX86=%d / fullpath=\"%s\"\n", pid, path, actions, attrp, argv, envp, x64, fullpath);
-    box_free(fullpath);
-    if (x64 || x86 || self) {
+    if (x64 || x86 || script || self) {
         // count argv...
         int i=0;
         while(argv[i]) ++i;
-        char** newargv = (char**)box_calloc(i+2, sizeof(char*));
+        int toadd = script?2:1;
+        char** newargv = (char**)box_calloc(i+toadd+1, sizeof(char*));
         newargv[0] = x86?emu->context->box86path:emu->context->box64path;
+        if(script) newargv[1] = emu->context->bashpath; // script needs to be launched with bash
         for (int j=0; j<i; ++j)
             newargv[j+1] = argv[j];
         if(self) newargv[1] = emu->context->fullpath;
+        if(script) newargv[2] = fullpath;
         printf_log(/*LOG_DEBUG*/LOG_INFO, " => posix_spawnp(%p, \"%s\", %p, %p, %p [\"%s\", \"%s\"...:%d], %p)\n", pid, newargv[0], actions, attrp, newargv, newargv[1], i?newargv[2]:"", i, envp);
-        int ret = posix_spawnp(pid, newargv[0], actions, attrp, newargv, envp);
+        ret = posix_spawnp(pid, newargv[0], actions, attrp, newargv, envp);
         printf_log(/*LOG_DEBUG*/LOG_INFO, "posix_spawnp returned %d\n", ret);
+        box_free(fullpath);
         //box_free(newargv);
-        return ret;
-    }
-    // fullpath is gone, so the search will only be on PATH, not on BOX64_PATH (is that an issue?)
-    return posix_spawnp(pid, path, actions, attrp, argv, envp);
+    } else
+        ret = posix_spawnp(pid, path, actions, attrp, argv, envp);
+    box_free(fullpath);
+    return ret;
 }
 
 EXPORT void my__Jv_RegisterClasses() {}