Передача ключевой информации из комментариев в ответ.
Функция wait()
сообщает вам PID и статус выхода -Вы просто должны захватить их, а не игнорировать их. Вам нужно будет использовать WIFEXITED
и WEXITSTATUS
(и если WIFEXITED
сообщает false, есть другие макросы для сигналов и дампов ядра и т. Д.).
Изменение кода:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#ifndef LS_PATH
#define LS_PATH "/bin/ls"
#endif
int main(int argc, char **argv)
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s directory\n", argv[0]);
return 1;
}
pid_t pid = fork();
if (pid == 0)
{
char cwd[255];
printf("Current working directory: %s\n", getcwd(cwd, sizeof(cwd)));
printf("Executing 'ls -a -l' in %s\n", argv[1]);
if (chdir(argv[1]) != 0)
{
fprintf(stderr, "%s: %s is not a valid directory\n", argv[0], argv[1]);
return 1;
}
//execl(LS_PATH, "ls", "--all", "-l", "--human-readable", (char*) NULL);
execl(LS_PATH, "ls", "-a", "-l", (char*) NULL);
fprintf(stderr, "Failed to execute %s\n", LS_PATH);
return 1;
}
else
{
int status;
int corpse = wait(&status);
if (corpse < 0)
printf("Failed to wait for process %d (errno = %d)\n", (int)pid, errno);
else if (corpse != pid)
printf("Got corpse of process %d (status 0x%.4X) when expecting PID %d\n",
corpse, status, (int)pid);
else if (WIFEXITED(status))
printf("Process %d exited with normal status 0x%.4X (status %d = 0x%.2X)\n",
corpse, status, WEXITSTATUS(status), WEXITSTATUS(status));
else if (WIFSIGNALED(status))
printf("Process %d exited because of a signal 0x%.4X (signal %d = 0x%.2X)\n",
corpse, status, WTERMSIG(status), WTERMSIG(status));
else
printf("Process %d exited with status 0x%.4X which is %s\n",
corpse, status, "neither a normal exit nor the result of a signal");
}
return 0;
}
Я работаю на Mac, который не использует GNU ls
, поэтому я сделал код настраиваемым во время компиляции для местоположения ls
, и он использует только переносимые параметры (-a
и -l
а не опции двойной тире). Я изменил сообщение и обнаружил еще несколько ошибок. Как и ваш код, предполагается, что fork()
не дает сбоя - он также должен проверять наличие ошибки там.
Пример вывода (сокращенно) - из программы es61
, скомпилированной из es61.c
:
$ es61 /orthography
Current working directory: /Users/jonathanleffler/soq
Executing 'ls -a -l' in /orthography
es61: /orthography is not a valid directory
Process 64463 exited with normal status 0x0100 (status 1 = 0x01)
$ es61 $PWD
Current working directory: /Users/jonathanleffler/soq
Executing 'ls -a -l' in /Users/jonathanleffler/soq
total 1016
drwxr-xr-x 100 jonathanleffler staff 3200 Oct 31 15:53 .
drwxr-xr-x+ 69 jonathanleffler staff 2208 Oct 31 15:53 ..
…
-rwxr-xr-x 1 jonathanleffler staff 9028 Oct 31 15:53 es61
-rw-r--r-- 1 jonathanleffler staff 1806 Oct 31 15:53 es61.c
drwxr-xr-x 3 jonathanleffler staff 96 Oct 31 15:43 es61.dSYM
drwxr-xr-x 9 jonathanleffler staff 288 Nov 5 2018 etc
…
-rw-r--r-- 1 jonathanleffler staff 390 Nov 16 2017 makefile
…
Process 64557 exited with normal status 0x0000 (status 0 = 0x00)
$