This is the lesson your shell stops being a parser and starts being a shell - it launches a real program. You spawn a child process, run the named executable in it, and wait for it to finish.
Given a word list, run the named program in a child process and wait for it to complete.
To run a program, a Unix shell does something that looks strange the first time:
it clones itself. The fork call makes a copy of the shell process; the copy
(the child) then execs - it throws away the shell’s code and replaces
itself with the program you asked for, keeping the same open files. The original
(the parent) stays behind and waits for the child to finish. This
fork-then-exec dance is the single most important mechanic in the whole project.
Notice that exec only returns if it failed - on success there is no shell code
left in the child to return to. So the line right after exec is your
error-and-give-up path. For today, name programs by their full path
(/bin/echo); teaching the shell to find echo on its own comes in a few lessons.
pid_t pid = fork();if (pid == 0) { // childexecv(words[0], words); // replace this process with the programperror(words[0]); // only reached if exec fails_exit(127);}waitpid(pid, &status, 0); // parent waits