Question

You are required to write a C program on Unix/Linux in which the parent process creates...

You are required to write a C program on Unix/Linux in which the parent process creates three child processes, lets them run concurrently, and waits for them to return and prints their exit status. The three child processes are assigned different tasks. Child one is to calculate and display the highest mark of a class of ten students for a unit. Child one is required to get the marks from the standard input (i.e. the keyboard). Child two is to load a program called “wc” (word count) to count file1. file1 is received from the command line argument. Child three is to modify file2 by first inserting “this is the updated version.” at the beginning of this file and then replacing all the occurrences of the word “execute” by “run” and “study” by “examine”. You are required to write your OWN program for the file update. file2 is received from the command line argument.

0 0
Add a comment Improve this question Transcribed image text
Answer #1

The below program completes allmost all requirement as mention for the program to interprets user commands and executes them.

/*

** Description : Implemenation of a Simple Shell which can

** interpret any unix commands and your own

** commands

** For compilation

** : gcc myShell.c or cc myShell.c

** To run : ./a.out

*/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/types.h>

#include <unistd.h>

#include <errno.h>

#define TRUE 1

#define FALSE !TRUE

#define MAX_BUFFER_SIZE 512

#define MAX_ARG_LEN 100

#define MAX_ARG_COUNT 10

#define CMD_LEN 50

#define CMDLINE_LEN 512

#define MAX_PATH_LEN 255

char PS1[100];

char PATH[255];

char currentDirectory[MAX_PATH_LEN];

int returnStatus = 0;

char *progName;

typedef enum { CD, EXIT, CMD, PWD, ECHO } CMDTYPE;

/*

** Funtion that is executed at the start of the shell

*/

void init()

{

strcpy(PS1, "[batchFile] ");

if (getcwd(currentDirectory, MAX_PATH_LEN) == NULL)

{

perror("getcwd");

exit(1);

}

strcpy(PATH, "/bin");

}

/*

** Prints the prompt string

*/

void showPrompt()

{

printf("%s:%s", currentDirectory, PS1);

}

/*

** Prints the welcome message at the start of the shell

*/

void showWelcomeScreen()

{

// printf("Welcome to GAK Shell...\n");

}

/*

** Helper function to parse the command line entered in the shell

**

** @param: command line entered

** @param: pointer to command string (used as output)

** @param: pointer to list of command line argument strings (used as output)

** @param: pointer to count of command line arguments (used as output)

*/

void parseCmdline(const char *cmdline, char *cmd, char ***cmd_argv, int *cmd_argc)

{

int i = 0;

int temp_argc = 0;

int start_index;

char **temp_argv = NULL;

while (cmdline[i] != ' ' && cmdline[i] != '\0' && i < CMD_LEN)

{

cmd[i] = cmdline[i];

i++;

}

if (i == CMD_LEN)

{

fprintf(stderr, "Cmd buffer overflow.\n");

exit(1);

}

cmd[i] = '\0';

/* if (cmdline[i] == '\0')

{

*cmd_argc = 0;

return;

}

*/

temp_argv = malloc(sizeof(char*));

temp_argv[temp_argc] = (char *) malloc((strlen(cmd)+1)*sizeof(char));

strcpy(temp_argv[temp_argc], cmd);

temp_argc++;

while (cmdline[i] != '\0')

{

while (cmdline[i] == ' ')

i++;

start_index = i;

while (cmdline[i] != ' ' && cmdline[i] != '\0')

i++;

if (temp_argv == NULL)

temp_argv = malloc(sizeof(char*));

else

temp_argv = realloc(temp_argv, (temp_argc+1)*sizeof(char*));

temp_argv[temp_argc] = (char *) malloc((i - start_index + 1) * sizeof(char));

//temp_argv[temp_argc] = (char *) malloc(MAX_ARG_LEN * sizeof(char));

strncpy(temp_argv[temp_argc], cmdline+start_index, (i - start_index));

temp_argv[temp_argc][i-start_index] = '\0';

temp_argc++;

}

temp_argv = realloc(temp_argv, (temp_argc+1)*sizeof(char*));

temp_argv[temp_argc] = NULL;

(*cmd_argv) = temp_argv;

(*cmd_argc) = temp_argc;

return;

}

/*

** Helper function that frees/deallocates the memory assigned during 'parseCmdline'

** function call

**

** @param: pointer to list of command line argument strings

** @param: pointer to count of command line arguments

*/

void freeCmdArgs(char ***cmd_argv, int *cmd_argc)

{

int i;

for (i = 0; i < (*cmd_argc); i++)

free((*cmd_argv)[i]);

if ((*cmd_argc) != 0)

free((*cmd_argv));

(*cmd_argc) = 0;

}

/*

** Helper function to identify the type of command

**

** @param: command string

*/

