c++ issue with using commandline inputs in a forked execvp

When running the code below I get an incorrect output. I am fairly sure I am doing something wrong with the execvp call as I have tried changing everything and only this seems to be responsible. As far as I know the parameters for execvp should be the filename and the array which I pass using execvp(argv[0], argv). Replacing these parameters with things such argv[1] seems to change the output which is why I think I am doing something wrong here.


a.out file -> lab1 (g++ lab1.cpp -o lab1)
folder -> lab1
.cpp file -> lab1.cpp


current output

1
2
3
4
5
6
7


    steve@fish lab1]$ lab1 -ls -l
    lab1 ls -l Parent process id is: 1747646
    lab1 ls -l Child process id is: 1747647
    [vnath@storm lab1]$ lab1: cannot access 'ls': No such file or directory


1
2
3
4
5
6
7
8
9
10
11
12
 

    What output should be:
    steve@fish lab1]$ lab1 ls -l
    lab1 ls -l Child process pid is 7302
    total 30 
    -r-xr-xr-x 1 steve staff  3567 Aug 17 07:45 lab1
    -rwxr--r-- 1 steve staff   547 Aug 17 08:00 lab1.cpp
    -rw-r--r-- 1 steve staff 11291 Aug 17 08:15 lab1.html
    -rw-r--r-- 1 steve staff   621 Aug 17 09:59 linux.txt
    lab1 ls -l Parent process pid is 7301


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

    #include <iostream>
    #include <unistd.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
      int ppid = 0;
      int cpid = 0;
     
    
      pid_t pid = fork();
    
      if(pid == -1) // error handling
      {
        perror("fork");
        return 1; // added
      }
      if(pid == 0) // child process
      {
        //cpid = pid;
        cpid = getpid();
    
        for(int i = 0; i < argc; i++)
           cout << argv[i] << " ";
    
        cout << "Child process id is: " << cpid << endl;
    
      
        if(execvp(argv[1], argv) < 0)
        {
          perror("exec");
          return 1;
        }
      }
    
      if(pid > 0) // parent process
      {
        ppid = getpid();
    
        for(int i = 0; i < argc; i++)
           cout << argv[i] << " ";
    
        cout << "Parent process id is: " << ppid << endl;
      }
    
      return 0;
    }

                                                 
Last edited on
print out your command line args.
you will see that argv[0] is the program's name, not the first parameter passed in. This is useful info sometimes, and one of those weird things you just need to remember.
Last edited on
i know its the program name, so then shouldn't execvp (argv[0], argv) be correct? Since the parameters it requires is the filename and array. Also even when using execvp (argv[1], argv) I do not get the correct output
Last edited on
> Also even when using execvp (argv[1], argv) I do not get the correct output
argv is the start of the arguments for the parent process, not the start you want for your child process.

Try
execvp(argv[1], &argv[1])

salem, it works! thanks for the solution. Could you perhaps explain a bit further? Why is the reference used(as far as I remember they are used mostly since they are efficient and to modify the variable used in the call)? Is execvp(argv[1], argv[1]) incorrect?
¿why in your first example you have -ls as argument? (note the hyphen)

& is the address operator, &argv[1] will give you the address of the second element of the argv array
you pass that to execvp to signal the start of the argument array (equivalent to execvp(argv[1], argv+1))
1
2
3
4
5
./lab1 ls -l
argv_parent = {"./lab1", "ls", "-l"}

ls -l
argv_child = {"ls", "-l"}



> Is execvp(argv[1], argv[1]) incorrect?
given that it doesn't even compile, yes, that's incorrect.
ne555 yeah -ls -l is a typo that I thought I removed all instances of, guess I missed one. Thanks for the clarification also
Topic archived. No new replies allowed.