How to Use the execlp Function in C

Jinku Hu Feb 02, 2024
How to Use the execlp Function in C

This article will demonstrate multiple methods about how to use the execlp function in C.

Use execlp to Execute a New Program Using Filename in C

exec family of functions are provided as an alternative API to the lower level execve system call to manage the loading of a new program into process memory. There are 6 separate functions in this family and they mostly differ in their parameters rather than result. execlp function is the one that gives the user option to specify the filename and the program is searched in directories that are listed the current PATH environment variable.

If the filename still contains the slash, it’s treated relative or absolute pathname. In the following example, we implement a program that behaves similarly to a shell. Namely, it takes the program name from the user and executes it as a child process. The parent waits, and once the child returns, the control goes to the next iteration of the user input. The program should be terminated by the user with Ctrl+D like keystroke (depends on the operating system). Notice that some shell commands can’t be executed, and most importantly, the command line arguments are not passed, but the program prints couldn't execute instead.

#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 is a variadic function; thus, it can take a variable number of arguments. The first and the last arguments are fixed though, representing the pointer to the filename and NULL cast to the char* correspondingly. Note that casting a null pointer is mandatory for the function to work, and it also denotes the ending of the variable number of arguments. In short, the second position’s arguments should specify the command line arguments for the program, and the first of which should be the filename itself.

Alternatively, we can implement the previous example to be able to execute commands with arguments. In this case, we utilized the execvp function that takes the argument list as an array. Also, we parsed the user input using strtok to take each space-separated string and pass them as arguments. As a result, we get closer emulation of a shell program.

#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);
}
Author: 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

Related Article - C Process