In: Computer Science
UNIX/LINUX LAB
(1) Review the sample shell program (tryShell.c), and compile/run the program (tryShell) with the following commands,
and at the end, use CTRL+C to terminate the program:
ls
ls -l tryShell*
date
whoami
hostname
uname -a
ctrl+C
(2) Run the program (tryShell) with "time -p" with a few commands:
time -p ./tryShell
(3) Edit the program (tryShell.c) so that it will exit (terminate the program) when the input command string is "exit"
try shell.c code at bottom
////////////
#include 
#include 
#include 
#include 
#include 
#define MAX 1024
void  parse(char *line, char **argv)
{
     while (*line != '\0') {    /* if not the end of line */ 
          while (*line == ' ' || *line == '\t' || *line == '\n')
               *line++ = '\0';  /* replace white spaces with 0*/
          *argv++ = line;       /* save the argument position */
          while (*line != '\0' && *line != ' ' && 
                 *line != '\t' && *line != '\n') 
               line++;      /* skip the argument until ...    */
     }
     *argv = '\0';          /* mark the end of argument list  */
}
void  execute(char **argv)
{
     pid_t  pid;
     int    status;
     if ((pid = fork()) < 0) {    /* fork a child process    */
          printf("*** ERROR: forking child process failed\n");
          exit(1);
     }
     else if (pid == 0) {          /* for the child process: */
          if (execvp(*argv, argv) < 0) {     /* exec command  */
               printf("*** ERROR: exec failed\n");
               exit(1);
          }
     }
     else {                            /* for the parent: */
          while (wait(&status) != pid) /* wait for completion */
               ;
     }
}
void  main(void)
{
     char  line[MAX];      /* the input line                 */
     char  *argv[64];       /* the command line argument      */
     while (1) {            /* repeat until done ....         */
          printf("Shell -> ");   /* display a prompt          */
            if (fgets(line, MAX, stdin) != 0){
               line[strcspn(line, "\n")] = '\0';
                  printf("\n");
        // Place your code here to check the command is "exit"
     //   to terminate the shell. 
                  parse(line, argv);     /* parse the line      */
                  execute(argv);        /* otherwise, execute cmd  */
         }  
     }
}
///////////
1)
./tryShell
Shell -> ls
hello hello1 hello.c shell.o tryShell tryShell.c
tryShell.o
Shell -> ls -l tryShell*
ls: tryShell*: No such file or directory
Shell -> ls -l tryShell
-rwxr-xr-x+ 1 saes0817 ice 8470 Oct 10 10:44 tryShell
Shell -> date
Sat Oct 10 10:51:39 EDT 2020
Shell -> whoami
saes0817
Shell -> hostname
devapp714cn
Shell -> uname -a
Linux devapp714cn 2.6.18-308.el5 #1 SMP Fri Jan 27 17:17:51 EST
2012 x86_64 x86_64 x86_64 GNU/Linux
Shell ->
2)
time -p ./tryShell
Shell -> ls
hello hello1 hello.c shell.o tryShell tryShell.c
tryShell.o
Shell -> date
Sat Oct 10 10:55:11 EDT 2020
Shell -> hostname
devapp714cn
Shell ->
real 14.35
user 0.00
sys 0.01

3) tryShell.c file with exit code
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#define MAX 1024
void  parse(char *line, char **argv)
{
     while (*line != '\0') {    /* if not the end of line */ 
          while (*line == ' ' || *line == '\t' || *line == '\n')
               *line++ = '\0';  /* replace white spaces with 0*/
          *argv++ = line;       /* save the argument position */
          while (*line != '\0' && *line != ' ' && 
                 *line != '\t' && *line != '\n') 
               line++;      /* skip the argument until ...    */
     }
     *argv = '\0';          /* mark the end of argument list  */
}
void  execute(char **argv)
{
     pid_t  pid;
     int    status;
     if ((pid = fork()) < 0) {    /* fork a child process    */
          printf("*** ERROR: forking child process failed\n");
          exit(1);
     }
     else if (pid == 0) {          /* for the child process: */
          if (execvp(*argv, argv) < 0) {     /* exec command  */
               printf("*** ERROR: exec failed\n");
               exit(1);
          }
     }
     else {                            /* for the parent: */
          while (wait(&status) != pid) /* wait for completion */
               ;
     }
}
void  main(void)
{
     char  line[MAX];      /* the input line                 */
     char  *argv[64];       /* the command line argument      */
     while (1) {            /* repeat until done ....         */
          printf("Shell -> ");   /* display a prompt          */
            if (fgets(line, MAX, stdin) != 0){
               line[strcspn(line, "\n")] = '\0';
                  printf("\n");
        // Place your code here to check the command is "exit"
     //   to terminate the shell. 
                   if (0 == strcmp(line, "exit")){
                    exit(1);
               }
                  parse(line, argv);     /* parse the line      */
                  execute(argv);        /* otherwise, execute cmd  */
         }  
     }
}
///////////
OUTPUT:
./tryShell
Shell -> ls
hello hello1 hello.c shell.o tryShell tryShell.c
tryShell.o
Shell -> exit
bash-3.2$
bash-3.2$
bash-3.2$