Can you execute a second instance of our shell from within our shell program (us
ID: 3799732 • Letter: C
Question
Can you execute a second instance of our shell from within our shell program (use './shell')? Which shell receives your input?
/* SMP1: Simple Shell */
/* LIBRARY SECTION */
#include <ctype.h> /* Character types */
#include <stdio.h> /* Standard buffered input/output */
#include <stdlib.h> /* Standard library functions */
#include <string.h> /* String operations */
#include <sys/types.h> /* Data types */
#include <sys/wait.h> /* Declarations for waiting */
#include <unistd.h> /* Standard symbolic constants and types */
/* DEFINE SECTION */
#define SHELL_BUFFER_SIZE 256 /* Size of the Shell input buffer */
#define SHELL_MAX_ARGS 8 /* Maximum number of arguments parsed */
/* VARIABLE SECTION */
enum { STATE_SPACE, STATE_NON_SPACE }; /* Parser states */
int imthechild(const char *path_to_exec, char *const args[])
{
return execv(path_to_exec, args) ? -1 : 0;
}
void imtheparent(pid_t child_pid, int run_in_background)
{
int child_return_val, child_error_code;
/* fork returned a positive pid so we are the parent */
fprintf(stderr,
" Parent says 'child process has been forked with pid=%d' ",
child_pid);
if (run_in_background) {
fprintf(stderr,
" Parent says 'run_in_background=1 ... so we're not waiting for the child' ");
return;
}
wait(&child_return_val);
/* Use the WEXITSTATUS to extract the status code from the return value */
child_error_code = WEXITSTATUS(child_return_val);
fprintf(stderr,
" Parent says 'wait() returned so the child with pid=%d is finished.' ",
child_pid);
if (child_error_code != 0) {
/* Error: Child process failed. Most likely a failed exec */
fprintf(stderr,
" Parent says 'Child process %d failed with code %d' ",
child_pid, child_error_code);
}
}
/* MAIN PROCEDURE SECTION */
int main(int argc, char **argv)
{
pid_t shell_pid, pid_from_fork;
int n_read, i, exec_argc, parser_state, run_in_background;
/* buffer: The Shell's input buffer. */
char buffer[SHELL_BUFFER_SIZE];
/* exec_argv: Arguments passed to exec call including NULL terminator. */
char *exec_argv[SHELL_MAX_ARGS + 1];
/* Entrypoint for the testrunner program */
if (argc > 1 && !strcmp(argv[1], "-test")) {
return run_smp1_tests(argc - 1, argv + 1);
}
/* Allow the Shell prompt to display the pid of this process */
shell_pid = getpid();
while (1) {
/* The Shell runs in an infinite loop, processing input. */
fprintf(stdout, "Shell(pid=%d)> ", shell_pid);
fflush(stdout);
/* Read a line of input. */
if (fgets(buffer, SHELL_BUFFER_SIZE, stdin) == NULL)
return EXIT_SUCCESS;
n_read = strlen(buffer);
run_in_background = n_read > 2 && buffer[n_read - 2] == '&';
buffer[n_read - run_in_background - 1] = ' ';
/* Parse the arguments: the first argument is the file or command *
* we want to run. */
parser_state = STATE_SPACE;
for (exec_argc = 0, i = 0;
(buffer[i] != ' ') && (exec_argc < SHELL_MAX_ARGS); i++) {
if (!isspace(buffer[i])) {
if (parser_state == STATE_SPACE)
exec_argv[exec_argc++] = &buffer[i];
parser_state = STATE_NON_SPACE;
} else {
buffer[i] = '';
parser_state = STATE_SPACE;
}
}
/* run_in_background is 1 if the input line's last character *
* is an ampersand (indicating background execution). */
buffer[i] = ''; /* Terminate input, overwriting the '&' if it exists */
/* If no command was given (empty line) the Shell just prints the prompt again */
if (!exec_argc)
continue;
/* Terminate the list of exec parameters with NULL */
exec_argv[exec_argc] = NULL;
/* If Shell runs 'exit' it exits the program. */
if (!strcmp(exec_argv[0], "exit")) {
printf("Exiting process %d ", shell_pid);
return EXIT_SUCCESS; /* End Shell program */
} else if (!strcmp(exec_argv[0], "cd") && exec_argc > 1) {
/* Running 'cd' changes the Shell's working directory. */
/* Alternative: try chdir inside a forked child: if(fork() == 0) { */
//if (fork() ==0){
if (chdir(exec_argv[1]))
/* Error: change directory failed */
fprintf(stderr, "cd: failed to chdir %s ", exec_argv[1]);
/* End alternative: exit(EXIT_SUCCESS);} */
} else {
/* Execute Commands */
/* Try replacing 'fork()' with '0'. What happens? */
//pid_from_fork = fork();
pid_from_fork = 0;
if (pid_from_fork < 0) {
/* Error: fork() failed. Unlikely, but possible (e.g. OS *
* kernel runs out of memory or process descriptors). */
fprintf(stderr, "fork failed ");
continue;
}
if (pid_from_fork == 0) {
return imthechild(exec_argv[0], &exec_argv[0]);
/* Exit from main. */
} else {
imtheparent(pid_from_fork, run_in_background);
/* Parent will continue around the loop. */
}
} /* end if */
} /* end while loop */
return EXIT_SUCCESS;
} /* end main() */
Explanation / Answer
lbu $10, matrix
lbu $11, matrix+1
lbu $12, matrix+2
lbu $13, matrix+3
lbu $14, matrix+4
lbu $15, matrix+5
lbu $16, matrix+6
lbu $17, matrix+7
lbu $18, matrix+8
lbu $19, matrix+9
lbu $20, matrix+10
lbu $21, matrix+11
lbu $22, matrix+12
lbu $23, matrix+13
lbu $24, matrix+14
lbu $25, matrix+15
addiu $2, $0, 8
addiu $9, $0, 256
loop:
addiu $2, $2, -1
srl $9, $9, 1
addu $27, $0, $0
and $26, $10, $9
srlv $26, $26, $2
or $27, $27, $26
and $26, $11, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $12, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $13, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $14, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $15, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $16, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $17, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $18, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $19, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $20, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $21, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $22, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $23, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $24, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
and $26, $25, $9
srlv $26, $26, $2
sll $27, $27, 1
or $27, $27, $26
sll $3, $2, 1
sh $27, transposed($3)
bgez $2, loop
nop
.data 0x2000
matrix:
.byte 0x80
.byte 0x80
.byte 0x40
.byte 0x40
.byte 0x20
.byte 0x20
.byte 0x10
.byte 0x10
.byte 0x08
.byte 0x08
.byte 0x04
.byte 0x04
.byte 0x02
.byte 0x02
.byte 0x01
.byte 0x01
.data 0x3000
transposed:
.half 0
.half 0
.half 0
.half 0
.half 0
.half 0
.half 0
.half 0
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.