Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

One can incidentally terminate sushi by pressing Ctrl+C (Ctrl+Break, Command+dot) or a similar combination of keys that sends SIGNIT to the shell. Function prevent_interruption() sets

One can incidentally terminate sushi by pressing Ctrl+C

(Ctrl+Break, Command+dot) or a similar combination of keys that sends

SIGNIT to the shell. Function prevent_interruption() sets up a signal

handler that intercepts SIGINT and displays message Type exit to

exit the shell on stderr. The name of the handler is

refuse_to_die(), its skeleton and the skeleton of

prevent_interruption() are provided in sushi.c. Hint: use system call

sigaction() to set up the handler. As a result, when you attempt to

interrupt the shell, it will display the message and continue.

II. (Non-actionable.) File sushi_yyparser.y has been refactored for

clarity. It also has mechanisms for building the command line. The

definitions of the supporting data structures: arglist_t, prog_t, and

redirection_t have been added to sushi.h. Familiarize yourself

with the definitions of the rules (non-terminal symbols) exe, args,

and arg.

exe, the command line program, is simply a list of arguments with some additional information stored in prog_t. An instance of the structure is created dynamically with malloc (lines 87 92). It must be freed after the command execution.

args is an array (not a list) of char*, each holding one argument (lines 9498). It is reallocated each time a new argument is discovered (lines 98103). It must be freed after the command execution.

arg, a command-line argument, is simply a string returned by the lexer (lines 105107). It must be freed after the command execution.

Once the command line is collected, it is passed to function int

spawn(prog_t *exe, prog_t *pipe, int bgmode), lines 4142. You can

disregard the second and the third parameters for now.

Sushi.c

#include

#include

#include "sushi.h"

#include

#include

int sushi_exit = 0;

static void refuse_to_die(int sig)

{

// TODO

}

static void prevent_interruption() {

// TODO

}

int main() {

char *file;

char *fileName = "/sushi.conf";

// read the commands from the file sushi.conf, located in the $HOME directory.

file = malloc(strlen(getenv("HOME")) + strlen(fileName) + 1);

strcat(strcpy(file, getenv("HOME")), fileName);

sushi_read_config(file);

prevent_interruption();

while (sushi_exit == 0) {

// display the prompt SUSHI_DEFAULT_PROMPT

printf("%s", SUSHI_DEFAULT_PROMPT);

char *commandLine = sushi_read_line(stdin);

if (commandLine != NULL){

// Call sushi_parse_command() if sushi_read_line() is successfully called

if (sushi_parse_command(commandLine) == 0) {

// store the returnValue to history if no syntax error found.

sushi_store(commandLine);

};

}

}

return EXIT_SUCCESS;

}

Sushi.h

#ifndefSUSHI_H

#defineSUSHI_H

#include

#include

#include

#include

#defineSUSHI_MAX_INPUT80/* really modest :) */

#defineSUSHI_HISTORY_LENGTH32

#defineSUSHI_DEFAULT_PROMPT"> "

char*sushi_read_line(FILE*in);

intsushi_read_config(char*fname);

voidsushi_store(char*line);

voidsushi_show_history();

char*sushi_unquote(char* s);

intsushi_parse_command(char*command);

externintsushi_exit;// The global exit flag

// Support for the primitive parse tree

// An array of arguments, eventually NULL-terminated

typedefstruct{

intsize;

char**args;

}arglist_t;

// I/O redirection, as in "foobar < foo > bar"

typedefstruct{

char*in, *out1, *out2;// stdin, stdout-write, stdout-append

}redirection_t;

// The program to be executed

typedefstructprog {

arglist_targs;// Arguments, including the program name

redirection_tredirection;// Optional redirections

structprog *next;// The next program in the pipeline, if any; NULL otherwise

}prog_t;

// Start a new program

intspawn(prog_t*exe,prog_t*pipe,intbgmode);

// Report unimplemented functions

void__not_implemented__();

// Replace standard malloc and realloc: abort() if malloc/realloc fails

// The likelyhood of the event is low, but the consequences are grave

void*super_malloc(size_tsize);

void*super_realloc(void*ptr,size_tsize);

#endif

sushi_yyparser.y

