Differences between execv () and system () function in C

3

I'm doing a command interpreter in C and I have a problem with the execv function.

I use a method called readCommand to read a text string and divide it into an array with the command and parameters. Then I pass to the function execv the array of the form execv(params[0],params) but it gives me an error.

The thing is that if instead of doing execv I do system( ) everything is correct. Any suggestions?

I leave the code here:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX_LENGTH 256
#define DEFAULT_STRING_LENGTH  256
#define MAX_PARAMETERS  16


void  initParams(char  ***  params);
void  read_command(char  *** params);
void  freeParams(char  ***  params);
void type_prompt();
int comprobarSalir(char cadena[]);

int main(){

        int salir = 0;
        char ** params;
        int i;

        do{

                type_prompt();

                fflush(stdout);
                initParams (& params);
                read_command (& params);
                salir = comprobarSalir(params[0]);
                //execv(params [0],  params);
                if (execv(params [0],  params) ==  -1)
                       printf("Error  al  ejecutar  el  comando'%s':%s\n",params [0],  strerror(errno));
                       freeParams (& params);

        }while(salir==0);

        return  0;

}


void  read_command(char  *** args) {
        char  input [256], *substr;
        int n = 0;
        fgets(input , sizeof(input), stdin);
        input[strlen(input) -1] = '
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX_LENGTH 256
#define DEFAULT_STRING_LENGTH  256
#define MAX_PARAMETERS  16


void  initParams(char  ***  params);
void  read_command(char  *** params);
void  freeParams(char  ***  params);
void type_prompt();
int comprobarSalir(char cadena[]);

int main(){

        int salir = 0;
        char ** params;
        int i;

        do{

                type_prompt();

                fflush(stdout);
                initParams (& params);
                read_command (& params);
                salir = comprobarSalir(params[0]);
                //execv(params [0],  params);
                if (execv(params [0],  params) ==  -1)
                       printf("Error  al  ejecutar  el  comando'%s':%s\n",params [0],  strerror(errno));
                       freeParams (& params);

        }while(salir==0);

        return  0;

}


void  read_command(char  *** args) {
        char  input [256], *substr;
        int n = 0;
        fgets(input , sizeof(input), stdin);
        input[strlen(input) -1] = '%pre%';
        substr = strtok(input , " ");
        if (substr  != NULL)
                memcpy ((* args)[n], substr , strlen(substr));
        else
                (*args)[n] = NULL;
                n++;
        while ((* args)[n-1] != NULL) {
                substr = strtok(NULL , " ");
                if (substr  != NULL)
                        memcpy ((* args)[n], substr , strlen(substr));
                else
                        (*args)[n] = NULL;
                        n++;
        }
}

void  freeParams(char  *** params){
        int i;
        char ** parameter;
        for (i=0; i<MAX_PARAMETERS; i++) {
                parameter = ((* params) +i);
                if (* parameter  != NULL) free(* parameter);
        }
        free(* params);
        *params = NULL;
}


void  initParams(char  *** params) {
        int i, j;
        char ** parameter;
        *params = (char **) malloc(sizeof(parameter) * MAX_PARAMETERS);
        for (i = 0; i<MAX_PARAMETERS; i++) {
                parameter = (* params) + i;
                *parameter = (char*) malloc(DEFAULT_STRING_LENGTH);
                for (j = 0; j<DEFAULT_STRING_LENGTH; j++)  *((* parameter)+j) = '%pre%';
        }
}

void type_prompt(){
                char cwd[1024];
        getcwd(cwd, sizeof(cwd));
        printf("%s$ ",cwd);
}

int comprobarSalir(char cadena[]){

        int salir = 0;

        if((cadena[0]=='e')&&(cadena[1]=='x')&&(cadena[2]=='i')&&(cadena[3]=='t')){
                salir = 1;
        }

        return salir;
}
'; substr = strtok(input , " "); if (substr != NULL) memcpy ((* args)[n], substr , strlen(substr)); else (*args)[n] = NULL; n++; while ((* args)[n-1] != NULL) { substr = strtok(NULL , " "); if (substr != NULL) memcpy ((* args)[n], substr , strlen(substr)); else (*args)[n] = NULL; n++; } } void freeParams(char *** params){ int i; char ** parameter; for (i=0; i<MAX_PARAMETERS; i++) { parameter = ((* params) +i); if (* parameter != NULL) free(* parameter); } free(* params); *params = NULL; } void initParams(char *** params) { int i, j; char ** parameter; *params = (char **) malloc(sizeof(parameter) * MAX_PARAMETERS); for (i = 0; i<MAX_PARAMETERS; i++) { parameter = (* params) + i; *parameter = (char*) malloc(DEFAULT_STRING_LENGTH); for (j = 0; j<DEFAULT_STRING_LENGTH; j++) *((* parameter)+j) = '%pre%'; } } void type_prompt(){ char cwd[1024]; getcwd(cwd, sizeof(cwd)); printf("%s$ ",cwd); } int comprobarSalir(char cadena[]){ int salir = 0; if((cadena[0]=='e')&&(cadena[1]=='x')&&(cadena[2]=='i')&&(cadena[3]=='t')){ salir = 1; } return salir; }
    
asked by Pablo González 16.12.2016 в 23:52
source

1 answer

4

Function system ()

The function system() allows us to perform the execution of a system command, so that the output of this can not be saved in a variable, but the return of this function will be the value returned by the command.

The prototype of the function is:

int system(const char *command)

Where the int that this function returns to us, can be a value equal to zero (0) if the command was executed successfully, or non-zero! (0) if the command could NOT be executed successfully.

This function is in the header:

#include <stdlib.h> - > C

#include <cstdlib> - > C ++

Example:

C

#include <stdio.h>
#include <stdlib.h>

int main(void){

    int retorno = system("ls");

    printf("Resultado: %d\n", retorno);

    return EXIT_SUCCESS;
}

C ++

#include <iostream>
#include <cstdlib>

using namespace std;

int main(void){

    int retorno = system("ls");

    cout << "Resultado:" << retorno << endl;

    return EXIT_SUCCESS;
}

The result of the execution (of both examples) is:

main  main.cpp                                                                                                                                                                                                
Resultado:0 

Execv () function

This function allows us to perform the execution of commands, just as system() does not allow us to save the output of the command in a variable. Unless it has a difference with system() . If execv() returns some value, execv() had an error.

The prototype of the function is:

int execv(const char *path, char *const argv[]);

The int that this function returns to us (In case it returns) is always -1.

That is, after a command is executed with execv() your main program ends after the execution of this.

This function is in the header:

#include <unistd.h> - > C / C ++

Before looking at the example, you must take into account that the following parameters are passed to the execv () function:

  • Path to the executable, eg: "/bin/ls"
  • An array that must contain, as the first element, the path of the executable, and as a last NULL, leaving in the middle the parameters that will be passed to your executable, eg: {"/bin/ls", "-l", NULL}
  • Example:

    C

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main(void){
    
        char *argumentos[] = {"/bin/ls", "-l", NULL}; 
    
        execv("/bin/ls", argumentos);
    
        printf("Termino!!!");
    
        return EXIT_SUCCESS;
    }
    

    C ++

    #include <iostream>
    #include <cstdlib>
    #include <unistd.h>
    
    using namespace std;
    
    int main(void){
    
        char *argumentos[] = {"/bin/ls", "-l", NULL}; 
    
        execv("/bin/ls", argumentos);
    
        cout << "Termino!!!" << endl;
    
        return EXIT_SUCCESS;
    }
    

    The result of the execution (of both examples) is:

    total 16                                                                                                                                                                                                      
    -rwxr-xr-x 1 35878 35878 9221 Mar 14 00:23 main                                                                                                                                                               
    -rw-r--r-- 1 35878 35878  329 Mar 14 00:23 main.cpp   
    

    You have noticed that the message "Termino!!!" , does not appear anywhere, is where the difference between these functions lies, while system() continues the execution of your program, execv() continues the execution of the program that you you indicate and your main program does not end.

    I hope it helps you

    References:

    system ()

    execv ()

        
    answered by 14.03.2017 / 01:34
    source