2012-01-05 2 views
2

필자는 개발 중에 디버깅 정보가 stderr로 이동하기 전에 (완전히 '데몬 화'되기 전에) 데몬을 작성했습니다. 이제 코드가 더 성숙하므로 stderr이 /dev/null으로 freopen(2) 호출로 리디렉션되었습니다. 디버깅을 위해 서버 데몬에 연결하고 명령을 보내서 마술처럼 소켓을 통해 stderr 스트림을 보내도록하고 싶습니다.상위 프로세스의 stderr을 분기 된 프로세스의 소켓 파일 설명자로 리디렉션 할 수 있습니까?

아이의 소켓 파일 기술자에 부모 프로세스stderr에 동작처럼 'dup(2)'할 (갈래의 과정에서) 방법이 있나요? Linux 전용 솔루션을 사용할 수 있습니다.

stderr으로 인쇄 할 수있는 코드가 있습니다. 확인을 위해 입니다. - 나는 단순히 만지지 않습니다. dup2 내가 부탁 해요 무엇을 할 수 있다면

이 작동합니다 : Redirect STDOUT and STDERR to socket in C?

+0

당신은 그것을 FIFO로 보내고 그것을 netcating하는 것을 고려 했습니까? –

+0

질문에서 _child_ 및 _parent_ 토론에 혼란 스럽습니다. 서버'fork (2)'가 모든 클라이언트에 대해 자식을합니까? 이 생성 된 자식 중 하나에서 _parent's_ 디버깅 정보를 가져 오시겠습니까? – sarnold

+0

@sarnold 예 & 예. 부모의 디버깅 정보를 생성 된 자식 중 하나에 대해 얻고 싶습니다. – Jamie

답변

1

프로세스가 fork(2)이되면, 자식 및 부모 프로세스는 파일 설명자 테이블을 공유하지 않으므로 하나의 작업이 다른 작업에 영향을 미치지 않습니다. 리눅스 특정 clone(2) 시스템 호출은 프로세스가 CLONE_FILES을 사용하여 파일 디스크립터 테이블을 공유 할 수있게하며 파일 시스템 정보 (파일 시스템 루트, 현재 작업 디렉토리, umask)는 CLONE_NS과 공유 할 수 있습니다. clone(2)을 사용하면 용도에 맞게 너무 크게 작성 될 수 있습니다. 또한 평범하지 않아 작업이 성가시다.

또 다른 접근 방식 인 bmargulies suggests은 클라이언트에게 오류 정보를 읽는 포트를 connect(2)에게 알려주는 상위 프로세스의 "오류 서버"부분을 만드는 것입니다. TCP를 고수하면 네트워크를 통해 작동하지만 인증 및 인증 코드가 없으면 모두 열 수 있습니다. unix(7) 소켓을 사용하는 경우 SCM_CREDENTIALS 메시지를 사용하여 연결 프로세스의 사용자, 그룹 및 PID를 확인할 수 있습니다.

또한 fork(2) 전에 모든 아이의 pipe(2) 시스템 호출을 사용하여 새 pipe(7)을 만들고, 아이 디버깅 정보를 원하지 않을 경우 그냥 filedescriptors을 낭비 할 수있다.당신이 아이 통신에 부모를 제공하기 위해 unix(7) 소켓을 사용하는 경우

, 당신은 한 프로세스에서 다른 프로세스로 FileDescriptor에 보내도록 SCM_RIGHTS 메시지를 사용할 수 있습니다 - 당신은 부모가 보내 수 중 하나를 읽기 위해 아이에 pipe(7) 또는 socket(7) 또는 자녀에게 학부모에게 pipe(7) 또는 socket(7)을 보내달라고 요청하십시오.

+0

친절하고 유익한 대답으로 다루기 쉬운 제안. 고마워요! – Jamie

1

dup2 문제점은 무엇입니까?

부모의 경우 부모의 경우 socketconnect을 argv에 전달합니다. 파이프의 쓰기 측의 파일 디스크립터를 argv의 자식에게 건네 준다. 그런 다음 close(2)dup2(numberFromArgv, 2)?

또는 오류 서버의 포트 번호를 자식 (또는 하드 와이어)에 전달하고 socket, connectdup2을 호출하도록합니다.

생각해 보니, 여기서 가장 큰 문제는 'f'부분입니다. freopen을 호출 한 후에는 설명자 번호가 더 이상 '2'가 아닙니다. fileno으로 전화하여 번호를 얻은 다음 dup2을 사용하여 해당 번호로 소켓을 옮깁니다.

+0

나는 그것을 시도했다 (나는 생각한다. 대답의 간결함은 혼란 스럽다). 'dup2 (sockfd, STDERR_FILENO);를 호출 한 자식은 원하는 결과를주지 못합니다. 이것은 부모 프로세스에서'freopen ("/ dev/null", "w", stderr);하지 않은 코드에서 시도되었습니다. 그러나 부모에서'dup2 (STDOUT_FILENO, STDERR_FILENO);'를 수행하면 stdout에 대한 모든 디버깅 정보를 볼 수 있는데, fork 된 프로세스가 부모의 파일 설명자에서 작동하지 않는다고 생각하게되었습니다. – Jamie

+0

나는 여기서 "오류 서버"아이디어를 좋아하지만 잠재적으로 다른 클라이언트에도 오류 메시지를 표시합니다. – sarnold

2

상위 프로세스가 분기되면 하위 프로세스는 부모 프로세스의 모든 상태를 강제로 변경할 수 없습니다. 부모와 의사 소통을하고 표준 오류 출력을 쓰는 위치를 변경하도록 요청할 수 있지만, 부모는 부모에게 강제로 그렇게 할 수는 없습니다. 또한, 부모가 fork (보통)와 같이 소켓을 클라이언트에 대해 닫은 경우, 클라이언트와 쉽게 통신 할 수 없습니다.

프로세스간에 (소켓) 파일 설명자를 마이그레이션하는 방법이 있지만, 협조 프로세스이기도합니다. 해당 경로로 이동하려면이 page에 수행 할 작업에 대한 설명과 작업을 수행 할 클라이언트 측 및 서버 측 프로그램에 대한 링크가 있어야합니다. (AF_UNIX 소켓 연결이 필요하고 자식 데몬에 을 사용하고 부모 데몬에 recvmsg()을 사용합니다.이 설정을 사용하면 하위 데몬이 클라이언트의 소켓 연결을 상위 데몬으로 전달할 수 있으므로 상위 데몬은 dup2() 파일 디스크립터가 2 (표준 오류)로 수신 된 다음 원래의 디스크립터를 닫은 후 표준 오류 출력이 클라이언트로 전송됩니다.

이렇게하면 설치 프로그램과 (이미 설명한대로) 자식과 부모 데몬 프로세스가 있습니다. 실제로 직접 작성한 것은 아니므로, 프로세스의 함정을 잘 모릅니다. 적어도 유닉스 계열 시스템에서는 실제로 널리 사용 가능합니다.

+0

매우 유익한 정보 ... 감사합니다. – Jamie