Utilice la función execlp en C

Jinku Hu 12 octubre 2023
Utilice la función execlp en C

Este artículo demostrará varios métodos sobre cómo utilizar la función execlp en C.

Utilice execlp para ejecutar un nuevo programa utilizando el nombre de archivo en C

La familia de funciones exec se proporciona como una API alternativa a la llamada al sistema execve de nivel inferior para gestionar la carga de un nuevo programa en la memoria del proceso. Hay 6 funciones separadas en esta familia y en su mayoría difieren en sus parámetros más que en el resultado. La función execlp es la que le da al usuario la opción de especificar el nombre del archivo y el programa se busca en directorios que se enumeran en la variable de entorno actual PATH.

Si el nombre del archivo aún contiene la barra, se trata como nombre de ruta relativo o absoluto. En el siguiente ejemplo, implementamos un programa que se comporta de manera similar a un shell. Es decir, toma el nombre del programa del usuario y lo ejecuta como un proceso hijo. El padre espera, y una vez que el hijo regresa, el control pasa a la siguiente iteración de la entrada del usuario. El programa debe ser terminado por el usuario con Ctrl+D como una pulsación de tecla (depende del sistema operativo). Tenga en cuenta que algunos comandos de shell no se pueden ejecutar y, lo más importante, los argumentos de la línea de comandos no se pasan, pero el programa imprime couldn't execute en su lugar.

#include <sys/wait.h>

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"

enum { MAXLINE = 256, MAXARGS = 48 };

int main(int argc, char *argv[]) {
  char buf[MAXLINE];
  pid_t pid;
  int status;

  char *str1, *token;

  printf("%% ");
  while (fgets(buf, MAXLINE, stdin) != NULL) {
    if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0;

    if ((pid = fork()) < 0) {
      perror("fork");
    } else if (pid == 0) {
      execlp(buf, buf, (char *)NULL);
      printf("couldn't execute: %s", buf);
      exit(127);
    }

    if (waitpid(pid, &status, 0) < 0) perror("waitpid");
    printf("%% ");
  }

  exit(EXIT_SUCCESS);
}

execlp es una función variada; por tanto, puede tomar un número variable de argumentos. Sin embargo, el primer y último argumento son fijos, representando el puntero al nombre del archivo y NULL convertido a char* correspondientemente. Tenga en cuenta que lanzar un puntero nulo es obligatorio para que la función funcione, y también denota el final de la variable número de argumentos. En resumen, los argumentos de la segunda posición deben especificar los argumentos de la línea de comandos para el programa, y ​​el primero de los cuales debe ser el nombre del archivo.

Alternativamente, podemos implementar el ejemplo anterior para poder ejecutar comandos con argumentos. En este caso, utilizamos la función execvp que toma la lista de argumentos como un array. Además, analizamos la entrada del usuario usando strtok para tomar cada cadena separada por espacios y pasarla como argumentos. Como resultado, obtenemos una emulación más cercana de un programa de shell.

#include <sys/wait.h>

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"

enum { MAXLINE = 256, MAXARGS = 48 };

int main(int argc, char *argv[]) {
  char buf[MAXLINE];
  char *args[MAXARGS];
  pid_t pid;
  int status, args_num = 0;

  char *str1, *token;

  printf("%% ");
  while (fgets(buf, MAXLINE, stdin) != NULL) {
    if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = 0;

    str1 = strdup(buf);
    for (int j = 0;; j++, str1 = NULL) {
      token = strtok(str1, " ");
      if (token == NULL) break;
      args[j] = token;
      args_num += 1;
      printf("%d: %s\n", j + 1, args[j]);
    }
    free(str1);
    args[args_num] = (char *)NULL;

    if ((pid = fork()) < 0) {
      perror("fork");
    } else if (pid == 0) {
      execvp(args[0], &args[0]);
      printf("couldn't execute: %s", buf);
      exit(127);
    }

    if (waitpid(pid, &status, 0) < 0) perror("waitpid");
    printf("%% ");
  }

  exit(EXIT_SUCCESS);
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artículo relacionado - C Process