programing

stdout 및 stdin 파일 설명자를 닫은 후 다시 열기

lovejava 2023. 10. 26. 20:26

stdout 및 stdin 파일 설명자를 닫은 후 다시 열기

인수가 주어지면 stdout을 파일로 리디렉션하거나 파일에서 stdin을 읽어오는 함수를 씁니다.이렇게 하려면 stdout 또는 stdin과 관련된 파일 설명자를 닫아서 파일을 열 때 방금 닫았던 설명자 아래에서 열립니다.이것은 효과가 있지만 문제는 이것이 완료되면 stdout과 stdin을 실제 상태로 복원해야 한다는 것입니다.

stdout에 대해 내가 할 수 있는 일은 열려 있습니다("/dev/tty", O_WRONLY). 하지만 왜 이것이 작동하는지 잘 모르겠고, 더 중요한 것은 stdin에 대한 동등한 문에 대해 알지 못합니다.

그래서 나는 포레스트 아웃을

close(1);
if (creat(filePath, O_RDWR) == -1)
{
    exit(1);
}

그리고 fortdin

close(0);
if (open(filePath, O_RDONLY) == -1)
{
    exit(1);
}

dup() 및 dup2()를 사용하여 파일 설명자를 복제해야 합니다.

int stdin_copy = dup(0);
int stdout_copy = dup(1);
close(0);
close(1);

int file1 = open(...);
int file2 = open(...);

< do your work. file1 and file2 must be 0 and 1, because open always returns lowest unused fd >

close(file1);
close(file2);
dup2(stdin_copy, 0);
dup2(stdout_copy, 1);
close(stdin_copy);
close(stdout_copy);

그러나 주의해야 할 작은 세부 사항이 있습니다(맨투맨에서).

두 디스크립터는 파일 디스크립터 플래그(실행 근접 플래그)를 공유하지 않습니다.실행 시 근접 플래그(FD_CLOEXEC; fcntl(2))에서 중복 설명자가 꺼져 있습니다.

이 문제가 발생하면 실행 시 근접 플래그를 복원해야 할 수도 있습니다. 경합 조건을 피하기 위해 dup2() 대신 dup3()을 사용할 수도 있습니다.

또한 프로그램이 다중 스레드인 경우 다른 스레드가 실수로 재매핑된 stdin/stdout에 기록/판독할 수 있습니다.

다음과 같이 리디렉션하기 에 설명자를 "저장"할 수 있습니다.

int save_in, save_out;

save_in = dup(STDIN_FILENO);
save_out = dup(STDOUT_FILENO);

나중에 사용할 수 있습니다.dup2복원 방법:

/* Time passes, STDIN_FILENO isn't what it used to be. */
dup2(save_in, STDIN_FILENO);

나는 그 예에서 오류 검사를 하지 않을 것입니다 - 당신은 그렇게 해야 합니다.

하위 프로세스를 생성하고 하위 프로세스 내부에서만 리디렉션을 설정할 수 있습니다.그런 다음 자식이 종료될 때까지 기다렸다가 부모 프로세스에서 작업을 계속합니다.그렇게 하면 방향 전환에 대해 전혀 걱정할 필요가 없습니다.

fork()를 사용한 코드의 예를 찾아보고() 기다립니다.

언급URL : https://stackoverflow.com/questions/9084099/re-opening-stdout-and-stdin-file-descriptors-after-closing-them