Thread: Creation of a Command Language Interpreter

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    10

    Creation of a Command Language Interpreter

    Hello fellow programmers,

    I was recently given a task of creating a CLI in c under a unix based system. I have almost completed the task, but am currently stuck with 2 particular points, the logic of the task is as follows (direct reference to documentation):

    main:
    loop
    get input line
    if end of input exit
    break line into words
    found := false
    if command is builtin
    then
    do_builtin( line)
    found := true
    else
    found := find_and_execute( line)
    end if
    if not found report error
    end loop

    The marking of the task is as follows:
    1. Read a full line of text from the user
    2. Detect exit as first word
    3. break line into words
    4. Appropriate test of fork() return value
    5. Correct process handles new task
    6. Appropriate choice of exec() family member
    7.Correct usage of exec() member
    8. Correct use of wait()
    9. Printing the exit status
    10. Working cd implementation

    I have completed points 1,2,3,4,6,8,9 and attempting point 10 currently.

    I request assistance in undertaking points 5 and 7. I have identified that i would use the execv family member, but not am aware of how to use it in this situation.

    The code of the execv family member should be located within the child process and if a keyword is entered that is identifed by unix (eg. ls = list directory), the process should carry out the task( ls = display output of list directory).

    I am allowed to receive assistance, as long as reference is made regarding who i obtained assistance from. Unfortunatley as this is a current task i am reluctant to post up any code and am therefore requesting trust and reliance in the c programming community.

    Please advise me in how i may be able to provide the code, without making it public, would people be willing to provide email addresses to which i can send the code?

    Please also note that the program will only compile on a unix machine.

    Thankyou

    Sicilian

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Not sure about the question as you'ave yourself solved item #5.
    That is, a Unix utility like "ls" will be invoked in the child process.
    Are you unsure about the arguments that are passed to execv()?

  3. #3
    Registered User
    Join Date
    Mar 2010
    Posts
    10
    Yes that is correct itCbitC the unix utility ls should be invoked by the child process, i am familiar with the arguments passed to the execv(argv[0],argv), but in the case of the program, i am unsure how i am meant to code the section(so to speak).

    My understanding for the execv is that the arguments passed to execv() are the path and the , keyword such as ls which is stored in an array called words within my program.

    Thankyou for your reply

    If i have said anything that is unclear or incorrect please inform me so that i may correct it and explain the problem more effectively
    Last edited by Sicilian_10; 04-15-2010 at 12:09 AM. Reason: To clear up understanding of concept

  4. #4
    Noob AnishaKaul's Avatar
    Join Date
    Jan 2010
    Location
    Gurgaon, India
    Posts
    115
    Sicilian_10

    You need to add something similar to the below code, to your program, before you fork anything new.

    cd cannot work as an external command because an external command creates a child process, and a process cannot affect the environment of its parent (shell in this case).

    Code:
    if (!strcmp (command, "cd"))
    	    {
    	      if (argv[1] == NULL)
    		{
    		  chdir ("/");
    		}
    	      else
    		{
    		  chdir (argv[1]);
    		}
    	      perror (command);
    	    }

  5. #5
    Registered User
    Join Date
    Mar 2010
    Posts
    10
    Sorry, i do not understand how any of that code has anything to do with point 7 and using the execv family member to invoke a task through the child.

    Thankyou for your explanation of point 10, but i have already completed it.
    Last edited by Sicilian_10; 04-15-2010 at 01:16 AM. Reason: Misunderstanding

  6. #6
    Noob AnishaKaul's Avatar
    Join Date
    Jan 2010
    Location
    Gurgaon, India
    Posts
    115
    Oh I didn't read that you have already completed point 10 !

  7. #7
    Noob AnishaKaul's Avatar
    Join Date
    Jan 2010
    Location
    Gurgaon, India
    Posts
    115
    You mean by point number 7 that you didn't understand how to get an proper listing of files when you do ls through your program ?

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    10
    From my understanding point 7 is completley based on the exec families

    For the purpose of this program i am using the execv

    The problem is that i used to have execl but my tutor said that this is incorrect based on the program and that i needed to change it to execv.

    I have not used the execv before and have been doing research on it for a while. I have attempted codes and looked at examples but each time it does not seem to work for the program.

    Within the child process execv exists, when a keyword such as ls, dir, etc is recognised by the program, it should carry out the task assigned to that keyword eg ls would result in the child process carrying out the task of displaying list directory.

    How this is possible, i do not understand, as the program was initially based on execl which was simple but execv has made it more difficult.
    Last edited by Sicilian_10; 04-15-2010 at 02:33 AM. Reason: Punctuation

  9. #9
    Noob AnishaKaul's Avatar
    Join Date
    Jan 2010
    Location
    Gurgaon, India
    Posts
    115
    Quote Originally Posted by Sicilian_10
    execv has made it more difficult.
    execvp is more simpler than execl

    See the following thread:
    Making a C++ shell

  10. #10
    Registered User
    Join Date
    Mar 2010
    Posts
    10
    not execvp its execv, there is a difference

  11. #11
    Noob AnishaKaul's Avatar
    Join Date
    Jan 2010
    Location
    Gurgaon, India
    Posts
    115
    Oh again i misread it
    May be i am tired today !

  12. #12
    Noob AnishaKaul's Avatar
    Join Date
    Jan 2010
    Location
    Gurgaon, India
    Posts
    115
    Ok Try the following program now with input -a only.

    I have fixed the command /usr/bin/who in the program.

    Tell me if i have again misread something !

    Code:
    #include <unistd.h>     // getpid(), getcwd()
    #include <sys/types.h>  // type definitions, e.g., pid_t
    #include <sys/wait.h>   // wait()
    #include <signal.h>     // signal name constants and kill()
    #include <iostream>
    #include <vector>
    #include <string.h>
    using namespace std;
    
    int main()
    {
    	while ( true )
    	{
          		// Show prompt.
    		cout << get_current_dir_name () << "$ " ;
    		char command[128];
    		cin.getline( command, 128 );
          
    		vector<char*> args;
    		char* prog = strtok( command, " " );
    		char* tmp = prog;
    		while ( tmp != NULL )
    		{
    			args.push_back( tmp );
    			tmp = strtok( NULL, " " );
    		}
          
    		char** argv = new char*[args.size()+1];
    		for ( int k = 0; k < args.size(); k++ )
    			argv[k] = args[k];
          
    		argv[args.size()] = NULL;
          
    		if ( strcmp( command, "exit" ) == 0 )
    		{
    			return 0;
    		}
    		else
    		{
    			pid_t kidpid = fork();
    
    			if (kidpid < 0)
    			{
    				perror( "Internal error: cannot fork." );
    				return -1;
    			}
    			else if (kidpid == 0)
    			{
    		  		// I am the child.					
    				execv ("/usr/bin/who", argv);
    		  
    				  // The following lines should not happen (normally).
    				perror( command );
    				return -1;
    			}
    			else
    			{
    				  // I am the parent.  Wait for the child.
    				if ( waitpid( kidpid, 0, 0 ) < 0 )
    				{
    					perror( "Internal error: cannot wait for child." );
    					return -1;
    				}
    			}
    		}
    	}
      
    	return 0;
    }

  13. #13
    Registered User
    Join Date
    Mar 2010
    Posts
    10
    The code that you have provided does not appear to work in the way intended for the program.

    Thankyou for your attempt anyway

  14. #14
    Noob AnishaKaul's Avatar
    Join Date
    Jan 2010
    Location
    Gurgaon, India
    Posts
    115
    can you kindly explain what the code doesn't do that you want exactly !

  15. #15
    Registered User
    Join Date
    Mar 2010
    Posts
    10
    The execv does not determine that a function keyword has been entered and as a result pass the task to the child to be carried out.

    From my understanding the only thing the current code will do is identify who is connected (so to speak through the execv"/usr/bin/who, the arguments are not identified.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why isn't the execlp() function doing anything?
    By jsrig88 in forum C Programming
    Replies: 5
    Last Post: 10-12-2009, 10:09 AM
  2. Replies: 2
    Last Post: 12-16-2008, 02:43 PM
  3. Interpreter Features Question
    By audinue in forum C Programming
    Replies: 0
    Last Post: 10-19-2008, 07:29 AM
  4. program not working...please look at this
    By JOlszewski in forum C Programming
    Replies: 3
    Last Post: 01-30-2006, 10:33 PM
  5. Newton + Einstein were wrong!
    By Jez in forum A Brief History of Cprogramming.com
    Replies: 64
    Last Post: 12-14-2004, 02:24 PM