Question

So I'm writing a program where the arguments are as follows:

program start emacs file.c

or even

program wait

In essence, the first argument (argv[0]) is the program name, followed by user inputs.

Inside my code, I invoke execvp. Thing is, I'm not entirely sure I'm invoking the right arguments.

if (pid == 0) { 
                    execvp(argv[1], argv); //Line of interest
                    exit(1);
                    }

are argv[1] and argv the correct arguments to pass for the functionality described above? I looked at the man page and they make sense but might not be correct for this case. Thank you!

Was it helpful?

Solution

In your main, argv will be like this in the first example:

argv[0] = "program";
argv[1] = "start";
argv[2] = "emacs";
argv[3] = "file.c";
argv[4] = NULL;

In execv you want to execute the program "start" with args "emacs file.c", right?. Then the first parameter should be argv[1] - "start" and the second one an array with this strings: {"start", "emacs", "file.c", NULL}. If you use argv, you include the "program" string in argv[0].

You can create a new array and copy these parameters or use the address of argv[1] like this:

execvp(argv[1], &argv[1]); //Line of interest

OTHER TIPS

The only thing that might be an issue is that argv[0] in argv passed to execvp won't match argv[1] (the first argument). Otherwise, it looks okay.

Imagine calling program cat file.txt. In your program, argv will be {"program", "cat", "file.txt", NULL}. Then, in cat, even though the binary called will be cat, argv will still be {"program", "cat", "file.txt", NULL}.

Since cat tries to open and read each argument as a file, the first file it'll try to open is cat (argv[1]), which isn't the desired behavior.

The simple solution is to use execvp(argv[1], argv+1) - this essentially shifts the argument array to the left by one element.

My understanding is that you want to take a specific action based on the second command-line argument (argv[1]). If the second argument is 'start', your program should start the executable named argv[2] with the arguments provided thereafter (right?). In this case, you should provide execvp with the executable name (argv[2]) [1] and a list of arguments, which by convention starts with the name of the executable (argv[2]).

execvp(argv[2], &argv[2]) would implement what we have described in the last paragraph (assuming this is what you intended to do).

[1] execvp expects 2 arguments as you know. The first is a filename; if the specified filename does not contain a slash character (/), execvp will do a lookup in the PATH environment variable (which contains a list of directories where executable files reside) to find the executable's fully-qualified name. The second argument is a list of command-line arguments that will be available to the program when it starts.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top