Не могу правильно запустить другие программы

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

void run() {
cout << "##Run" << endl;
pid_t process_id = fork();

if (process_id == 0) {
char* args[] = {  "sudo", "ls", "-l" };
auto i = execvp("sudo", args);
cout << "#Result: " << i << endl;
return;
} else if (process_id < 0) {
throw std::runtime_error("fork() failed");
} else if (process_id > 0) {
wait(&process_id);
}
return;
}

void run_decorator() {
cout << "###Run decorator: " << endl;
run();
}

int main() {
run();
run_decorator();
return 0;
}

И вывод

##Run
total 88
-rwxr-xr-x 1 bezik bezik 77560 Nov 29 19:53 colors
-rwxr-xr-x 1 bezik bezik    63 Nov 26 21:45 compile
drwxr-xr-x 2 bezik bezik  4096 Nov 26 20:46 headers
drwxr-xr-x 2 bezik bezik  4096 Nov 23 00:48 sources
###Run decorator:
##Run
#Result: -1

Может кто-нибудь объяснить мне, почему execvp не удалось при вызове из функции run_decorator ()?

2

Решение

Читать внимательно документация execvp (3). Это говорит о execl так далее…:

Первый аргумент, по соглашению, должен указывать на
имя файла, связанное с исполняемым файлом. Список
аргументы должен заканчиваться нулевым указателем, и, так как это
переменные функции, этот указатель должен быть приведен (char *) NULL,

и относительно execvp:

Массив указателей должен заканчиваться нулевым указателем.

Так что вы должны код:

char* args[] = {  "sudo", "ls", "-l",  NULL };
execvp("sudo", args);

КСТАТИ, execvp вообще не возвращайся, Кроме на провал. Не нужно сохранять свой результат после звонка.

Но вам нужно, когда execvp возвращает (и это происходит только при ошибке), чтобы показать какое-то сообщение об ошибке. Я предлагаю:

perror("execvp");
exit(EXIT_FAILURE);

и вы могли бы найти действительные аргументы для вызова, в этом конкретном случае, _exit (2) вместо выход (3). Я все еще предпочитаю exit (потому что это очистит буферы stdio и запустит atexit (3)-зарегистрированные обработчики).

Может кто-нибудь, пожалуйста, объясните мне, почему execvp не удалось

Да, ERRNO (3). Который используется PError (3).

Не забывай читать внимательно документация каждой используемой функции. Для системных вызовов (перечисленных в Системные вызовы (2)) и стандартные функции библиотеки C (см. интро (3)), как правило, вы должны обрабатывать случай сбоя (часто используя errnoпо крайней мере через perror затем exit)

Я не понимаю зачем тебе sudo с ls, Есть несколько случаев, когда это может быть полезно, так как большую часть времени ваш рабочий каталог в списке (тогда sudo бесполезно), и в этом случае вы могли бы даже использовать opendir (3), READDIR (3) с стат (2) (так что не надо fork затем execvp /bin/ls программа).

Читайте также о УИП методы в execve (2) а также Учетные данные (7) (а также setreuid (2)). Увидеть этот (вы могли бы избежать sudo с вашей собственной программой setuid).

Кстати, вы должны скомпилировать с все предупреждения и отладочная информация (g++ -Wall -Wextra -g с НКУ) а также использовать отладчик gdb (и, возможно Трассирование (1) а также Valgrind (1)).

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector