diff --git a/function.c b/function.c
index 72ecb7f..7884f83 100644
--- a/function.c
+++ b/function.c
@@ -1710,29 +1710,12 @@ func_shell_base (char *o, char **argv, int trim_newlines)
       return o;
     }
 
-# ifdef __EMX__
   /* close some handles that are unnecessary for the child process */
   CLOSE_ON_EXEC(pipedes[1]);
   CLOSE_ON_EXEC(pipedes[0]);
-  /* Never use fork()/exec() here! Use spawn() instead in exec_command() */
   pid = child_execute_job (FD_STDIN, pipedes[1], errfd, command_argv, envp);
   if (pid < 0)
-    perror_with_name (error_prefix, "spawn");
-# else /* ! __EMX__ */
-  pid = fork ();
-  if (pid < 0)
-    perror_with_name (error_prefix, "fork");
-  else if (pid == 0)
-    {
-#  ifdef SET_STACK_SIZE
-      /* Reset limits, if necessary.  */
-      if (stack_limit.rlim_cur)
-       setrlimit (RLIMIT_STACK, &stack_limit);
-#  endif
-      child_execute_job (FD_STDIN, pipedes[1], errfd, command_argv, envp);
-    }
-  else
-# endif
+    perror_with_name (error_prefix, "child_execute_job");
 #endif
     {
       /* We are the parent.  */
diff --git a/job.c b/job.c
index e4a40ac..9cf5c58 100644
--- a/job.c
+++ b/job.c
@@ -1426,9 +1426,6 @@ start_job_command (struct child *child)
 #endif /* !VMS */
     {
       /* Fork the child process.  */
-
-      char **parent_environ;
-
     run_local:
       block_sigs ();
 
@@ -1444,8 +1441,6 @@ start_job_command (struct child *child)
 
 #else
 
-      parent_environ = environ;
-
 #ifndef NO_OUTPUT_SYNC
       /* Divert child output if output_sync in use.  */
       if (child->output.syncout)
@@ -1456,7 +1451,6 @@ start_job_command (struct child *child)
             errfd = child->output.err;
         }
 #endif
-# ifdef __EMX__
       /* If we aren't running a recursive command and we have a jobserver
          pipe, close it before exec'ing.  */
       if (!(flags & COMMANDS_RECURSE) && job_fds[0] >= 0)
@@ -1467,19 +1461,11 @@ start_job_command (struct child *child)
       if (job_rfd >= 0)
         CLOSE_ON_EXEC (job_rfd);
 
-      /* Never use fork()/exec() here! Use spawn() instead in exec_command() */
       child->pid = child_execute_job (child->good_stdin ? FD_STDIN : bad_stdin,
                                       outfd, errfd,
                                       argv, child->environment);
-      if (child->pid < 0)
-        {
-          /* spawn failed!  */
-          unblock_sigs ();
-          perror_with_name ("spawn", "");
-          goto error;
-        }
 
-      /* undo CLOSE_ON_EXEC() after the child process has been started */
+      /* undo FD_CLOEXEC after the child process has been started */
       if (!(flags & COMMANDS_RECURSE) && job_fds[0] >= 0)
         {
           fcntl (job_fds[0], F_SETFD, 0);
@@ -1488,41 +1474,13 @@ start_job_command (struct child *child)
       if (job_rfd >= 0)
         fcntl (job_rfd, F_SETFD, 0);
 
-#else  /* !__EMX__ */
-
-      child->pid = fork ();
-      environ = parent_environ; /* Restore value child may have clobbered.  */
-      if (child->pid == 0)
-        {
-          /* We are the child side.  */
-          unblock_sigs ();
-
-          /* If we aren't running a recursive command and we have a jobserver
-             pipe, close it before exec'ing.  */
-          if (!(flags & COMMANDS_RECURSE) && job_fds[0] >= 0)
-            {
-              close (job_fds[0]);
-              close (job_fds[1]);
-            }
-          if (job_rfd >= 0)
-            close (job_rfd);
-
-#ifdef SET_STACK_SIZE
-          /* Reset limits, if necessary.  */
-          if (stack_limit.rlim_cur)
-            setrlimit (RLIMIT_STACK, &stack_limit);
-#endif
-          child_execute_job (child->good_stdin ? FD_STDIN : bad_stdin,
-                             outfd, errfd, argv, child->environment);
-        }
-      else if (child->pid < 0)
+      if (child->pid < 0)
         {
-          /* Fork failed!  */
+          /* child process startup failed!  */
           unblock_sigs ();
-          perror_with_name ("fork", "");
+          perror_with_name ("child_execute_job", "");
           goto error;
         }
-# endif  /* !__EMX__ */
 #endif /* !VMS */
     }
 
@@ -2195,15 +2153,15 @@ start_waiting_jobs (void)
   return;
 }
 
