Question

In: Computer Science

This program is a simple version of the linux shell using execvp by forking using C...

This program is a simple version of the linux shell using execvp by forking using C

Currently this program of the shell assumes user enters no spaces before and no extra spaces between strings.

Using exec, an executable binary file (eg: a.out) can be converted into a process. An example of using exec is implementing a shell program or a command interpreter. A shell program takes user commands and executes them.

  • int execvp(const char *file, char *const argv[]);

    • Same as execv except that we don’t have to give the full path name of the command. Uses the $PATH environment variable to find the path.

static char* args[] = {"cp", "cat.txt", "test1.txt", NULL};
execv("cp", args);

Only code void cmdToArray().

Program should be able to execute ls -l.

<cmd> ls -l
<cmd> cp file1.txt file2.txt

#include <stdio.h>
#include <string,h>// strcmp
#include <stdlib.h>// exit
#include <unistd.h>// fork, exec
#include <sys/wait.h>// wait

#define MAXARGS 20
#define ARGLEN 256

void execute(char *cmd, char *arglist[]);
void cmdToArray(char *cmd, char *arglist);

int main(void)
{
int pid;
char *arglist[MAXARGS+1]; // array of pointers
char cmd[ARGLEN]; // read stuff here

while (1)
{
printf("cmd> ");
fgets(cmd, ARGLEN, stdin);

// remove newline from cmd
cmd[strlen(cmd) - 1] = '\0';

// exit if user types exit
if (strcmp(cmd, "exit") == 0)
{
exit(0);
}
else if (*cmd != '\0')
{
// TODO: break cmd into individual strings as elements of arglist
cmdToArray(cmd, arglist);
execute(arglist);
}
}

return 0;
}

void cmdToArray(char *cmd, char *arglist[]) //code here
{
// cmd = "*cp file1.txt file2.txt"
// char cmd[25] = ('c', 'p', ' ', 'f', ')
// arglist[0] = cmd;
// arglist[1] = &cmd[3];
// arglist[2] = &cmd[9];
// arglist[3] = "NULL";
// arglist = (**char)malloc(sizeof(char*) * cmd);
// arglist[0] = (char *)malloc(sizeof(char) *MAXARGS * string);
// int length = strlen(cmd);
/* for (int i = 0; i < length; ++i)
{
if (cmd[i] != ' ')
{
arglist[argc] = &cmd[i];
++argc;
}
else if(cmd[i] == ' ')
{
cmd[i] = '\0';
}
} */

}

void execute(char *arglist[])
{
int pid, exitstatus;

pid = fork(); // make new process
if (pid == -1)
{
perror("fork failed");
exit(1);
}
else if (pid == 0)
{
execvp(arglist[0], arglist);
// exec cannot return
fprintf(stderr, "Cannot execute %s\n", arglist[0]);
exit(1); // exec failed
}
else
{
int got_pid = wait(&exitstatus);
if (got_pid == pid)
{
printf("The child we were waiting for died\n");

if (WIFEXITED(exitstatus))
{
printf("child process %d exited with value %d\n", pid, WEXITSTATUS(exitstatus));
}
}
else if (got_pid == -1)
{
perror("wait failed");
}
}
}

Solutions

Expert Solution

Please look at my code and in case of indentation issues check the screenshots.

-----------------main.c----------------

#include <stdio.h>
#include <string.h>// strcmp
#include <stdlib.h>// exit
#include <unistd.h>// fork, exec
#include <sys/wait.h>// wait
#define MAXARGS 20
#define ARGLEN 256

void execute(char *arglist[]);
void cmdToArray(char *line, char *arglist[]);

int main(void)
{
   int pid;
   char *arglist[MAXARGS + 1];   // array of pointers
   char cmd[ARGLEN];   // read stuff here

   while (1)
   {
       printf("cmd > ");
       fgets(cmd, ARGLEN, stdin);

       // remove newline from cmd
       cmd[strlen(cmd) - 1] = '\0';

       // exit if user types exit
       if (strcmp(cmd, "exit") == 0)
       {
           exit(0);
       }
       else if (*cmd != '\0')
       {
           // TODO: break cmd into individual strings as elements of arglist
           cmdToArray(cmd, arglist);
           execute(arglist);
       }
   }

   return 0;
}


void cmdToArray(char *line, char *arglist[])   //splits the line into words and stores in arglist array
{
   while (*line != '\0')                                         // if not the end of line .......
   {   
       while (*line == ' ' || *line == '\t' || *line == '\n')   //checks if we are near whitespaces
           *line++ = '\0';                                    // replace white spaces with \0 NULL character
       *arglist++ = line;                             // save the argument position (start position of word)
       while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n')    //skips characters within a word
           line++;                                             //skip till end of next argument (end position of the word)
   }
   *arglist = '\0';                                         //mark the end of argument list
}

