C/Linux

[C] execve()를 사용하여 execlp() 구현하기

김호록님 2023. 1. 3. 19:39

execlp() 구현하기

  • execve()를 이용하여 execlp()를 구현하시오.
  • 기존 execlp()와 겹치지 않도록 myexeclp() 함수로 구현할 것

가변인자 함수를 사용할 것

  • execlp()는 인자의 길이가 가변적임
  • 가변적 인자를 처리해주기 위해서는 stdarg(3)이 필요함
  • 인터넷에서 사용 예제를 검색해볼 것
  • 구현의 편의를 위해 인자의 최대 길이는 MAXARGS를 사용할 것

자체 테스트 방법

  • 환경변수 PATH로부터 경로명을 가져와 테스트해 볼 것
  • 파일이 있는지, 그 파일이 실행 가능한지 테스트해야 함
  • 제일 뒤의 경로명부터 테스트해야 함
  • 처음 실행할 수 있는 경로명에 있는 실행파일을 사용할 것

반환 값

  • 실패 시 -1 반환
#define _XOPEN_SOURCE
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAXARGS 31
#define MAXFILENAME 1024
#define MAXPATHSTR 5000

extern char **environ;
int myexeclp(const char *file, const char *args, ...) {
  va_list ap;
  char *vector[MAXARGS];
  va_start(ap, args);
  vector[0] = (char *)args;
  for (int i = 1; i < MAXARGS; i++) {
    if (args == NULL)
      vector[i] = (char *)0;
    else
      vector[i] = va_arg(ap, void *);
  }
  va_end(ap);

  if (execve(file, vector, environ) < 0) {
    fprintf(stderr, "myexeclp error\n");
    return -1;
  } else
    return 0;
}

int main(void) {
  char path[MAXPATHSTR];

  sprintf(path, "PATH=%s:%s", getcwd(NULL, 0), getenv("PATH"));
  putenv(path);

  // prepare the executable file named "hello"
  system("cp hello.tmp hello.c");
  system("clang -pthread -lm -o hello hello.c");
  system("rm hello.c");
    pid_t pid = fork();

  if (pid == 0) {
    printf("---MYEXECLP---\n");
    myexeclp("hello", "hello", "-a", "-b", "-c", (char *)0);
  } else {
    wait(NULL);
    printf("---ORIGINAL EXECLP---\n");
    execlp("hello", "hello", "-a", "-b", "-c", (char *)0);
  }

  return 0;
}