---
date: 2023-11-28
description: Walkthrough of Shell Lab for CSCI 2400 Computer Systems
tags: C, CSCI2400, UNIX
draft: true
---
# Shell Lab
## Introduction
...
We will be solving this lab trace by trace.
## trace01
We don't have to do anything here. The pre-existing code skeleton already passes this.
## trace 02
```
#
# trace02.txt - Process builtin quit command.
#
quit
WAIT
```
From the lab handout, we know that we need to implement this in the `builtin_cmd`
```
// builtin_cmd: Recognizes and interprets the built-in commands: quit, fg, bg, and jobs. [25 lines]
/////////////////////////////////////////////////////////////////////////////
//
// builtin_cmd - If the user has typed a built-in command then execute
// it immediately. The command name would be in argv[0] and
// is a C string. We've cast this to a C++ string type to simplify
// string comparisons; however, the do_bgfg routine will need
// to use the argv array as well to look for a job number.
//
int builtin_cmd(char **argv)
{
string cmd(argv[0]);
return 0; /* not a builtin command */
}
```
We can simply add an if statement and check if the passes string is equal to `quit`
```
int builtin_cmd(char **argv)
{
string cmd(argv[0]);
if (cmd == "quit") {
exit(0);
}
return 0; /* not a builtin command */
}
```
Now, we also need to make sure we are checking if the passes command is a builtin command. So, looking at `eval`
```
/////////////////////////////////////////////////////////////////////////////
//
// eval - Evaluate the command line that the user has just typed in
//
// If the user has requested a built-in command (quit, jobs, bg or fg)
// then execute it immediately. Otherwise, fork a child process and
// run the job in the context of the child. If the job is running in
// the foreground, wait for it to terminate and then return. Note:
// each child process must have a unique process group ID so that our
// background children don't receive SIGINT (SIGTSTP) from the kernel
// when we type ctrl-c (ctrl-z) at the keyboard.
//
void eval(char *cmdline)
{
/* Parse command line */
//
// The 'argv' vector is filled in by the parseline
// routine below. It provides the arguments needed
// for the execve() routine, which you'll need to
// use below to launch a process.
//
char *argv[MAXARGS];
//
// The 'bg' variable is TRUE if the job should run
// in background mode or FALSE if it should run in FG
//
int bg = parseline(cmdline, argv);
if (argv[0] == NULL)
return; /* ignore empty lines */
return;
}
```
We simply add a check for `builtin_cmd`
```
void eval(char *cmdline)
{
/* Parse command line */
//
// The 'argv' vector is filled in by the parseline
// routine below. It provides the arguments needed
// for the execve() routine, which you'll need to
// use below to launch a process.
//
char *argv[MAXARGS];
//
// The 'bg' variable is TRUE if the job should run
// in background mode or FALSE if it should run in FG
//
int bg = parseline(cmdline, argv);
if (argv[0] == NULL)
return; /* ignore empty lines */
// First check if it is a builtin command
if (!builtin_cmd(argv)) {
return;
}
return;
}
```
## Trace 03
```
#
# trace03.txt - Run a foreground job.
#
/bin/echo tsh> quit
quit
```