-4

I would like to get which command as a parameter of execv. For example user types "firefox" as an input. It will show the file path with which firefox command and i would like to use it in execv. Here is my try :

int main(void)
{
            //char inputBuffer[MAX_LINE]; /*buffer to hold command entered */
            char *args[MAX_LINE/2 + 1]; /*command line arguments */



    while (1){

            char command1[50] = "which ";
            char *input = args[0]; /* args[0] holds input */
            strcat(command1,input);

            char *const parmList[] = {input,NULL};

             char buf[100];  /* will convert command to the file path */
             char *str;
             FILE *file;

            if (NULL == (file = popen(command1, "r"))) {
                perror("popen");
                exit(EXIT_FAILURE);
              }

            while (fgets(buf, sizeof(buf), file) != NULL) {

              }
              pclose(file);

        int count=0;
        for(int m=0;m<buf[m];m++){
            if(buf[m] != ' ')
                count++;
        }


        char x5[count];
            for(int t=0;t<=count;t++){
                x5[t]=buf[t];
            }

            printf("%s\n\n\n\n",x5); /*i tried to delete spaces from 'buf'

        but there is something wrong in file path the output is something like that :
        (input : firefox)
        usr/bin/firefox
        (some weird characters)  

because of weird characters execv don't get filepath correctly. I have to this
only with execv
 */



                pid_t childpid;
                childpid = fork();

            if (childpid == -1) { 
            printf("error"); 
            }

            if (childpid == 0) { 

            execv(x5, parmList);

            }
      }

    }
Clifford
  • 88,407
  • 13
  • 85
  • 165
  • in `strcat` call, you have the arguments backwards – DBug Dec 06 '15 at 22:57
  • [yawn], someone say summat? – Martin James Dec 06 '15 at 22:58
  • 1
    this line: `char *input = args[0]; will not work for several reasons. 1) the declaration of `main()` is not `int main( int argc, char *args[] )` so the args[0] is not available and this line: `char *args[MAX_LINE/2 + 1];` only declares an array of pointer to pointers to char, it does not give any of those pointers any useful value. – user3629249 Dec 06 '15 at 23:01
  • when inputting a 'path' to an executable, the input buffer must be large enough to hold the max allowed path length + the executable name. `buf[]` is only 100 bytes. So not nearly large enough to be 'robust'. – user3629249 Dec 06 '15 at 23:11
  • 1
    There are over 10 million questions on SO. Shouting to be heard will not work. I have edited your question title to be less offensive to the community - you will no doubt get good answers much faster that way. *Interesting* and *well formed* is what gets your question noticed here, not shouting or demanding. It's no one's emergency but your own. – Clifford Dec 06 '15 at 23:28
  • 1
    @user3629249 : Post answers as answers, not as comments. – Clifford Dec 06 '15 at 23:29
  • args[0] come from another method that i didn't write. I think my problem is how holding char from popen because the output gets weird right there. – Gökhan Yenilmez Dec 06 '15 at 23:38
  • Sorry it is my first post and i am almost going crazy. Because i can't make it and this is the smallest part in my project. The deadline is 5 days later – Gökhan Yenilmez Dec 06 '15 at 23:41
  • @GökhanYenilmez We can't help you if you are not showing the actual code. At the minimum it will distract from the real problem as people will attempt to answer things which appear to be wrong with the code but which is in fact due to some missing code. So if you want help please provide a [Minimal Complete and Verifiable Example](https://stackoverflow.com/help/mcve). "how holding char from popen"..that doesn't make grammatical sense so not clear what you are asking. – kaylum Dec 06 '15 at 23:47
  • what happens if the user input is more than one token? for instance: `ls -al` – user3629249 Dec 06 '15 at 23:57
  • have you printed out the string(s) pointed to by `args[]` to assure they are as expected? have you printed out the first parameter passed to `execv()` to assure it is as expected? – user3629249 Dec 06 '15 at 23:59
  • suggest using `execlp()` or `exedvp()` rather than `execv()` as those functions will perform a search for the `filename` specified in the first parameter, so no need to retrieve the full path and append the filename to the path. – user3629249 Dec 07 '15 at 00:07
  • @Clifford, My early comments have nothing to do with the problem the OP is having. So naturally they are comments rather than answers. I have posted an answer that addresses the problem the OP is having. – user3629249 Dec 07 '15 at 17:57

1 Answers1

1

there are, as you noticed, a few problems with the two loops that are trying to remove any embedded spaces in the value being passed as first param to execv()

Note: always place the literal on the left to have compiler catch error if accidentally wrote an assignment rather than a comparison statement.

1) failed to trim any trailing newline from the buf[] array.

2) those loops are, well, not correct. Suggest:

// remove trailing newline
char * newline = NULL;
if( NULL != (newline = strstr( buf, "\n") ) )
{ // then trim newline
    *newline = '\0';
}

// data declarations for removing space characters
char *sourceIndex = buf;
char *targetIndex = buf;

// following loop removes space characters, in place
// and stops when the string terminator char encountered
for( ; sourceIndex; sourceIndex++)  
{
    if( ' ' != *sourceIndex )
    { // then char to have in final output
        *targetIndex = *sourceIndex; // copy it
        targetIndex++;               // step to next position in target
    }
}

*targetIndex = '\0'; // terminate the (possibly shorter) string
...

// pass to new process
if( 0 == childpid )
{ // then child process
    execv(buf, parmList); // only returns if execv() failed
    perror( "execv failed" );
    exit( EXIT_FAILURE );
}
user3629249
  • 16,402
  • 1
  • 16
  • 17