Two example outputs (provided by my professor) are (these are inputted in the Linux terminal):
ibrahim@ibrahim-latech:~$ ./prog2 .
Current working directory: /
Transferring key information from comments into an answer.
The wait() function tells you the PID and the exit status — you just have to capture them, not ignore them. You'll need to use WIFEXITED
and WEXITSTATUS
(and if WIFEXITED
reports false, there are other macros to use for signals and core dumps, etc).
Modifying your code:
#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;
}
I work on a Mac which doesn't use GNU ls
so I've made the code compile-time configurable for the location of ls
and it only uses portable options (-a
and -l
and not the double-dash options). I've changed the messaging and detected some more errors. Like your code, this assumes fork()
does not fail — it should check for an error there too.
Sample output (abbreviated) — from program es61
compiled from 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)
$