Link to home
Start Free TrialLog in
Avatar of halt1001
halt1001

asked on

Unix shell

Im doing an assignment, programming in C, in Unix.
The task is, stimulating a shell.
It should accept any command entered.

I have done it, and so far it could run commands entered from the prompt.

However, the problems are:

1. No error returning back when an invalid command entered.

2. Another task is, the pipe operator. I dont know how to do this. Any1 know
how to make it accept pipes like in normal shell? For example:

command1 paratemeters | command 2 ....

Thanks for reading.

Alan.




-----------------------------------------
Here's the code at the moment:
-----------------------------------------

#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main();
void parent(int pid);
void child();

char command[100];

int main() {
 int ret;

 do {
      printf("alan_ass2$");
      fgets(command,100,stdin);

      if ( strncmp(command,"logout\n",8) == 0 )
       exit(1);
      if ( strncmp(command,"\n",1) == 0 )
       continue;

      if( (ret=fork()) > 0 )
           parent(ret);
      else if ( ret == 0 )
           child();
      else
           perror("fork() failed");
     } while (1);

}

void parent(int pid)
{
    int childs_exit_val;

 /*
 ** The parent only invokes the wait() if the command is a foreground
command,
 ** i.e. there is no '&' at the end of the line
 */
}

void child()
{
     char *argv[100]; /* 100 is arbitrarily long enough for this assignment
*/
     char *tmp;
     int cnt,i;

     cnt = -1;
     printf("\n");
            tmp=strtok(command, "\n");
            tmp=strtok(tmp, " ");
            while ( tmp != NULL )
            {
                    argv[++cnt]= tmp;
                    tmp=strtok(NULL," ");
            }

     if ((strncmp(argv[0],"cd",2)==0)&&(strlen(argv[0])==2))
          argv[0]="chdir";

     for (i=0; i<=cnt; i++) {
          printf("argv[%d] = '%s'\n", i, argv[i]);
     }

     argv[cnt+1]=NULL;

     execvp(argv[0], argv);

 /*
 ** If we arrive here, an error must have occurred otherwise a different
 ** program image would be active.
 */
    perror("execvp");
    exit(1); /* must be careful to exit a child process */
}




ASKER CERTIFIED SOLUTION
Avatar of VGR
VGR

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of grg99
grg99

Funny thing about execvp-- on many a Unix system it's an undocumented quirk, the parameters have to be accessible even after you do the execvp!

That is, you can't return and deallocate your argv array.  No idea why, except MAYBE the kernel just scheduls the exec, then returns control to your task (or exits it).  So maybe try putting your argv array someplace where its going to b around for a while, like in static memory.

As for the vertical bar operator, that's a bit tricky, you have to fork off both programs, but with the stdout of #1 passed to the stdin of #2.  See the pipe() and dup() man pages.    Better yet, google for some example code, it's a tricky thing to get right, and hard to debug too!

Several of your fellow classmates have posted questions regarding this
assignment in the last week in these forums. With a little looking, you
should be able to locate the 3 previous discussions,  and benefit from
many ready-made hints.
ah ? I was on so-called-holidays  ;-)