Uso de funciones de la serie exec (execl, execlp, execle, execv, execvp)

Uno, el ejecutivo reemplaza la imagen del proceso

Unix utiliza un método único en la creación de procesos, que separa la creación de procesos de la carga de una nueva imagen de proceso. La ventaja de esto es que hay más espacio para administrar las dos operaciones.

Cuando creamos un proceso, normalmente reemplazamos el proceso hijo con una nueva imagen de proceso, lo que se puede hacer con la serie de funciones exec. Por supuesto, la serie de funciones ejecutivas también puede reemplazar el proceso actual.

Por ejemplo: ejecutar el comando ps en la línea de comandos del shell es en realidad el proceso del shell que llama a fork para copiar un nuevo proceso hijo, y usar la llamada al sistema exec para reemplazar completamente el proceso hijo recién generado con el proceso ps.

2. funciones de la serie exec (execl, execlp, execle, execv, execvp)

Incluya el archivo de encabezado <unistd.h>

Características:

用exec函数可以把当前进程替换为一个新进程,且新进程与原进程有相同的PID。exec名下是由多个关联函数组成的一个完整系列,
 头文件<unistd.h>

extern char **environ;

原型:

int execl(const char *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(const char *path, const char *arg, ..., char * const envp[]);

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

int execvp(const char *file, char *const argv[]);

parámetro:

El parámetro de ruta indica el nombre del programa que desea iniciar, incluido el nombre de la ruta

El parámetro arg representa los parámetros del programa de inicio. Generalmente, el primer parámetro es el nombre del comando a ejecutar, no con una ruta y arg debe terminar con NULL.

Valor de retorno: devuelve 0 en caso de éxito, devuelve -1 en caso de error

Nota: La capa inferior de la serie de funciones ejecutivas mencionadas anteriormente se implementa a través de la llamada al sistema execve:

       #include <unistd.h>

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

DESCRIPTION:
       execve() executes the program pointed to by filename.  filename must be
       either a binary executable, or a script starting with  a  line  of  the form

La diferencia entre la serie ejecutiva de funciones anterior:

1. La función exec con l: execl, execlp, execle, lo que significa que los siguientes parámetros se dan en forma de parámetros variables y todos terminan con un puntero nulo.

Ejemplo:

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

int main(void)
{
    
    
    printf("entering main process---\n");
    execl("/bin/ls","ls","-l",NULL);
    printf("exiting main process ----\n");
    return 0;
}

Utilice execl para reemplazar el proceso principal actual, y no se mostrarán todas las últimas declaraciones de impresión.

2. La función exec con p: execlp, execvp, lo que significa que la ruta del primer parámetro no necesita ingresar la ruta completa, solo se puede dar el nombre del comando, y buscará el comando en la variable de entorno PATH

Ejemplo:

Cuando no hay p pero no se proporciona la ruta completa: el
resultado mostrará el error execl: NO existe tal archivo o directorio,
por lo que el reemplazo de la imagen del proceso no es exitoso, el proceso principal continúa ejecutándose y se genera el proceso principal saliente -

Cuando no se proporciona la ruta completa con p:
salida que ingresa al
proceso principal, y la salida de ejecución de ls -l, el reemplazo del espejo del proceso es exitoso y el proceso principal no continúa la ejecución;

3. La función exec sin l: execv, execvp significa que los parámetros requeridos por el comando se dan en forma de char * arg [] y el último elemento de arg debe ser NULL

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

int main(void)
{
    
    
    printf("entering main process---\n");
    int ret;
    char *argv[] = {
    
    "ls","-l",NULL};
    ret = execvp("ls",argv);
    if(ret == -1)
        perror("execl error");
    printf("exiting main process ----\n");
    return 0;
}

Reemplazo del proceso exitoso

4. La función exec con e: execle significa que la variable de entorno se pasa al proceso que necesita ser reemplazado

Del prototipo de función anterior, encontramos:

carácter externo ** aproximadamente;

El entorno aquí es una matriz de punteros, y el carácter al que apunta cada puntero es "XXX = XXX".

Los datos guardados por medio ambiente pueden verse mediante el comando env;

//test程序二进制位test
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    
    
    //char * const envp[] = {"AA=11", "BB=22", NULL};
    printf("Entering main ...\n");
    int ret;
    ret =execle("./hello", "hello", NULL);
    //execle("./hello", "hello", NULL, envp);
    if(ret == -1)
        perror("execl error");
    printf("Exiting main ...\n");
    return 0;
}
//hello.c文件编译为hello可执行的程序
#include <unistd.h>
#include <stdio.h>
extern char** environ;

int main(void)
{
    
    
    printf("hello pid=%d\n", getpid());
    int i;
    for (i=0; environ[i]!=NULL; ++i)
    {
    
    
        printf("%s\n", environ[i]);
    }
    return 0;
}

La salida después de ejecutar la prueba es la variable de entorno vista bajo el comando env bajo el shell, se puede ver que cuando se usa execle, la variable de entorno se pasará al nuevo proceso;

Tres, el papel del logotipo FD_CLOEXEC en la función fcntl () en la serie de funciones exec

#include <unistd.h>
#include <fcntl.h>

int fcntl (int fd, int cmd,… / * arg * /);

Banderas del descriptor de archivo
Los siguientes comandos manipulan las banderas asociadas con un
descriptor de archivo . Actualmente, solo se define uno de estos indicadores: FD_CLOEXEC, el indicador de
cierre al ejecutar . Si el bit FD_CLOEXEC es 0, el descriptor de archivo
permanecerá abierto en un execve (2), de lo contrario se cerrará.

 //如果FD_CLOEXEC标识位为0,则通过execve调用后fd依然是打开的,否则为关闭的

  F_GETFD (void)
         Read the file descriptor flags; arg is ignored.

  F_SETFD (long)
         Set the file descriptor flags to the value specified by arg.

如 : fcntl (fd, F_SETFD, FD_CLOEXEC);

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
    
    

    printf("Entering main ...\n");
    int ret = fcntl(1, F_SETFD, FD_CLOEXEC);
    if (ret == -1)
        perror("fcntl error");
    int val;
    val =execlp("ls", "ls","-l", NULL);
    if(val == -1)
        perror("execl error");
    printf("Exiting main ...\n");
    return 0;
}

Como en el código anterior, la salida estándar 1 se desactiva debido al indicador FD_CLOEXEC de fcntl, y la salida de ls -l de execlp se informa como una descripción de archivo incorrecta;

Enlace de referencia:
https://www.cnblogs.com/mickole/p/3187409.html

Supongo que te gusta

Origin blog.csdn.net/sun172270102/article/details/109892085
Recomendado
Clasificación