Как я могу получить возвращаемое значение / bin / ls -R, если я запускаю его с помощью execl ()?
Если вы правильно wait()
(см. Нижнюю часть моего ответа) ) тогда вы получаете возвращаемое значение /bin/ls -R
.
, которое не может быть 0
Не уверен, что вы подразумеваете под этим , но состояние выхода 0
означает, что процесс завершился правильно. Что-то отличное от 0
означает, что произошла ошибка, поэтому вы обычно хотите, чтобы все завершалось с 0
, а не с чем-то другим.
Семейство функций exec*()
не возвращается при успешном выполнении. Прочтите страницу руководства , чтобы узнать больше.
Если вы хотите, чтобы ребенок потерпел неудачу, то передайте неверный путь к execl
, чтобы он потерпел неудачу, или просто return 1
сразу. Чтобы заставить ls -R
возвращать что-то отличное от 0
, вы можете передать третий аргумент execl()
, указывающий путь, к которому у вас нет доступа, как, например, /root
.
Я также не совсем уверен, что не так с вашим кодом, поскольку он компилируется и работает правильно на моей машине, , но , вот несколько практических правил, которым нужно следовать, чтобы найти проблему и избежать это в первую очередь:
Всегда читайте руководство (в данном случае man 2 wait
):
If wstatus is not NULL, wait() and waitpid() store status information in the int to which it points. This
integer can be inspected with the following macros (which take the integer itself as an argument, not a
pointer to it, as is done in wait() and waitpid()!):
WIFEXITED(wstatus)
returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by return‐
ing from main().
WEXITSTATUS(wstatus)
returns the exit status of the child. This consists of the least significant 8 bits of the status
argument that the child specified in a call to exit(3) or _exit(2) or as the argument for a return
statement in main(). This macro should be employed only if WIFEXITED returned true.
Всегда проверяйте наличие ошибок в функциях, которые могут не работать. Подсказка: в основном 99% системных вызовов могут дать сбой, fork
и wait
- некоторые из них.
pid_t child_pid = fork();
if (child_pid == -1) {
perror("fork() failed");
return 1;
}
// ...
pid_t res = wait(&child_status);
if (res != child_pid) {
perror("wait() failed");
return 1;
}
Всегда компилировать включающие предупреждения: gcc -Wall -Wextra -pedantic
.
Применение приведенных выше правил в большинстве случаев - все, что вам нужно, чтобы выяснить, в чем проблема. Вот рабочая версия вашей программы после их применения:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void) {
pid_t child_pid, res;
int child_status;
child_pid = fork();
if (child_pid == -1) {
perror("fork() failed");
return 1;
}
if(child_pid == 0) {
sleep(123);
execl("/bin/ls", "-R", NULL);
perror("execl() failed");
exit(1);
}
res = wait(&child_status);
if (res != child_pid) {
perror("wait() failed");
return 1;
}
if (WIFEXITED(child_status))
printf("Child exited with status %d.\n", WEXITSTATUS(child_status));
else if (WIFSIGNALED(child_status))
printf("Child killed by signal %d.\n", WTERMSIG(child_status));
else {
puts("This should never happen! Something's really wrong.");
return 1;
}
return 0;
}