C에서 execlp 함수 사용

Jinku Hu 2023년10월12일
C에서 execlp 함수 사용

이 기사에서는 C에서execlp함수를 사용하는 방법에 대한 여러 방법을 보여줍니다.

execlp를 사용하여 C 파일 이름을 사용하여 새 프로그램 실행

exec 함수 계열은 새 프로그램을 프로세스 메모리로로드하는 것을 관리하기 위해 하위 수준execve 시스템 호출에 대한 대체 API로 제공됩니다. 이 제품군에는 6 개의 별도 기능이 있으며 결과보다는 매개 변수가 대부분 다릅니다. execlp 함수는 사용자에게 파일 이름을 지정할 수있는 옵션을 제공하는 기능으로 현재PATH 환경 변수가 나열된 디렉토리에서 프로그램을 검색합니다.

파일 이름에 여전히 슬래시가 포함되어 있으면 상대 또는 절대 경로 이름으로 처리됩니다. 다음 예제에서는 쉘과 유사하게 동작하는 프로그램을 구현합니다. 즉, 사용자로부터 프로그램 이름을 받아 자식 프로세스로 실행합니다. 부모는 기다렸다가 자식이 반환되면 컨트롤은 사용자 입력의 다음 반복으로 이동합니다. 프로그램은 사용자가 키 입력과 같은 Ctrl+D를 사용하여 종료해야합니다 (운영 체제에 따라 다름). 일부 셸 명령은 실행할 수 없으며 가장 중요한 것은 명령 줄 인수가 전달되지 않지만 프로그램은 대신 couldn't execute을 인쇄합니다.

#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는 가변 함수입니다. 따라서 가변 개수의 인수를 사용할 수 있습니다. 그러나 첫 번째와 마지막 인수는 고정되어 파일 이름에 대한 포인터를 나타내고 그에 따라char*에 대한NULL 캐스트를 나타냅니다. 함수가 작동하려면 null 포인터를 캐스팅해야하며 가변 인수 개수의 끝을 나타냅니다. 간단히 말해서 두 번째 위치의 인수는 프로그램의 명령 줄 인수를 지정해야하며 첫 번째는 파일 이름 자체 여야합니다.

또는 인수로 명령을 실행할 수 있도록 이전 예제를 구현할 수 있습니다. 이 경우 인수 목록을 배열로 취하는execvp함수를 사용했습니다. 또한strtok를 사용하여 사용자 입력을 구문 분석하여 공백으로 구분 된 각 문자열을 인수로 전달했습니다. 결과적으로 우리는 쉘 프로그램을 더 가깝게 에뮬레이션합니다.

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

관련 문장 - C Process