3

I am trying to implement a shell. I will be creating a hist array to store the last 10 commands, that I want to be able to retrieve later on in order to execute. So, I am trying to find a way to get all the command line arguments back once I store them in that hist array.

Some of the code is provided, the gettoks(), is a function to get and parse a command line of input. The function gettoks() returns an array of pointers to character strings. Each string is either a word containing the letters, numbers, ., and /, or a single character string containing one of the special characters: ( ) < > | & ;

I understand that I can pass toks to execvp, to execute the command immediately after executing it, but once it is stored in a 2d array of strings, how would I be able to retrieve it ?

I also understand that pointers and arrays can make my life easier, but I am still not so familiar with them! So, I was wondering if I can get some feedback on the code and solve the compilation error at line "execvp(c[0] , c);".

"error: invalid conversion from ‘char’ to ‘const char*’ error: cannot convert ‘const char*’ to ‘char* const*’ for argument ‘2’ to ‘int execvp(const char*, char* const*)’"

Thank you.

#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <cstdlib>
#include <stdio.h>

using namespace std;

extern "C"
{
  extern char **gettoks();
} 

int main( int argc, char *argv[] )
{
  // local variables
  int ii;
  char **toks;
  int retval;
  string tokenString;  
  string hist[11][2];

  // initialize local variables
  ii = 0;
  toks = NULL;
  retval = 0;
  tokenString = "";

  int m = 0; // command counter

  for(int i = 0; i < 11; i++){ // initialize the hist array
    for (int j = 0; j <2; j++){
      hist[i][j]= "";
    }
  }

  // main (infinite) loop
  while( true )
    {
      // get arguments
      toks = gettoks();

      if( toks[0] != NULL ){ // if a command is entered     
         if ( m < 10){
            m++;  // increment the number of commands 
                  for( ii=0; toks[ii] != NULL; ii++ ){ // add the command to the hist array 
              tokenString += toks[ii];              
                  }
         hist[m][0] = toks[0]; 
         hist[m][1] = tokenString; 
         }
         else if (m == 10){ // if the hist array is full
          for( int k = 1; k < 10; k++ ){ // shift the commands in the hist array 
            for (int l = 0; l < 2; l++){       
                      hist[k][l] = hist[k+1][l];                
                  }
          }          
          for( ii= 0; toks[ii] != NULL; ii++ ){ // add the new command to the hist array        
                      tokenString += toks[ii];              
          }
          hist[10][0] = toks[0]; 
          hist[m][1] = tokenString;                 
         }

     }  
     for(int i = 1; i < 11; i++){// print the hist array
         for (int j = 0; j <2; j++){
           cout << hist[i][j] << "\t";
         }
         cout << endl;
     }

     tokenString = ""; // reset  

     const char * c = hist[1][1].c_str();
     execvp(c[0] , c);


       if( !strcmp( toks[0], "exit" ))
         break;
    }


  // return to calling environment
  return( retval );
}
H.K
  • 125
  • 3
  • 15

1 Answers1

2

execvp is intended to be used like that:

char* cmd[] = { "sleep", "1", NULL };
execvp(cmd[0], cmd);

But in your code, you are passing c which is a regular C string (const char *). You can use the array returned by your gettoks() function directly with execvp.

Marcelo Cerri
  • 162
  • 1
  • 10