3

I am using the exevcp system call in order to execute "ping www.google.com". However, when I execute the code below:

#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

using namespace std;

int main(int argc, char *argv[]){
    vector<char*> pingArgs;
    pingArgs.push_back("www.google.com");
    pingArgs.push_back(NULL);
    execvp("ping", &pingArgs[0]);
    return 0;
}

The below output is displayed, implying that I did not provide a link as an argument to the ping command. This seems strange, considering that in the vector which stores the arguments, I clearly added "www.google.com":

Usage: ping [-aAbBdDfhLnOqrRUvV64] [-c count] [-i interval] [-I interface]
            [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
            [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
            [-w deadline] [-W timeout] [hop1 ...] destination
Usage: ping -6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
             [-l preload] [-m mark] [-M pmtudisc_option]
             [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize]
             [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline]
             [-W timeout] destination
Chris
  • 26,361
  • 5
  • 21
  • 42
Adam Lee
  • 436
  • 1
  • 14
  • 49
  • This code will not compile in modern compilers. `"www.google.com"` is a string literal, which is implemented as a `const char[14]` array, which *decays* into a `const char*` pointer to the 1st `char`. You can't store a `const char*` pointer into a `std::vector` of `char*` pointers. In any case, there are other questions on StackOverflow that show how to use `execvp()` with `std::vector` correctly, for instance [How to pass a vector of strings to execv](https://stackoverflow.com/questions/5797837/), [How to pass a vector to execvp](https://stackoverflow.com/questions/5846934/), etc. – Remy Lebeau Oct 05 '21 at 23:19

1 Answers1

2
 vector<char*> pingArgs;
 pingArgs.push_back("www.google.com");
 pingArgs.push_back(NULL);

The first parameter to a program, it's argv[0], is the name of the program itself.

Here, you're merely informing the ping program that it's name is www.google.com, and it has no additional parameters.

 vector<char*> pingArgs;
 pingArgs.push_back("ping");
 pingArgs.push_back("www.google.com");
 pingArgs.push_back(NULL);

The first parameter to execvp is the executable to execute, but you still must provide all parameters separately.

However, all of the above is completely wrong anyway, for a tangential reason. In modern C++ string literals are const char *, and not char *. You must be using an ancient C++ compiler that either relaxes const-correctness when it comes to string literals or fails to implement it correctly, and I expect every modern C++ compiler to fail to compile the shown code for this unrelated reason.

Correctly doing this requires a little bit more work, in C++, but that's not directly related to the question you asked, and would be a separate question.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • "*string literals are `const char *`*" - technically, they are `const char[N]` arrays which *decay* into `const char*` pointers. – Remy Lebeau Oct 05 '21 at 23:21