2010-12-15 2 views
3

여기에 문제가 있습니다 : 클라이언트로부터 요청을 받고, 요청으로 인해 (일부 모듈에서) 함수를 실행하는 데몬을 가지고 있습니다. 클라이언트. fork() 후에 STDIN, STDOUT 및 STDERR을 닫습니다. 하나의 기능은 dmesg를 검사하는 것입니다. 이를 위해 을 통해 dmesg 출력을 엽니 다 (DMESG, "/ bin/dmesg |"). 필자는 함수가 끝난 후 자동으로 닫힐 것이라고 생각했기 때문에이 fh를 읽은 후에이 fh를 닫지 않습니다. 그러나 이것은 일어나지 않으며 dmesg를 호출 할 때마다 좀비가 생깁니다.Perl : close()없이 open()을 통해 좀비 생성하기

How can I reinitialize Perl's STDIN/STDOUT/STDERR? "다시 열지 말고 STDOUT을 닫을 때의 문제점은 다른 파일을 열면 fd가 0,1 또는 2가되어 나중에 STDOUT을 다시 열 수 없게된다는 것입니다." 에 의해 jmanning2k 그리고 나는 그것과 관련이 있다고 생각하지만 실제로 얻지는 않습니다. 나는 누군가가 그것을 나에게 설명 할 수 있기를 바란다.

나는이 문제를 피할 수 있음을 안다. qx()를 통해 dmesg를 호출하여; 또는 간단히 fh를 닫으면 좀비가 어디에서 왔는지 이해하고 싶습니다. 내가 그것을 완성 기능 후 자동으로 닫 것이라고 생각했기 때문에

답변

6

형태

open DMESG, "/bin/dmesg|"; 

파이프 열리고 동적 변수를 DMESG 범위에 할당. 동적으로 범위가 지정된 변수는 실제로 Perl에서 "영원히"살며 local이 나타날 때마다 필요에 따라 저장됩니다.

대신 양식을 사용하는 경우

open my $dmesg, "/bin/dmesg|"; 

어휘 핸들 변수 $dmesg (즉, 그것이 다시하거나 전달에 저장되지 살아 그것을 유지하는 다른 이유가없는 가정, 범위 출구에 종료됩니다 전역 변수).

+0

감사합니다. 그것을 설명하기위한 것입니다. – olo

5

open(DMESG, "/bin/dmesg |") 나는 그것에서 읽은 후이 FH를 닫지 마십시오.

이 작업을하려면 핸들이 어휘 적이어야하므로 범위를 벗어날 수 있습니다.

open my $dmesg, … 
+0

아하하스 오른쪽. 덕분에 – olo

1

문제는 Perl 소스 자체와 관련이 있습니다. 다음 파일 doio.c의 기능 Perl_do_openn에서 코드 조각의 : 기존 파일 핸들을 열 경우

fd = PerlIO_fileno(IoIFP(io)); 
if (IoTYPE(io) == IoTYPE_STD) { 
    /* This is a clone of one of STD* handles */ 
    result = 0; 
} 
else if (fd >= 0 && fd <= PL_maxsysfd) { 
    /* This is one of the original STD* handles */ 
    saveifp = IoIFP(io); 
    saveofp = IoOFP(io); 
    savetype = IoTYPE(io); 
    savefd = fd; 
    result = 0; 
} 

, 파일 핸들)을 (개방에 의해 폐쇄 및 재개 될이 이 성병 발생하지 않습니다 * 핸들은 위의 코드에서 볼 수 있습니다. 그래서 perl은 다음 자유 핸들을 열어 이전 핸들을 열어 둡니다.