2014-11-27 7 views
0
  • 나는 다른 popen() 또한 dup()
  • STDOUT (PHP를 예를 들어 같은) 다른 프로세스에서 호출 프로그램 또는 SSH를 통해, 프로세스가 종료되지 않습니다를했습니다.

process_test.c : gcc process_test.cdup() 및 popen()이 다른 프로세스에서 호출 될 때 내 프로세스가 종료되지 않는 이유는 무엇입니까?

#include <stdio.h> 
#include <unistd.h> 

int main() { 
    int out; 

    out = dup(STDOUT_FILENO); 
    // close(out); 

    popen("sleep 10\0", "r"); 
} 

컴파일, 실행 :

  • ./a.out이 -> 정상적으로 종료
  • ruby -e 'system("./a.out");' -> 일반적으로
  • php -r passthry("./a.out");를 종료 ->는
  • 를 중단
  • ssh remotehost ./a.out - 나는 dup 표준 출력을하지 않거나 DUP를 닫을 때>는이 나에게 내가하고 싶은 동작을 보여줍니다 내가 찾을 수있는 가장 짧은 재현 코드

을 끊지 않고,

  • 를 중단 더 잘 이해하기.

    fork/pcntl/etc를 사용하여 여러 PHP 응용 프로그램/프레임 워크에서이를 추출하는 데 몇 시간이 걸렸습니다. 즉, 나는 이것을 쓴 것이 아니고 이것을 만들었다. 그러나 명백하게 그것의 전체의 감각은 내가 모든 것을 떼어 놓기 때문에 길을 잃었다.

    질문

    왜 어떤 호출이 (PHP, SSH) 끊지 않고 다른 없습니다 (루비)?
  • 이후에 fd 을 닫은 경우에도 내 프로그램이 중지됩니다. 왜?
  • 답변

    0
    ssh를 통해 stdoud에 DUP를 프로그램을 호출 할 때하는 것은 ssh를 만든 때문에

    , 그래서 ssh를 종료하려고 할 때이 표준 출력은 다른 채널을 열었습니다 할 수 있기 때문이다.

    나는 더 나은 대답을하려고합니다 : 올바르게 기억한다면 stdout은 채널 번호 1입니다. dup을 만들기 위해 stdout을 가리키는 새 채널 3도 있습니다. ssh가 채널 2 및 채널 2 (stdinput 및 stderr) togheter를 닫으려고 할 때 채널 3 이상을 차지하는 다른 자원이 있기 때문에 ssh를 닫을 수 없습니다.

    나는 그대로 내가 데모를 실행하면 그것이 충분히 명확 타노에게

    를 희망하고 나는 errno를 = 15 얻을 또는이 답변의 끝 부분에 설명 된대로 16 일 수있다. 나는 다른 방법으로 그것을 실행하는 경우 그러나이 : ​​

    #include <stdio.h> 
    #include <unistd.h> 
    #include <errno.h> 
    
    int main() { 
        int out; 
        int status; 
    
        out = dup(STDOUT_FILENO); 
        // close(out); 
        FILE *fp = popen("sleep 10\0", "r"); 
        status = pclose(fp); 
        if (status == -1) { 
          printf("pclose error: %d", errno); 
        } 
        close(out); 
    } 
    

    나는 더 이상 오류가 발생하지 않습니다. bash에서 오류를 검사하려면 다음을 사용하십시오. echo $?

    즉, c 프로그램을 종료하기 전에 할당 된 모든 자원을 재실행해야합니다.

    그게 전부입니다.

    최저 reagards 타노

    #define ENOTBLK  15 /* Block device required */ 
        #define EBUSY  16 /* Device or resource busy */ 
    
    +0

    나는 당신이 쓴 것을 읽을 수 있지만 문구 중 일부는 혼란 "... 0과 2 채널로을 togheter 채널 2를 닫습니다 ..."무슨 일이 있는지입니다 무슨 뜻이야? 그리고 질문 : 피 호출자 (ssh)가 프로세스가 수행하는 내부 세부 사항에 의존하는 이유는 무엇입니까? 예 : popup() 후에 sup도 빠져 나가지 않을 것이다. – mark

    +0

    필자는 내 질문에 대해 다시 한번 말하고 ** ** popen 후 fd **를 닫아도 상황을 설명하지 않고 끝내지 않을 것이라고 덧붙였다. – mark

    +0

    소스 코드를 보면 ssh 프로세스가 rlogin 또는 telnet과 같습니다 : 원격 프로그램과의 연결 및 설정을 시작한 후 원격 프로그램의 입력 채널에 매핑 된 ssh의 입력 채널이 있으므로 채널 1의 경우 2. ssh는 모든 채널이 열렸을 때 연결을 닫습니다 (예 : 0, 1, 2). 그래서 당신이 다른 작품을하기 위해서 1 채널을 복제했기 때문에 ssh는 그 프로세스가 끝나고 복제 된 채널 1을 닫을 때 끝날 것입니다. 설명하기가 매우 복잡해 보이는데 30 년 전 그런 행동을 많이했습니다 .... – gaetanoM