2

I am calling an executable from another executable in android Linux. Following is the relevant code:

...
int status = system("/system/bin/executable");
...

My requirement is not to wait for the executable to complete its execution. Means I want to run executable independent of the executable that calls it.

I have searched over the internet and didn't find how to make this system call non-blocking. Please help me to resolve it.

Vatish Sharma
  • 1,536
  • 3
  • 16
  • 35
  • 7
    Use `fork()` and then `exec()` in the child process. See e.g. "[How do fork and exec work?](//unix.stackexchange.com/q/179604)" as well as [a few other questions here](https://duckduckgo.com/?q=site%3Aunix.stackexchange.com+fork+exec&atb=v142-1&ia=web) – Kusalananda Jun 25 '19 at 13:26
  • 1
    You do it as in shell. Add a `&` at the end of the command: `system("/system/bin/executable &");`. Of course, you won't able to retrieve the status of your executable in that case. –  Jun 25 '19 at 13:39
  • 2
    @mosvy with `fork` and `exec` you can retrieve the status with `wait`. – ctrl-alt-delor Jun 25 '19 at 14:18
  • 1
    @ctrl-alt-delor and if you don't wait, you create zombies. Seriously, `system(3)` is already doing a fork + exec + wait, it just takes most of the complications off the user's back. –  Jun 25 '19 at 14:22
  • 2
    @mosvy I agree, if what you want to do is within what it dose (running in background and collecting status is not). I have not done C for a while, but I assume there are other libraries that abstract `fork` and `exec`, but are more powerful that `system`. – ctrl-alt-delor Jun 25 '19 at 14:29
  • 2
    Yeah, `popen(3)`. `FILE *p = popen("command >/dev/null", "r"); ... do other stuff ...; exit_status = pclose(p);` ;-) –  Jun 25 '19 at 14:32
  • Likely a duplicate of https://stackoverflow.com/questions/1002513/non-blocking-version-of-system I'm not voting to close as a dupe just yet, as that would close it immediately. – Andrew Henle Jun 26 '19 at 12:17

2 Answers2

5

The system() function, without error handling, looks like this:

int system(char const *cmdline)
{
    pid_t pid = fork();
    if(pid == 0)
    {
        char const *argv[] = { "sh", "-c", cmdline, NULL };
        execve("/bin/sh", argv, NULL);
        _exit(1);
    }
    else
    {
        int status;
        waitpid(pid, &status, 0);
        return status;
    }
}

The command itself is parsed by the shell, so you can use the normal & suffix to send the command into the background. The shell then terminates immediately, the background program is reparented to PID 1 (so your program isn't responsible for collecting the zombie), and system() returns.

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
1

I am able to achieve non-blocking with following code:

if (fork() == 0)
        {
            char *args[] = {..., NULL};
            char *env[] = {..., NULL};
            if (execve("/system/bin/executable", args, env) == -1)
                print("Error: [%d]", errno);
        }

There are few importants thing here:

  • fork() will create a new process. So from line if(fork() == 0), there will be 2 process running in the same space of main program.
  • Both processes continue executing from the point where the fork( ) calls returns execution to the main program..
  • fork() == 0 will let only child process in the if condition.
  • execve(..) will replace child process program(which is its parent program from which it copied by fork command) with /system/bin/executable.
  • execve(..) will not return if it get success in runing the executable else return -1.
  • In case of execve(..) failure the errno will be filled with the actual error.

Please correct me if I am wrong. I hope it will help someone.

Vatish Sharma
  • 1,536
  • 3
  • 16
  • 35
  • you should collect `fork()`ed pid, in case you intend to wait for it latter on. – Archemar Jun 26 '19 at 12:56
  • consider what happens after the execve() failed and you printed that error message. You'll also have to install an `SIGCHLD` handler and wait for the child, in order to not turn it into a zombie. –  Jun 27 '19 at 04:06
  • @Archemar my `executable` is an independent program and wait is not required by the parent process. – Vatish Sharma Jun 27 '19 at 05:21
  • @Archemar I think appending the `&` suffix is fine in my case. As it will handle the zombie process for me. Thanks to @Simon for its explanation. – Vatish Sharma Jun 27 '19 at 05:22