Based on: https://github.com/mysql/mysql-server/commit/39193238c7d004eb5f17d0ee8332490bfc615cf1

Author: Dharanendiran <dharanendiran@timesys.com>
Date: Tue, 26 Sep 2023 23:01:50 +0530

---
 client/mysql_install_db.cc | 76 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/client/mysql_install_db.cc b/client/mysql_install_db.cc
index 28e4eaab..98a6e0c8 100644
--- a/client/mysql_install_db.cc
+++ b/client/mysql_install_db.cc
@@ -30,8 +30,10 @@
 #include <unistd.h>
 #include <pwd.h>
 #include <signal.h>
+#if !defined (__UCLIBC__)
 #include <spawn.h>
 #include <pthread.h>
+#endif
 #include <sys/types.h>
 #include <sys/wait.h>
 
@@ -1094,12 +1096,18 @@ bool process_execute(const string &exec, Fwd_iterator begin,
                        Fwd_iterator end, Reader_func_t reader,
                        Writer_func_t writer)
 {
+#if !defined (__UCLIBC__)
   pid_t child;
   bool retval= true;
+#else
+  int child;
+#endif
   int read_pipe[2];
   int write_pipe[2];
+#if !defined (__UCLIBC__)
   posix_spawn_file_actions_t spawn_action;
   char *execve_args[MAX_MYSQLD_ARGUMENTS];
+#endif
 
   /*
     Disable any signal handler for broken pipes and check for EPIPE during
@@ -1117,6 +1125,7 @@ bool process_execute(const string &exec, Fwd_iterator begin,
     return false;
   }
 
+#if !defined (__UCLIBC__)
   posix_spawn_file_actions_init(&spawn_action);
   /* target process std input (0) reads from our write_pipe */
   posix_spawn_file_actions_adddup2(&spawn_action, write_pipe[0], 0);
@@ -1198,6 +1207,73 @@ bool process_execute(const string &exec, Fwd_iterator begin,
   posix_spawn_file_actions_destroy(&spawn_action);
   free(local_filename);
   return retval;
+#else
+  child= vfork();
+  if (child == 0)
+  {
+    /*
+      We need to copy the strings or execve will fail with errno EFAULT
+    */
+    char *execve_args[MAX_MYSQLD_ARGUMENTS];
+    char *local_filename= strdup(exec.c_str());
+    execve_args[0]= local_filename;
+    int i= 1;
+    for(Fwd_iterator it= begin;
+        it!= end && i < MAX_MYSQLD_ARGUMENTS-1;)
+    {
+      execve_args[i]= strdup(const_cast<char *>((*it).c_str()));
+      ++it;
+      ++i;
+    }
+    execve_args[i]= 0;
+
+    /* Child */
+    if (dup2(read_pipe[0], STDIN_FILENO) == -1 ||
+        dup2(write_pipe[1], STDOUT_FILENO) == -1 ||
+        dup2(write_pipe[1], STDERR_FILENO) == -1)
+    {
+      return false;
+    }
+    ::close(read_pipe[0]);
+    ::close(read_pipe[1]);
+    ::close(write_pipe[0]);
+    ::close(write_pipe[1]);
+    char *const arg[]={(char *)NULL};
+    execve(local_filename, execve_args, arg);
+    /* always failure if we get here! */
+    error << "Child process exited with errno= " << errno << endl;
+    exit(1);
+  }
+  else if (child > 0)
+  {
+    /* Parent thread */
+    ::close(read_pipe[0]);
+    ::close(write_pipe[1]);
+    if (!writer(read_pipe[1]) || errno != 0)
+    {
+      error << "The child process terminated prematurely. "
+            << "Errno= " << errno
+            << endl;
+      if (errno != EPIPE)
+        reader(write_pipe[0]);
+      ::close(read_pipe[1]);
+      ::close(write_pipe[0]);
+      return false;
+    }
+    ::close(read_pipe[1]);
+    reader(write_pipe[0]);
+    ::close(write_pipe[0]);
+  }
+  else
+  {
+    /* Failure */
+    ::close(read_pipe[0]);
+    ::close(read_pipe[1]);
+    ::close(write_pipe[0]);
+    ::close(write_pipe[1]);
+  }
+  return true;
+#endif
 }
 
 int generate_password_file(Path &pwdfile, const string &adminuser,
-- 
2.25.1

