+
+#ifdef HAVE_SYSTEM
+#ifdef HAVE_WAITPID
+
+
+SCM_DEFINE (scm_system_star, "system*", 0, 0, 1,
+ (SCM args),
+"Execute the command indicated by @var{args}. The first element must\n"
+"be a string indicating the command to be executed, and the remaining\n"
+"items must be strings representing each of the arguments to that\n"
+"command.\n"
+"\n"
+"This function returns the exit status of the command as provided by\n"
+"@code{waitpid}. This value can be handled with @code{status:exit-val}\n"
+"and the related functions.\n"
+"\n"
+"@code{system*} is similar to @code{system}, but accepts only one\n"
+"string per-argument, and performs no shell interpretation. The\n"
+"command is executed using fork and execlp. Accordingly this function\n"
+"may be safer than @code{system} in situations where shell\n"
+"interpretation is not required.\n"
+"\n"
+"Example: (system* \"echo\" \"foo\" \"bar\")")
+#define FUNC_NAME s_scm_system_star
+{
+ if (scm_is_null (args))
+ SCM_WRONG_NUM_ARGS ();
+
+ if (scm_is_pair (args))
+ {
+ SCM oldint;
+ SCM oldquit;
+ SCM sig_ign;
+ SCM sigint;
+ SCM sigquit;
+ int pid;
+ char **execargv;
+
+ /* allocate before fork */
+ execargv = scm_i_allocate_string_pointers (args);
+
+ /* make sure the child can't kill us (as per normal system call) */
+ sig_ign = scm_from_ulong ((unsigned long) SIG_IGN);
+ sigint = scm_from_int (SIGINT);
+ sigquit = scm_from_int (SIGQUIT);
+ oldint = scm_sigaction (sigint, sig_ign, SCM_UNDEFINED);
+ oldquit = scm_sigaction (sigquit, sig_ign, SCM_UNDEFINED);
+
+ pid = fork ();
+ if (pid == 0)
+ {
+ /* child */
+ execvp (execargv[0], execargv);
+ SCM_SYSERROR;
+ /* not reached. */
+ return SCM_BOOL_F;
+ }
+ else
+ {
+ /* parent */
+ int wait_result, status;
+
+ if (pid == -1)
+ SCM_SYSERROR;
+
+ SCM_SYSCALL (wait_result = waitpid (pid, &status, 0));
+ if (wait_result == -1)
+ SCM_SYSERROR;
+ scm_sigaction (sigint, SCM_CAR (oldint), SCM_CDR (oldint));
+ scm_sigaction (sigquit, SCM_CAR (oldquit), SCM_CDR (oldquit));
+
+ return scm_from_int (status);
+ }
+ }
+ else
+ SCM_WRONG_TYPE_ARG (1, args);
+}
+#undef FUNC_NAME
+#endif /* HAVE_WAITPID */
+#endif /* HAVE_SYSTEM */
+
+