Step 3: Built-in commands
Some commands cannot be separate programs. cd changes the shell's own current folder; if it ran in a child process, the change would vanish when the child exited. So cd, pwd and exit are built-ins handled inside the shell with system calls chdir and getcwd. Watch the folder change in the output.
ExampleC
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define MAX_ARGS 16
int tokenize(char *line, char *argv[]) {
int argc = 0;
char *p = line;
while (*p != '\0' && argc < MAX_ARGS - 1) {
while (*p == ' ') p++;
if (*p == '\0') break;
argv[argc++] = p;
while (*p != '\0' && *p != ' ') p++;
if (*p != '\0') *p++ = '\0';
}
argv[argc] = NULL;
return argc;
}
// Built-ins must run inside the shell itself: a child process cannot change the shell's folder.
// Returns 1 if the command was a built-in.
int run_builtin(int argc, char *argv[]) {
if (strcmp(argv[0], "pwd") == 0) {
char buf[256];
printf("%s\n", getcwd(buf, sizeof(buf)));
return 1;
}
if (strcmp(argv[0], "cd") == 0) {
const char *target = argc > 1 ? argv[1] : "/";
if (chdir(target) != 0) printf("cd: no such directory: %s\n", target);
return 1;
}
if (strcmp(argv[0], "exit") == 0) {
printf("bye\n");
exit(0);
}
return 0;
}
int main(void) {
char *script[] = { "cd /usr", "pwd", "cd /nowhere/at/all", "pwd", "cd", "pwd" };
char *argv[MAX_ARGS];
for (int i = 0; i < 6; i++) {
char line[100];
strcpy(line, script[i]);
printf("tiny> %s\n", line);
int argc = tokenize(line, argv);
if (argc > 0) run_builtin(argc, argv);
}
return 0;
}Output
tiny> cd /usr tiny> pwd /usr tiny> cd /nowhere/at/all cd: no such directory: /nowhere/at/all tiny> pwd /usr tiny> cd tiny> pwd /
Notice that the failed cd /nowhere/at/all reports an error, leaves the folder unchanged (pwd still says /usr), and the shell carries on: a shell must never crash on a bad command. A bare cd goes to / here (a real shell goes to your home folder).
Quick check
Why can cd not be a separate program?
Finish the quick check (and any code exercise) to complete this lesson, or mark it done yourself.
Tip: use the left and right arrow keys to move between lessons.