execve с поиском пути? - PullRequest
       29

execve с поиском пути?

4 голосов
/ 17 октября 2011

Я хочу выполнить программу из моего кода и предоставить ей переменные окружения и аргументы.AFAICT, execve - правильный выбор.

Но execve получает аргумент path, а не filename, то есть он ожидает, что первый аргумент будет путем к исполняемому файлу.

Я знаю, что могу разобрать $PATH сам, чтобы найти путь, но на самом деле, нет другого выбора?Никто другой не реализовал это где-нибудь для меня, чтобы использовать?

1 Ответ

8 голосов
/ 17 октября 2011

Некоторые системы могут предоставлять execvpe().Поиск в Google по запросу «execvpe» показывает множество вариантов, включая, по крайней мере, одну реализацию (значительно более сложную, чем то, что следует, но включает в себя большую часть execvp() в своем собственном коде).

Для тех, кто это делаетнет, вы можете предоставить это для себя:

int execvpe(const char *program, char **argv, char **envp)
{
    char **saved = environ;
    int rc;
    environ = envp;
    rc = execvp(program, argv);
    environ = saved;
    return rc;
}

Вы, вероятно, могли бы выжить без rc (просто принудительно возвращая -1), поскольку execvp() только когда-либо возвращает -1 (и это только когда-либо возвращается наошибка).

Возможно, вам даже не нужно беспокоиться о безопасности потоков в этом коде.Обычный сценарий, который будет использовать его, это сразу после fork(), и в этот момент в процессе есть только один поток.Если вы думаете, что можете использовать его, когда вокруг несколько потоков, то вам нужно довольно тщательно подумать о том, безопасно ли изменять глобальную среду даже кратко.Ясно, что если execvp() завершится успешно, проблем не будет (все потоки будут внезапно прерваны).Если произойдет сбой execvp(), возможно, один из других потоков увидит измененную среду и на основании этого может принять неверные решения.В этом случае вам необходимо надлежащим образом защитить окружающую среду (и это, вероятно, предполагает (взаимное исключение) блокировку в getenv(), setenv() и putenv(), а также в execvpe()).

(Реализация execvpe(), которую я обнаружил, позволяет избежать проблем с безопасностью потоков благодаря реализации логики execvp() и последующему использованию execve() для выполнения программы.)

Обычно, если execvpe() возвращается, процесс будетвыход, поэтому очень часто восстановление среды не повлияет на программу.Тем не менее, это лучше, чем потом сожалеть.

...