2016-12-07 13 views
0

다음은 코드 단편입니다.dup2가 순차적으로 발생하지 않는 이유는 무엇입니까?

int saved_stdout = dup(1); 
int fd = open("file.txt", O_WRONLY | O_CREAT, 0640); 

close(1); 
dup(fd); 
close(fd); 

printf("This text should go into the file\n"); 

//restore stdout 
dup2(saved_stdout, 1); 
printf("stdout restore"); 

나는 dup 및 dup2에 대해 배우려고합니다. 그래서 처음에 내 file.txt를 stdout에 연결했습니다. 그래서 printf를 사용할 때마다 나는 stdout 대신에 file.txt를 써야합니다. 하지만 일단이 사용법을 다 끝내면 다시 복원하기를 원하므로 dup2도 사용합니다.

"이 텍스트는 파일에 저장해야합니다 \ n"라는 텍스트는 실제로 파일에 저장되지 않지만 stdout에는 인쇄됩니다. 왜 그렇게? 나는 그것을 위해 straced, 그 dup2 호출 전에 발견 printf ("이 텍스트 ..."); 성명서, 왜 그렇게?

답변

3

출력 버퍼링 문제 일 수 있습니다. stdout은 터미널에 쓰지 않는 경우 완전히 버퍼링되므로, dup()으로 파일로 리디렉션하면 버퍼링됩니다. printf() 다음에 출력을 내 보내십시오.

printf("This text should go into the file\n"); 
fflush(stdout); 
+0

이것은 내가 찾고 있었던 것이다. 감사합니다. – posixKing

+0

'fflush()'가 "작동"하는 동안, 나는 그것이 잘못된 이유라고 생각합니다. 'open()'이 작동 한 직후에'printf()'를 두는 것만으로도 좀 더 미묘한 일이 일어납니다. 문제는 파일 디스크립터와 FILE 구조가 섞인 것입니다.이 구조는 다른 시스템에서 다른 결과를 얻는 것을 의미하는 정의되지 않은 영역입니다. 원하는 것을하기위한 올바른 방법은'freopen ("file.txt", "w", stdout)'이다. 그 작업은 명확하게 정의됩니다. – gilez

+0

@gilez 필자가 무언가를 작성하고 파일 설명자를 변경하는 동안은 안전해야한다고 생각합니다. 필자는이 대답으로 조금 주저하고 있지만,'printf()'가 발생할 때가 아니라'stdin'이 열릴 때 버퍼링이 초기화되는 것으로 의심하기 때문에 인정합니다. 그러나 그것은 게으 르고 첫 번째 글에서 그것을 할 수 있습니다. – Barmar

0

필자는 이전 대답을 잘못 선택 했으므로 ......... 그러나 printf()을 사용하면 에 stdout을 사용하고 있는데 그 안에는 설명자 또는 터미널을 가리키는 내용이 있습니다. fd 1을 변경하면 분명히 변경되지 않습니다.

테스트 결과가 일치하지 않으므로 여기를 포기하십시오. 난 그냥 단지 open() 후이 라인을 퍼팅 모호한 행동을 강조하는, 그것은 나를 위해 일하게하는 것이 추가 할 :

printf("fileno is %i\n", fileno(stdout)); 

는 파일 기술자 조작으로 printf()FILE * 작업을 함께 사용하지 마십시오. 설명자에 write()을 사용해야합니다.

+1

'dup()'은 사용 가능한 첫 번째 설명자를 사용합니다. 그의 코드는'dup2()'가 추가되기 전에 어떻게 이루어 졌는가하는 것이다. – Barmar

+0

@Barmar, 나는 혼란이 "처음 사용 가능한"것이 무엇을 의미하는지 생각합니다. 그것이 닫혀 있거나 1 번 사용 되었기 때문에 1일까요? – gilez

+0

폐쇄 된 이래로 1이어야한다고 생각합니까? – posixKing