The value −1 can only be returned by system
if initial creation of a child process (via fork
) or collection of its exit status (via wait
) fails. Neither of these things can happen because of a problem with the command passed to system
, because the command is interpreted in the child process. Problems with the command will show up as system
returning a value s
that is not equal to either 0 or −1, and for which either WIFEXITED(s) && WEXITSTATUS(s) != 0
or WIFSIGNALED(s)
is true. (The macros WIFEXITED
, WIFSIGNALED
, and WEXITSTATUS
are defined in sys/wait.h
.) (See the POSIX specification for system
to understand why this happens.)
fork
failures typically only happen because of system-wide resource exhaustion and/or severe imposed resource quotas. For instance, this program prints
true: status=-1 errno=11 (Resource temporarily unavailable)
when I run it.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
int main(void)
{
struct rlimit rl;
rl.rlim_cur = 1;
rl.rlim_max = 1;
setrlimit(RLIMIT_NPROC, &rl);
int status = system("true");
printf("true: status=%d errno=%d (%s)\n", status, errno, strerror(errno));
return 0;
}
A wait
failure inside system
could happen if you have a SIGCHLD handler that steals the wait status. For instance, this program prints
true: status=-1 errno=10 (No child processes)
when I run it. (There are several other ways in which a SIGCHLD handler could interfere with system
; this is just the shortest demo program I could think of.)
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
int main(void)
{
signal(SIGCHLD, SIG_IGN);
int status = system("true");
printf("true: status=%d errno=%d (%s)\n", status, errno, strerror(errno));
return 0;
}
You said that whatever command you pass to system
does execute correctly but system
nonetheless returns −1, and that makes me think your problem is due to a bad interaction between wait
and a SIGCHLD
handler. Getting "No child processes" (ECHILD
) in errno
is consistent with this hypothesis, because wait
is documented to produce that error code, and fork
isn't. But it's just a hypothesis. To diagnose your problem any better than this, we need to see a complete test program that we can compile and run for ourselves and observe the exact same failure condition that you are. Please read and follow the instructions at https://stackoverflow.com/help/mcve .