+/*
+ * execve_shell - Execute a shell with execve, or interpret it with
+ * /bin/sh
+ */
+static void execve_shell (const char *shellstr,
+ char *args[],
+ char *const envp[])
+{
+ int err;
+ (void) execve (shellstr, (char **) args, envp);
+ err = errno;
+
+ if (access (shellstr, R_OK|X_OK) == 0) {
+ /*
+ * Assume this is a shell script (with no shebang).
+ * Interpret it with /bin/sh
+ */
+ size_t n_args = 0;
+ char **targs;
+ while (NULL != args[n_args]) {
+ n_args++;
+ }
+ targs = (char **) xmalloc ((n_args + 3) * sizeof (args[0]));
+ targs[0] = "sh";
+ targs[1] = "-";
+ targs[2] = xstrdup (shellstr);
+ targs[n_args+2] = NULL;
+ while (1 != n_args) {
+ targs[n_args+1] = args[n_args - 1];
+ n_args--;
+ }
+
+ (void) execve (SHELL, targs, envp);
+ } else {
+ errno = err;
+ }
+}