CMDTYPE getCmdType(const char *cmd)

{

if (strcmp(cmd, "exit") == 0)

return EXIT;

if (strcmp(cmd, "cd") == 0)

return CD;

if (strcmp(cmd, "pwd") == 0)

return PWD;

if (strcmp(cmd, "echo") == 0)

return ECHO;

return CMD;

}

/*

** Implementation of 'echo' command. Assumes that the possible options are

** 1. $? - print the last exit status

** 2. $$ - print the pid of shell

** 3. $<name> - print the value of the environment variable

** 4. <string> - print the string as is

**

** @param: count of command line arguments

** @param: list of command line argument strings

*/

void echoCmd(int argc, char **argv)

{

int i;

char *envVal;

for (i = 1; i < argc; i++)

{

// Print the last exit status

if (strcmp(argv[i], "$?") == 0)

printf("%d", returnStatus);

// Print the shell's pid

else if (strcmp(argv[i], "$$") == 0)

printf("%d", getpid());

else if (argv[i][0] == '$')

{

if ((envVal = getenv(argv[i]+1)) == NULL)

{

perror("getenv");

return;

}

else

printf("%s", envVal);

}

/*else if (strcmp(argv[i], "$PATH") == 0)

printf("%s", PATH);*/

else

printf("%s", argv[i]);

printf(" ");

}

printf("\n");

}

/*

** Takes care of validating the command path and executing the command

** by forking a child process

**

** @param: the command string

** @param: command line arguments count

** @param: list of command line arguments strings

**

** @return: exit status of the command  

*/

int execCmd (char *cmd, int argc, char **argv)

{

char cmdPath[MAX_PATH_LEN];

pid_t child_pid;

int retStat;

#ifdef DEBUG

printf ("cmd: %s\n", cmd);

printf ("PATH: %s\n", PATH);

#endif

if (cmd[0] == '/')

strcpy(cmdPath, cmd);

else if (cmd[0] == '.')

{

if (realpath(cmd, cmdPath) == NULL)

{

fprintf(stderr, "%s: '%s' not found\n", progName, cmd);

return 1;

}

}

else

{

strcpy(cmdPath, PATH);

strcat(cmdPath, "/");

strcat(cmdPath, cmd);

}

#ifdef DEBUG

printf("cmdPath: %s\n", cmdPath);

#endif

if (access(cmdPath, F_OK) != 0)

{

fprintf(stderr, "%s: '%s' not found\n", progName, cmd);

return 1;

}

else

{

child_pid = fork();

if (child_pid < 0)

{

perror("fork");

return -1;

}

else if (child_pid == 0)

{

if (execv(cmdPath, argv) == -1)

{

perror("execv");

return 1;

}

}

else

{

wait(&retStat);

return retStat;

}

}

}

/*

** Changes the current working directory of the program/shell

**

** @param: target path

*/

void changeDirectory(char *target)

{

char tempPath[MAX_PATH_LEN];

char tempCurDir[MAX_PATH_LEN];

/*

** 'target' contains an absolute address

** ex: /var/lib

*/

if (target[0] == '/')

strcpy(tempPath, target);

/*

** 'target' contains a relative address

** ex: foo/bar

*/

else

{

strcpy(tempPath, currentDirectory);

strcat(tempPath, "/");

strcat(tempPath, target);

}

/*

** Sanity check for the new path

*/

if (realpath(tempPath, tempCurDir) == NULL)

{

fprintf(stderr, "%s: cd: '%s': %s\n", progName, tempPath, strerror(errno));

return;

}

else

{

if (chdir(tempCurDir) == -1)

{

perror("chdir");

return;

}

strcpy(currentDirectory, tempCurDir);

}

}

/*

** Prints the current working directory using 'getcwd' library function

*/

void printCurrentWorkingDirectory()

{

char tempPath[MAX_PATH_LEN];

if (getcwd(tempPath, MAX_PATH_LEN) == NULL)

perror("getcwd");

else

printf("%s\n", tempPath);

}

/*

** Main function

**

** @param: count of command line arguments

** @param: list of command line argument strings

** @param: list of environment variable strings

*/

int main(int argc, char **argv, char **envp)