-#ifndef WINDOWS32
+#if !defined (WINDOWS32) && !defined (_AMIGA) && !defined (__MSDOS__) && !defined (VMS)
 
-/* EMX: Start a child process. This function returns the new pid.  */
-# if defined __EMX__
-int
+/* Start a child process. This function returns the new pid.  */
+pid_t
 child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
                    char **argv, char **envp)
 {
-  int pid;
+  pid_t pid;
+# if defined __EMX__
   int save_stdin = -1;
   int save_stdout = -1;
   int save_stderr = -1;
@@ -2277,42 +2235,43 @@ child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
       else
         close (save_stderr);
     }
+#else
+  pid = fork ();
+  if (pid == 0)
+    {
+      /* We are the child side.  */
+      unblock_sigs ();
 
-  return pid;
-}
-
-#elif !defined (_AMIGA) && !defined (__MSDOS__) && !defined (VMS)
+#ifdef SET_STACK_SIZE
+      /* Reset limits, if necessary.  */
+      if (stack_limit.rlim_cur)
+        setrlimit (RLIMIT_STACK, &stack_limit);
+#endif
 
-/* UNIX:
-   Replace the current process with one executing the command in ARGV.
-   STDIN_FD/STDOUT_FD/STDERR_FD are used as the process's stdin/stdout/stderr;
-   ENVP is the environment of the new program.  This function does not return.  */
-void
-child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
-                   char **argv, char **envp)
-{
-  /* For any redirected FD, dup2() it to the standard FD then close it.  */
-  if (stdin_fd != FD_STDIN)
-    {
-      dup2 (stdin_fd, FD_STDIN);
-      close (stdin_fd);
-    }
+      /* For any redirected FD, dup2() it to the standard FD then close it.  */
+      if (stdin_fd != FD_STDIN)
+        {
+          dup2 (stdin_fd, FD_STDIN);
+          close (stdin_fd);
+        }
 
-  if (stdout_fd != FD_STDOUT)
-    dup2 (stdout_fd, FD_STDOUT);
-  if (stderr_fd != FD_STDERR)
-    dup2 (stderr_fd, FD_STDERR);
+      if (stdout_fd != FD_STDOUT)
+        dup2 (stdout_fd, FD_STDOUT);
+      if (stderr_fd != FD_STDERR)
+        dup2 (stderr_fd, FD_STDERR);
 
-  if (stdout_fd != FD_STDOUT)
-    close (stdout_fd);
-  if (stderr_fd != FD_STDERR && stderr_fd != stdout_fd)
-    close (stderr_fd);
+      if (stdout_fd != FD_STDOUT)
+        close (stdout_fd);
+      if (stderr_fd != FD_STDERR && stderr_fd != stdout_fd)
+        close (stderr_fd);
 
-  /* Run the command.  */
-  exec_command (argv, envp);
+      /* Run the command. This function does not return. */
+      exec_command (argv, envp);
+    }
+#endif
+  return pid;
 }
-#endif /* !AMIGA && !__MSDOS__ && !VMS */
-#endif /* !WINDOWS32 */
+#endif /* !WINDOWS32 && !AMIGA && !__MSDOS__ && !VMS */
 
 #ifndef _AMIGA
 /* Replace the current process with one running the command in ARGV,
@@ -2397,14 +2356,20 @@ exec_command (char **argv, char **envp)
 
 # ifdef __EMX__
   int pid;
+  char **parent_environ = environ;
 # endif
 
   /* Be the user, permanently.  */
   child_access ();
 
-# ifdef __EMX__
+  /* Set correct environment. This includes modified PATH, which allows execvp() or
+     spawnvpe() to actually locate the binary which can be placed in current directory. */
+  environ = envp;
+
   /* Run the program.  */
+# ifdef __EMX__
   pid = spawnvpe (P_NOWAIT, argv[0], argv, envp);
+  environ = parent_environ; /* Restore original environment */
   if (pid >= 0)
     return pid;
 
@@ -2413,8 +2378,6 @@ exec_command (char **argv, char **envp)
     errno = ENOEXEC;
 
 # else
-  /* Run the program.  */
-  environ = envp;
   execvp (argv[0], argv);
 
 # endif /* !__EMX__ */
diff --git a/job.h b/job.h
index 207fe89..6f461ef 100644
--- a/job.h
+++ b/job.h
@@ -126,13 +126,8 @@ int child_execute_job (char *argv, struct child *child);
 # define FD_STDIN       (fileno (stdin))
 # define FD_STDOUT      (fileno (stdout))
 # define FD_STDERR      (fileno (stderr))
-# if defined(__EMX__)
-int child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
+pid_t child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
                        char **argv, char **envp);
-# else
-void child_execute_job (int stdin_fd, int stdout_fd, int stderr_fd,
-                        char **argv, char **envp) __attribute__ ((noreturn));
-# endif
 #endif
 #ifdef _AMIGA
 void exec_command (char **argv) __attribute__ ((noreturn));
