gopher.navan.dev gopher.navan.dev:70 gopher://gopher.navan.dev:70/0/posts/2023-11-28-shell-lab.md
---
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
```