%{

#include "sushi.h"

int yylex();

void yyerror(const char* s);

%}

%union {

char *s;

int i;

arglist_t alist;

prog_t *exe;

redirection_t redir;

}

%token YY_SUSHI_SET

%token YY_SUSHI_HISTORY

%token YY_SUSHI_EXIT

%token YY_SUSHI_JOBS

%token YY_SUSHI_PWD

%token YY_SUSHI_CD

%token YY_SUSHI_UNKNOWN

%token YY_SUSHI_LESS

%token YY_SUSHI_MORE

%token YY_SUSHI_MOREMORE

%token YY_SUSHI_AMP

%token YY_SUSHI_BAR

%token YY_SUSHI_TOK

%type arg

%type out_redir any_redir in_redir out1_redir out2_redir inout_redir

%type args

%type bg_mode

%type exe out_exe in_exe redir_exe pipe

%start cmdline

%%

cmdline:

{ /* an empty line is valid, too! Do nothing */ }

| redir_exe bg_mode { spawn($1, NULL, $2); }

| in_exe pipe bg_mode { spawn($1, $2, $3); }

| arg YY_SUSHI_SET arg { __not_implemented__(); } /* TODO */

| YY_SUSHI_JOBS { __not_implemented__(); } /* TODO */

| YY_SUSHI_PWD { __not_implemented__(); } /* TODO */

| YY_SUSHI_CD arg { __not_implemented__(); } /* TODO */

| YY_SUSHI_HISTORY { sushi_show_history(stdout); }

| YY_SUSHI_EXIT { sushi_exit = 1; }

pipe:

YY_SUSHI_BAR out_exe { __not_implemented__(); } /* TODO */

| YY_SUSHI_BAR exe pipe { __not_implemented__(); } /* TODO */

redir_exe:

exe { $$ = $1; }

| exe any_redir { $$ = $1; $$->redirection = $2; __not_implemented__(); }

in_exe:

exe { $$ = $1; }

| exe in_redir { $$ = $1; $$->redirection = $2; __not_implemented__(); }

out_exe:

exe { $$ = $1; }

| exe out_redir { $$ = $1; $$->redirection = $2; __not_implemented__(); }

inout_redir:

in_redir out_redir { $$.in = $1.in; $$.out1 = $2.out1; $$.out2 = $2.out2; }

| out_redir in_redir { $$.in = $2.in; $$.out1 = $1.out1; $$.out2 = $1.out2; }

out_redir:

out1_redir { $$ = $1; }

| out2_redir { $$ = $1; }

any_redir:

in_redir { $$ = $1; }

| out_redir { $$ = $1; }

| inout_redir { $$ = $1; }

in_redir: YY_SUSHI_LESS arg { $$.in = $2; $$.out1 = $$.out2 = NULL; }

out1_redir: YY_SUSHI_MORE arg { $$.out1 = $2; $$.in = $$.out2 = NULL; }

out2_redir: YY_SUSHI_MOREMORE arg { $$.out2 = $2; $$.in = $$.out1 = NULL; }

bg_mode:

{ $$ = 0; }

| YY_SUSHI_AMP { $$ = 1; __not_implemented__(); }

exe:

args {

$$ = malloc(sizeof(prog_t));

$$->args = $1;

$$->redirection.in= $$->redirection.out1 = $$->redirection.out2 = NULL;

$$->next = NULL; }

args:

arg {

$$.args = malloc(sizeof(char*)); // New argument array

$$.args[0] = $1; // Its first element

$$.size = 1; }

| args arg {

$$ = $1;

$$.size++; // Increase argument array size

$$.args = realloc($$.args, sizeof(char*) * $$.size); // Add storage

$$.args[$$.size - 1] = $2; } // Add the last element

arg:

YY_SUSHI_TOK { $$ = $1; }

%%

/* This section is empty */

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Managing Your Information How To Design And Create A Textual Database On Your Microcomputer

Authors: Tenopir, Carol, Lundeen, Gerald

1st Edition

1555700233, 9781555700232

More Books

Students also viewed these Databases questions

Question

How does a client authenticate it to the SMTP that uses SSL or TLS?

Answered: 1 week ago