Thread: Help: A Simple Shell

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    4

    Help: A Simple Shell

    I have to do an assignment where I make a simple shell like application in C. It basically takes user input from a command line, parses it, and runs the execv() command to run it in a new process. Since we have to use the execv() and not the execvp(), I need to access and parse the users path to run commands. Unfortunately I have NEVER written a C program, and that is where I am having a problem. If anyone has any ideas or solutions, I would appreciate it. The following code uses execvp() and runs just fine. I need to figure out how to make it use execv(). I understand the concept, I need to parse the path, check to see if the command exists in any of the path locations, If it does execute it with that absolute path. Since I have never written in C before, I am having a REALLY difficult time. I already e-mailed my teacher and he said that recieving help is not a problem as long as I reference any help I got in the program. the following code is what I have so far:


    Code:
    
    /* fork.c - example of a fork in a program */
    /* The program asks for UNIX commands to be typed and inputted to a string*/
    /* The string is then "parsed" by locating blanks etc. */
    /* Each command and sorresponding arguments are put in a args array */
    /* execvp is called to execute these commands in child process */
    /* spawned by fork() */
    
    /* c89 -o fork fork.c */
    
    #include <stdio.h>
    
        main()
       {
          char buf[1024];
          char *args[64];
    		char *pathDir{200};
       
    	   parsePath();
    	
          for (;;) {
            /*
             * Prompt for and read a command.
             */
             printf("user$");
          
             gets(buf);
          
          
             parse(buf, args);
          
             execute(args);
          }
        
       }
    
    /*
     * parse--split the command in buf into
     *         individual arguments.
     */
        parse(buf, args)
           char *buf;
           char **args;
       {
          while (*buf != NULL) {
            /*
             * Strip whitespace.  Use nulls, so
             * that the previous argument is terminated
             * automatically.
             */
             while ((*buf == ' ') || (*buf == '\t'))
                *buf++ = NULL;
          
            /*
             * Save the argument.
             */
             *args++ = buf;
          
            /*
             * Skip over the argument.
             */
             while ((*buf != NULL) && (*buf != ' ') && (*buf != '\t'))
                buf++;
          }
       
          *args = NULL;
       }
    
    
        parsePath( char *dirs[] ){
       
          char pathEnvVar;
          char thePath;
          int i;
          for( i = 0 ; i < 64 ; i++ ){
             dirs[i] = NULL;
          }
          pathEnvVar = (char *) malloc(strlen(pathEnvVar) + 1);
          strcpy(thePath, pathEnvVar);
       
       
       
       }
    /*
     * execute--spawn a child process and execute
     *           the program.
     */
        execute(args)
           char **args;
       {
          int pid, status;
       
        /*
         * Get a child process.
         */
          if ((pid = fork()) < 0) {
             perror("fork");
             exit(1);
          }
       
        /*
         * The child executes the code inside the if.
         */
          if (pid == 0) {
             execvp(*args, args);
             perror(*args);
             exit(1);
          
          }
       
        /*
         * The parent executes the wait.
         */
          while (wait(&status) != pid)
            /* empty */ ;
       }
    this is not an attempt to get someone to do my homework, I am truly lost. I have a bit of experience in programming, so I grasp the concepts and fully understand them. I just dont know how to implement them in C. Unfortunately my professor wants a more specific question to help me. I don't even know the syntax for C and the pointer passing is confusing me a bit how they are declared. I am about to just give up and take incomplete credit, which I hate to do.

    Thanks in advance for any help,

    Roaming_Builder

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I don't think your professor goes far enough -- he wants a more specific question; I'm asking for any question at all.

    While I'm waiting, some comments:
    (1) If you have some experience in programming, then presumably you know some programming language. Can you write what you need in that language? At least if nothing else you know you will have the logic down.
    (2) I would imagine your library has a C textbook, if not the one they use for the introductory classes. With some experience, you could probably start around chapter 2, maybe 3; by the time you get to chapter 15 or 20 or so you should know all the syntax you'll need.
    (3) I assume by "path" you mean the environment variable? You're going to have to both interface with the OS to get that information, and know what kind of thing is going to come back (e.g., what symbols can and will be used to separate directories). This parsing is going to look a lot like the parse() that's already written -- read it, and its comments!, to see what you're going to need to do.

  3. #3
    Registered User
    Join Date
    Feb 2008
    Posts
    4
    sorry, didn't have time to write a response before work this morning. Been on mandatory 12 hr days all week. I went to the library as you suggested and did in face find some C programming books and I will hopefully get to read some of it before i zonk out tonight...

    I guess my more specific question is that I am trying to figure out how to make the parsePath function work like the parse function. It seems like the only difference between the two is that parse uses spaces from the command line and parsePath will need to separate using the colon ( It seems like the path is like PATH=/opt/intel/cc/9.1.042/bin:/opt/intel/fc/9.1.036/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/local/src/NAMD_2.6_Linux-i686:/opt/mpich/bin

    on my school server. I believe that is standard formatting. The separate file paths separated by a :.

    was wondering if I just need to change the line in parse
    Code:
             while ((*buf == ' ') || (*buf == '\t'))
                *buf++ = NULL;
    to

    Code:
             while (*buf == ':')
                *buf++ = NULL;
    then that should build an array with the paths just like the other parser built an array of arguments using whitespace(they were using " "-space and \t-I think tab)?

    Then I still need to try to figure out how to lookup each of the paths directories to see if the command is there(ie, "ls" is stored somewhere...). Hopefully I can find something in my book about that if you don't know.

    from there then I should just have to pass the complete path where the command is including the command name itself as the first parameter in the argument array to the execv() function, so usr/bin/ls or wherever it is stored then the -l -whatever those will be the rest of the args in the array.

    I have 24hours to learn a new programming language and still have to work 12hrs tomorrow, eek! HAHA anyways thanks in advance for any ideas or input.

    -Roaming_builder

    BTW however this assignment goes i still plan on learning C, so if you have any good ideas on resources that may help, feel free to share...

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The idea with the colon should work. You're going to have to run some system calls for the second, I think.

  5. #5
    Registered User
    Join Date
    Feb 2008
    Posts
    4
    ok, I have no idea what system calls I need to use, but I am looking for them in these books now , thanks. So far it talks about opening a file, but not checking to see if one exists. FURTHER READING IMMINENT =)

  6. #6
    Registered User
    Join Date
    Feb 2008
    Posts
    4
    do you happen to know the name of the system call I need? Just thought it wouldn't hurt to ask, I assume not or you would have listed it above...

    Thanks again,

    Roaming Builder

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    ls will tell you whether a file is in a given directory.... Edit: and now that I think of it, which will give you the path of the executable as well.

    Granted, these assume a *nix OS, but I think the whole problem assumes a *nix OS. These aren't C commands, these should go in a popen, I guess.
    Last edited by tabstop; 02-10-2008 at 10:18 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 34
    Last Post: 05-27-2009, 12:26 PM
  2. Implement Redirection for a simple shell
    By koooee in forum C Programming
    Replies: 4
    Last Post: 02-22-2009, 03:21 PM
  3. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  4. System.ini Shell Problems
    By (TNT) in forum Windows Programming
    Replies: 2
    Last Post: 08-26-2001, 01:05 PM