Как разблокировать функцию system ()? - PullRequest
1 голос
/ 25 июня 2019

Я вызываю исполняемый файл из другого исполняемого файла в Android Linux.Ниже приведен соответствующий код:

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

Мое требование - не ждать, пока executable завершит свое выполнение.Означает, что я хочу запустить executable независимо от исполняющего файла, который его вызывает.

Я искал в Интернете и не нашел, как сделать этот системный вызов неблокирующим.Пожалуйста, помогите мне решить эту проблему.

Ответы [ 2 ]

5 голосов
/ 26 июня 2019

Функция system() без обработки ошибок выглядит следующим образом:

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;
    }
}

Сама команда анализируется оболочкой, поэтому вы можете использовать обычный суффикс & для отправки команды в фоновый режим. Затем оболочка немедленно завершает работу, фоновая программа переопределяется в PID 1 (поэтому ваша программа не отвечает за сбор зомби), и system() возвращает.

1 голос
/ 26 июня 2019

Я могу добиться неблокирования с помощью следующего кода:

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

Здесь есть несколько важных вещей:

  • fork() создаст новый процесс.Таким образом, из строки if(fork() == 0) в одном и том же пространстве основной программы будут выполняться 2 процесса.
  • Оба процесса продолжают выполняться с того момента, когда вызовы fork () возвращают выполнение основной программе.
  • fork() == 0 разрешит только дочерний процесс в условии if.
  • execve(..) заменит дочернюю программу процесса (которая является его родительской программой, из которой он скопирован командой fork) /system/bin/executable.
  • execve(..) не вернется, если он успешно выполнит исполняемый файл, иначе вернет -1.
  • В случае сбоя execve(..) errno будет заполнено фактической ошибкой.

Пожалуйста, поправьте меня, если я ошибаюсь.Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...