Pregunta

Me gustaría preparar un vector de argumento de la vieja escuela (argv) a utilizar dentro de la función

  

int execve (const char * nombre, char   * Const argv [], char * const envp []);

Lo he probado con la clase STL :: vector:

std::string arguments = std::string("arg1");    
std::vector<char*> argv; 
char argument[128];
strcpy(argument, arguments.c_str());
argv.push_back(argument); 
argv.push_back('\0'); // finish argv with zero

Por último paso el vector a execve ()

  

execve ( "bashscriptXY", y argv [0], NULL)

El código se compila pero se ARGV "ignorado" por execve (). Por lo tanto, parece estar mal, lo que estoy tratando. ¿Cómo debo construir un ARGV de una manera eficiente con C ++?

¿Fue útil?

Solución

Creo que el char [128] es redundante, ya que la cadena local tendrá la misma vida, también, trate de añadir el programa como argv [0] como rossoft dijo en su respuesta:

const std::string arguments("arg1");    
std::vector<const char*> argv;

argv.push_back("bashscriptXY");
// The string will live as long as a locally allocated char*
argv.push_back(arguments.c_str()); 
argv.push_back(NULL); // finish argv with zero

execve(argv[0], &argv[0], NULL);

Otros consejos

Tenga en cuenta que argv[0] es siempre el nombre del comando en sí. Así que si quieres pasar 1 parámetro para un programa, usted tiene que llenar dos elementos:

argv[0] debe ser "bashscriptXY" (o lo que quieras ...)
 argv[1] = "your_argument"

Un par de cuestiones:

  • el primer elemento de la matriz argv se supone que es el nombre del programa
  • argv el vector puede tomar tipos char const* como execve() no modifica los argumentos (aunque el proceso que se invoca puede - pero los habrá copias en su propio espacio de direcciones). Para que pueda empujar cadenas c_str() en la misma. (ver comentarios)

Trate de hacer esto:

// unfortunately, execve() wants an array of `char*`, not
//  am array of `char const*`.
//  So we we need to make sure the string data is 
//  actually null terminated
inline
std::string& null_terminate( std::string& s)
{
    s.append( 1, 0);
    return s;
}

// ...

std::string program = std::string( "bashscriptXY");
std::string arg1("arg1");
std::string arg2("arg2");

null_terminate(program);
null_terminate(arg1);
null_terminate(arg2);

std::vector<char *> argv; 

argv.push_back( &program[0]);
argv.push_back( &arg1[0]); 
argv.push_back( &arg2[0]); 
argv.push_back( NULL); // finish argv with zero

intptr_t result = execve( program.c_str(), &argv[0], NULL);

A menos que los argumentos están codificadas, que tendrá que hacer algo de asignación de memoria dinámica. En primer lugar, crear una matriz de punteros a carácter para el número de argumentos, a continuación, asignar memoria para cada argumento y copiar los datos en.

Esta pregunta es muy similar e incluye algunas de las soluciones de código.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top