Shell program in C

Hi all,

I have an assignment from school to write a shell program in linux. the idea is to exercise fork() and execv() functions.. the shell program is supposed to be the master and every command that the user prints will run in a new process. we also need to try running the command in every path from the enviroment variable PATH.

for some reason, the execv function isn't working.. any idea what i'm doing wrong?

 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
 pid_t pid;
 char *sh="Shell>";
 int i,pathindex=0, ret;
 char line[80];   // getting the user prompt
 char *paths[20]={"NULL"}; // 20 values path array
 char *currentpath, *path;  // current path to execute in   
 char *arg[]={NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} ;
//////////////////////////////////////////////////////////////////////////////
 path=getenv("PATH");
 currentpath=strtok(path,":");
 while (currentpath!=NULL)
  {
   paths[pathindex]=currentpath; // filling the paths array
   currentpath=strtok(NULL,":"); // from enviroment variable
   pathindex++;   // PATH.
  }
 system("/usr/bin/clear");
 printf("\n\nShell Program (OS Course)\n");
 printf("-------------------------\n\n");
 while (1)
  { 
   printf("%s",sh);
   gets(line);
   arg[0]=strtok(line," ");      // getting command
   if (strcmp(line,"leave")==0) exit(0);
   for (i=1;i<10;i++) arg=strtok(NULL," "); //getting command arguments
   pathindex=0;
   while (paths[pathindex]!=NULL)
   {
    if ((pid=fork())<0)
    {
     printf("Error: Couldn't fork\n");
     exit(1);
    }
    if (pid==0)
    {
    printf("trying to run %s in %s\n",arg[0],paths[pathindex]);
    ret=execv(paths[pathindex],arg);
     if (ret==-1) exit(1);
    }
    else { wait(); pathindex++; }
   }
  }
 return 0;
}

I tried compiling a simple test file just to see if execv works and it did..
it was something like:

Holon Institute of Technology/ B.Sc Computer Science / Operation Systems Course with Dr.Wiseman

An argv vector normally ends in a null pointer? Usually, strtok should be tested to ensure there is a return (consider a for ( strtok ptr, ptr, strtok( NULL ) loop for neatness) (strtok is a good core dump generator if not handled very carefully)?

execvp does examine path, so I guess you are assigned writing execvp from execv.

I like to invest in white space to set off every loop, if, switch with new lines and indentation. I am not enjoying reading the code, so no a+ right off. You deserve structural indentation and spacing! You might always use {} with if/while/for, so you can easily add in debugging commands or additional function points.

some_action ;
 
if ( bool-predicate-one
  || bool-predicate-two ){
    action ;
  }
 
next-action ;

Also, never use gets(); it is unsafe, use fgets( ..., stdin ), getchar() or read( 0, ... ).