void execute(char *arglist[])
{
   int pid, exitstatus;

   pid = fork();   // make new process
   if (pid == -1)
   {
       perror("fork failed");
       exit(1);
   }
   else if (pid == 0)
   {
       execvp(arglist[0], arglist);
       // exec cannot return
       fprintf(stderr, "Cannot execute %s\n", arglist[0]);
       exit(1);   // exec failed
   }
   else
   {
       int got_pid = wait(&exitstatus);
       if (got_pid == pid)
       {
           printf("The child we were waiting for died\n");

           if (WIFEXITED(exitstatus))
           {
               printf("child process %d exited with value %d\n", pid, WEXITSTATUS(exitstatus));
           }
       }
       else if (got_pid == -1)
       {
           perror("wait failed");
       }
   }
}

--------------Screenshots-------------------

------------------Output-----------------

---------------------------------------------------------------------------------------
Please give a thumbs up if you find this answer helpful.
If it doesn't help, please comment before giving a thumbs down.
Please Do comment if you need any clarification.
I will surely help you.

Thankyou


Related Solutions

Using Virtualbox in Debian, write a simple program (a single .cpp file) in Linux shell C++...
Using Virtualbox in Debian, write a simple program (a single .cpp file) in Linux shell C++ Rules: -Use fork(), exec(), wait(), and exit() _______________________________________________________________________________________________________________________________________________ -A line of input represents a token group. -Each token group will result in the shell forking a new process and then executing the process. e.g. cat –n myfile.txt // a token group -Every token group must begin with a word that is called the command(see example above). The words immediately following a command are calledarguments(e.g....
Using Virtualbox in Debian, write a simple program (a single .cpp file) in Linux shell C++...
Using Virtualbox in Debian, write a simple program (a single .cpp file) in Linux shell C++ Rules: -Use fork(), exec(), wait(), and exit() _______________________________________________________________________________________________________________________________________________ -A line of input represents a token group. -Each token group will result in the shell forking a new process and then executing the process. e.g. cat –n myfile.txt // a token group -Every token group must begin with a word that is called the command(see example above). The words immediately following a command are calledarguments(e.g....
Using C Write a program that will serve as a simple shell. This shell will execute...
Using C Write a program that will serve as a simple shell. This shell will execute an infinite for loop. In each iteration of the loop, the user will be presented with a prompt. When the user enters a command, the shell will tokenize the command, create a child process to execute it and wait for the child process to be over. If the user enters an invalid command, the shell should recognize the situation and show a meaningful message....
Systems Programming in Linux using C Remake the version of the ls -ialR command in C.....
Systems Programming in Linux using C Remake the version of the ls -ialR command in C.. In this version of ls, you must also consider symbolic file types. Make sure you have file header comments and function header comments. Also, write inline comments whenever necessary.
Write a shell program named HELLO2(this should be done in linux, using bash) Consider files in...
Write a shell program named HELLO2(this should be done in linux, using bash) Consider files in the current directory whose names end in 't' or 'z'. For such files only, your program should list certain LINES of the file(s). These lines are those that have at least 4 x's somewhere in the line. Note that the x's may be upper- or lower-case, and may be separated by other characters; so the following 3 lines DO match: XXxX and more things...
Systems Programming - File Operations Create your version of the tail command in Linux using C...
Systems Programming - File Operations Create your version of the tail command in Linux using C The lseek system call allows you to move the current position anywhere in a file. The call lseek(fd, 0, SEEK_END) moves the current position to the end of the file. The tail command displays the last ten liens of a file. Try it. tail has to move, not to the end of the file, but to a spot ten lines before the end of...
C program simple version of blackjack following this design. 1. The basic rules of game A...
C program simple version of blackjack following this design. 1. The basic rules of game A deck of poker cards are used. For simplicity, we have unlimited number of cards, so we can generate a random card without considering which cards have already dealt. The game here is to play as a player against the computer (the dealer). The aim of the game is to accumulate a higher total of points than the dealer’s, but without going over 21. The...
Linux Directories, File Properties, and the File System in C Understanding Unix/Linux Programming Your version of...
Linux Directories, File Properties, and the File System in C Understanding Unix/Linux Programming Your version of mv command The mv command is more than just a wrapper around the rename system call. Write a version of mv that accepts two argument. The first argument must be the name of a file, and the second argument may be the name of a file or the name of a directory. If the destination is the name of a directory, then mv moves...
Design two shell programs working on Linux (Ubuntu) Design a shell script program, 1) reading given...
Design two shell programs working on Linux (Ubuntu) Design a shell script program, 1) reading given only two integer numbers from command line arguments and computing their multiplication. If two integer numbers are not given, print “Wrong Input” on your screen. Note that, the number of arguments is known when the script runs. Take a screenshot showing your shell program and its execution step. Design a shell program to remove all the shell programming files ending with sh on your...
please write in c using linux or unix Write a program that will simulate non -...
please write in c using linux or unix Write a program that will simulate non - preemptive process scheduling algorithm: First Come – First Serve Your program should input the information necessary for the calculation of average turnaround time including: Time required for a job execution; Arrival time; The output of the program should include: starting and terminating time for each job, turnaround time for each job, average turnaround time. Step 1: generate the input data (totally 10 jobs) and...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT