SYSTEM(3)

이름
system - shell 명령어 실행하기

사용법
#include <stdlib.h>

int system (const char * string);

설명
system() 함수는 /bin/sh -c string를 호출하여 string 에 지정된 명령어를 실행하며, 명령어가 끝난후 반환된다. 명령어가 실행되는 동안, SIGCHLD 는 블럭되며, SIGINT 그리고 SIGQUIT 는 무시된다.

반환값
리턴된 값은 만일 /bin/sh 을 위한 execve() 호출이 실패한다면, 리턴된 값은 127 이며, 다른 에러가 있다면 -1, 그렇지 않으면 명령어의 리턴코드가 반환된다.

string 값이 NULL이라면, system() 은 shell을 이용할수 있다면 0 이 아닌 값을, 그렇지 않으면 0 값을 반환한다.

system() 은 어떤 다른 자식의 wait 상태에 영향을 주지 않는다.

호환
ANSI C, POSIX.2, BSD 4.3

버그

libc 버전의 system() 이 인터럽트를 무시한다는 것은 매우 불행한 일이다. 이것은 함수 후출시 루프에서 인터럽트할수 없게 되도록 프로그램을 만든다. 이것은 그런 목적의 프로그램은 system() 이 아닌 개인 버전의 함수를 사용해야 한다.(경고: 테스트된 코드가 아니다!)
int my_system (const char *command) {
    int pid, status;
    if (command == 0)
        return 1;
    pid = fork();
    if (pid == -1)
        return -1;
    if (pid == 0) {
        char *argv[4];
        argv[0] = "sh";
        argv[1] = "-c";
        argv[2] = command;
        argv[3] = 0;
        execve("/bin/sh", argv, environ);
        exit(127);
    }
    do {
        if (waitpid(pid, &status, 0) == -1) {
            if (errno != EINTR)
                return -1;
        } else
            return status;
    } while(1);
}

suid 나 sgid 우선권이 있는 프로그램에서는 system() 을 사용하지 마라. 왜냐하면 몇몇 환경 변수들을 위한 이상한 값들이 시스템을 오작동시킬수 있기 때문이다. 대신에 exec(3) 계열의 함수를 사용해라. 그러나 execlp(3) 나 execvp(3)은 제외해라. 사실 system() 함수는 /bin/sh 이 bash 버전 2인 시스템에서 suid 나 sgid 우선권이 있는 프로그램에서는 잘 작동하지 않는다. 왜냐하면 bash 2는 시작시 우선권을 없애기 때문이다. (Debian은 sh처럼 구동시 이것을 하지 않는 수정된 bash를 사용한다.)

/bin/sh 의 유용성 검사는 실제적으로는 행해지지 않는다; 항상 유효하다고 가정한다. ISO C는 검사를 지정하지만, POSIX.2는 리턴 값은 항상 0 이 아닌 값이어야 한다고 지정한다. 왜냐하면 shell이 없는 시스템은 행해져서는 안되기 때문이다.

반환 값 127은 shell 명령어에서 가능하다. 그러므로 이 반환 값은 execve() 가 실패했다는것을 확실히 가리키지 않는다; 확신을 위해 errno 를 검사해라.

관련 항목
sh(1), signal(2), exec(3)

역자
정강훈 <skyeyes@soback.kornet.net>, 2001년 3월 12일