IT이야기

C에서 stdin 및 stdout 재라우팅

cyworld 2022. 5. 4. 21:43
반응형

C에서 stdin 및 stdout 재라우팅

다시 열고 싶다.stdin그리고stdout(그리고 아마도)stderr내가 하고 있는 동안) 파일들을 처리해서, 나중에 다시 전화해서printf()또는putchar()또는puts()파일에 저장될 것이며, 향후에 에 대한 호출이 있을 것이다.getc()파일로부터 그런 것이 나올 것이다.

1) 표준 입력/출력/오류를 영구적으로 잃고 싶지 않다.나는 나중에 프로그램에서 그것들을 재사용하고 싶을지도 모른다.

2) 새로운 파일 핸들을 열고 싶지는 않다. 왜냐하면 이 파일 핸들은 많이 돌려야 하거나 글로벌하게(흔들려야 하기 때문이다.

3) 하나도 안쓰는데open()또는fork()어쩔 수 없는 경우 시스템 의존적 기능.

따라서 기본적으로 다음과 같은 작업을 수행할 수 있는가?

stdin = fopen("newin", "r");

그리고, 만약 그렇다면, 어떻게 하면 원래의 가치를 얻을 수 있을까?stdin다시? 보관해야 하나?FILE *나중에 다시 돌려받을 수 있을까?

왜 사용하는가?C89 규격에는 다음 섹션의 내주 중 하나에 답이 있다.<stdio.h>:

116. 함수의 주요 용도는 표준 텍스트 스트림(,stderr 또는 )과 관련된 파일을 변경하는 것이다. 이러한 식별자는 함수에 의해 반환된 값이 할당될 수 있는 수정 가능한 lvalue가 될 필요가 없기 때문이다.

freopen예를 들어, 일반적으로 잘못 사용된다.stdin = freopen("newin", "r", stdin);. 이것은 더 이상 휴대할 수 없다.fclose(stdin); stdin = fopen("newin", "r");. 두 표현 모두 할당을 시도함stdin할당 가능한 것으로 보장되지 않는.

올바른 사용 방법freopen할당을 생략하는 경우:freopen("newin", "r", stdin);

freopen("/my/newstdin", "r", stdin);
freopen("/my/newstdout", "w", stdout);
freopen("/my/newstderr", "w", stderr);

... do your stuff

freopen("/dev/stdin", "r", stdin);
...
...

이게 내 원형-페그-제곱 구멍-오미터에 바늘을 꽂는 거잖아, 뭘 하려고 그래?

편집:

stdin, stdout 및 stderr는 새로 생성된 모든 프로세스의 파일 설명자 0, 1, 2라는 점을 기억하십시오.freopency는 같은 fd를 유지해야 하고, 그냥 새로운 스트림을 그들에게 할당해야 한다.

따라서, 이것이 실제로 여러분이 원하는 것을 하고 있는지 확인하는 좋은 방법은 다음과 같다.

printf("Stdout is descriptor %d\n", fileno(stdout));
freopen("/tmp/newstdout", "w", stdout);
printf("Stdout is now /tmp/newstdout and hopefully still fd %d\n",
   fileno(stdout));
freopen("/dev/stdout", "w", stdout);
printf("Now we put it back, hopefully its still fd %d\n",
   fileno(stdout));

나는 이것이 freopen()의 예상된 행동이라고 믿는다. 보시다시피, 당신은 여전히 세 개의 파일 설명자(및 관련 스트림)만 사용하고 있다.

이것은 셸이 리디렉션할 것이 없기 때문에 어떤 셸 리디렉션보다 우선할 것이다.하지만, 그것은 아마도 파이프를 망가뜨릴 것이다.프로그램이 파이프의 차단 끝(FIFO, 파이프가 아님)에 있는 경우 SIGPINE용 핸들러를 설정해야 할 수 있다.

그래서 ./your_program --stdout /tmp/stdout.txt --stderr /tmp/stderr.txt는 freopency와 동일한 실제 파일 설명자를 유지하여 쉽게 달성되어야 한다.내가 이해할 수 없는 건 왜 한번 바꾸면 다시 넣어야 하는 거야?확실히, 만약 누군가가 어떤 옵션을 통과했다면, 그들은 프로그램이 종료될 때까지 그것이 지속되기를 원했을까?

이런 걸 찾고 있는 것 같은데.

이것은 Tim Post의 방법을 수정한 버전이다. 나는 /dev/stdout 대신 /dev/tty를 사용했다.stdout(/proc/self/fd/1)과 연동되지 않는 이유를 모르겠다.

freopen("log.txt","w",stdout);
...
...
freopen("/dev/tty","w",stdout);

/dev/tty를 사용하여 출력은 앱이 실행된 터미널로 리디렉션된다.

이 정보가 유용하기를 바란다.

os 함수 dup2()는 필요한 것을 제공해야 한다(정확히 필요한 것을 참조하지 않는 경우).

구체적으로는 stdin 파일 설명자를 다른 파일 설명자로 dup2()하고 stdin으로 다른 일을 한 다음 원할 때 다시 복사할 수 있다.

dup() 함수는 열린 파일 설명자를 복제한다.구체적으로는 F_DUPFD 상수 명령 값을 사용해 fcntl()함수가 제공하는 서비스에 대한 대체 인터페이스를 제공하며, 세 번째 인수는 0이다.중복된 파일 설명자는 모든 잠금을 원본과 공유한다.

성공 시 dup()은 원본과 다음과 같은 공통점을 가진 새 파일 설명자를 반환한다.

  • 동일한 열린 파일(또는 파이프)
  • 동일한 파일 포인터(두 파일 설명자가 하나의 파일 포인터 공유)
  • 동일한 액세스 모드(읽기, 쓰기 또는 읽기/쓰기)

그 사이에 C 소스 코드 라이브러리가 널 위해 이 모든걸 해줄거야, stdout이나 stderr을 리디렉션해.하지만 멋진 부분은 당신이 가로채는 스트림에 당신이 원하는 만큼의 콜백 기능을 할당함으로써 당신이 하나의 메시지를 여러 목적지, DB, 텍스트 파일 등에 아주 쉽게 보낼 수 있게 해준다는 것이다.

여기에 stdout, stderr과 동일하게 보이고 동작하는 새로운 스트림을 만드는 것은 사소한 일로, 이 새로운 스트림을 여러 위치로 리디렉션할 수도 있다.

*oogle에서 U-Streams C 라이브러리를 찾으십시오.

freopen쉬운 부분을 해결한다.만약 당신이 아무것도 읽지 않고 POSIX 시스템 콜을 사용할 의향이 있다면, 구식 스틴을 계속 유지하는 것은 어렵지 않다.dup또는dup2그것으로부터 읽기 시작했다면, 모든 내기는 틀렸다.

혹시 이 문제가 발생하는 맥락을 알려주시겠습니까?

낡은 것을 기꺼이 버릴 수 있는 상황을 고수할 것을 권하고 싶다.stdin그리고stdout따라서 사용할 수 있다.freopen.

이것은 가장 쉽게 이용할 수 있고, 편리하고, 유용한 방법이다.

freopen("dir","r",stdin);

참조URL: https://stackoverflow.com/questions/584868/rerouting-stdin-and-stdout-from-c

반응형