{

char cmdline[CMDLINE_LEN];

char cmd[CMD_LEN];

char **cmd_argv = NULL;

int cmd_argc;

int i;

int closeShell = FALSE;

char tempPath[MAX_PATH_LEN];

progName = argv[0];

init();

showWelcomeScreen();

while (closeShell != TRUE)

{

showPrompt();

gets(cmdline);

parseCmdline(cmdline, cmd, &cmd_argv, &cmd_argc);

#ifdef DEBUG

printf("++++++++++++++++++++++++++++++++++++++++++++++\n");

for (i = 0; i < cmd_argc; i++)

printf("argv[%d] = %s\n", i, cmd_argv[i]);

printf("++++++++++++++++++++++++++++++++++++++++++++++\n");

#endif

switch(getCmdType(cmd))

{

case ECHO:

echoCmd(cmd_argc, cmd_argv);

break;

case PWD:

printf("%s\n", currentDirectory);

break;

case EXIT:

closeShell = TRUE;

break;

case CD:

changeDirectory(cmd_argv[1]);

break;

case CMD:

returnStatus = execCmd(cmd, cmd_argc, cmd_argv);

break;

}

freeCmdArgs(&cmd_argv, &cmd_argc);

}

return 0;

}

Add a comment
Know the answer?
Add Answer to:
You are required to write a C program on Unix/Linux in which the parent process creates...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • How to Write a C program (for Linux/Unix) that: –Creates a struct, where each instance can...

    How to Write a C program (for Linux/Unix) that: –Creates a struct, where each instance can store one message. –Forks a process. –Creates 2+ messages, with contents of your choice, in the parent and sends them to the child via a named or anonymous pipe. –Prints the contents of all received messages in the child process. –If necessary, cleans up after the pipe. Note (the subjects about signal and Pipes )

  • (In Unix) Make a C program that creates a zombie child process. Both parent and child...

    (In Unix) Make a C program that creates a zombie child process. Both parent and child processes should execute the command "ps" to show the current process list. (1) ** Copy and paste your code in your report. ** (2) Take a screen shot that shows the defunct information generated by "ps".

  • 19. UNIX/Linux normally include two editors: vi and (choose the single best answer). 20. You can...

    19. UNIX/Linux normally include two editors: vi and (choose the single best answer). 20. You can use thecommand to create empty a create b. make c touch d mu 21. Which command can be used to leave vi temporarily to access the command line? 22 If you execute the contents of filel are sorted and the results are stored in file2. a sort file1 -ofile2 b. sort file1 >file2 c sort filel -d file2 d sort filel filez field or...

  • Using either a UNIX or a Linux system, write a C program that forks a child...

    Using either a UNIX or a Linux system, write a C program that forks a child process that ultimately becomes a zombie process. Process states can be obtained from the command: ps -l The process states are shown below the S column; processes with a state of Z are zombies. The process identifier (pid) of the child process is listed in the PID column, and that of the parent is listed in the PPID column. Because you do not want...

  • Word count. A common utility on Unix/Linux systems. This program counts the number of lines, words...

    Word count. A common utility on Unix/Linux systems. This program counts the number of lines, words (strings of characters separated by blanks or new lines), and characters in a file (not including blank spaces between words). Write your own version of this program. You will need to create a text file with a number of lines/sentences. The program should accept a filename (of your text file) from the user and then print three numbers: The count of lines/sentences The count...

  • Using Unix processes Submit a README file that lists the files you have submitted along with...

    Using Unix processes Submit a README file that lists the files you have submitted along with a one sentence explanation. Call it Prj1README. MakeCopy.c : Write a C program that makes a new copy of an existing file using system calls for file manipulation. The names of the two files and copy block sizes are to be specified as command line arguments. Open the source file in read only mode and destination file in read/write mode. ForkCopy.c : Write a...

  • C Programming Language on Linux - Word Frequency Program Please write a Program in C that...

    C Programming Language on Linux - Word Frequency Program Please write a Program in C that will accept a text file name as a command-line argument via a main program that will do the following: First, read the file (first pass) and create a linked list of words (in their order of occurrence), with the frequency of each word set to 0. Then, read the file (second pass) and for each word identified, search the linked list, and when found,...

  • Write a C program called test that takes one command line argument, an integer N. When...

    Write a C program called test that takes one command line argument, an integer N. When we run test: ./test N the program will do this: the parent process forks N child processes each child process prints its process ID, exits the parent process waits for all child processes to exit, then exits

  • Write a C program for Linux called pipes.c that does the following: In the main() function,...

    Write a C program for Linux called pipes.c that does the following: In the main() function, it creates a pipe using the pipe() function, then creates two child processes with fork(). Child 1 redirects stdout to the write end of the pipe and then executes with execlp() the "ps -aux" command. Child 2 redirects its input from stdin to the read end of the pipe, then it executes the "sort -r -n -k 5" command. After creating both children, the...

  • Q4) Write a C program named "hw3q4.c” that takes three string inputs from the command line...

    Q4) Write a C program named "hw3q4.c” that takes three string inputs from the command line arguments that represent file names. The first and second files contain four sorted integer numbers that represent set elements. The main process creates a child process that shares the three files. The child process determines the intersection set of two sets and saves the line: "Child process PID: xxxx Intersection of (x, x, x, x) and (y, y, y, y) (z, z, z, z)"...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT