윈도우 vc++ 환경에서 fflush()를 fflush(stdin)과 같이 입력 버퍼를 비울 때 사용했었다. 그러나, 리눅스에서 코딩을 하다 보니 fflush()의 원래 용도는 입력 버퍼를 비우는 것과 전혀 상관이 없다는 사실을 알게 되었다. 윈도우에서 코딩할 때는 visual studio에서 알아서 확장하였기 때문에 (MSDN에 나와 있음) 상관이 없지만, 리눅스 환경에서 이식성이 없다.
윈도우 환경에서만 fflush(stdin)을 사용하는 것과 마찬가지로
리눅스 환경에서만 사용 가능한 __fpurge(stdin)이라는 함수가 있는데..
리눅스에서 아무리 테스트해도 버퍼가 비워지지 않는다.
코드가 잘못된 것일까.
아래는 내가 작성한 예제 코드. (아래 코드에서 주석을 해제하면 된다.)
#include <stdio.h>
#include <unistd.h> // 내부 함수 : int pipe(int filedes[2];
#include <stdlib.h> // 내부 함수 : void exit(int status);
#include <string.h> // 내부 함수 : int strcmp(const char *s1, const cahr *s2);
//#include <stdio_ext.h> // 내부 함수 __fpurge(FILE *stream);
#define BUFSIZE 30
int main(int argc, char *argv[])
{
int fd1[2]; // 파이프의 filedes 저장. 자식이 넣고(1), 부모가 읽는다(0)
int fd2[2]; // 파이프의 filedes 저장. 부모가 넣고(1), 자식이 읽는다(0)
char buf[BUFSIZE]; // 문자열 임시 저장
pid_t pid; // process id
int rcount = 0; // receive count
int wcount = 0; // send count
if(pipe(fd1) == -1 || pipe(fd2) == -1)
{
printf("ERROR\n");
exit(1);
}
pid = fork(); // 자식 프로세스 생성
if(pid < 0)
{
printf("fork() ERROR\n");
exit(1);
}
while(1)
{
if(pid == 0) // 자식 프로세스이면
{
printf("Child, Input your string(max 29) : ");
//__fpurge(stdin);
fgets(buf, BUFSIZE, stdin);
//__fpurge(stdin);
write(fd1[1], buf, BUFSIZE); // 부모 프로세스에 메시지 전송
buf[strlen(buf)-1] = 0x00;
if(strcmp(buf, "quit") == 0) // 종료 메시지를 보냈다면
exit(0);
else
sleep(1); // 부모가 수신하여 출력할 시간을 벌기 위해
read(fd2[0], buf, BUFSIZE); // 부모 프로세스의 메시지 수신
buf[strlen(buf)-1] = 0x00;
if(strcmp(buf, "quit") == 0) // 종료 메시지가 도착했다면
exit(0);
else
printf("I'm child. My receive result : %s\n\n", buf);
}
else // 부모 프로세스이면
{
read(fd1[0], buf, BUFSIZE); // 자식 프로세스의 메시지 수신
rcount++; // 수신 횟수 증가
buf[strlen(buf)-1] = 0x00;
if(strcmp(buf, "quit") != 0)
printf("I'm parent. My receive result : %s\n\n", buf);
else // 자식의 종료 메시지가 도착했다면
{
wait();
printf("\nprogram close...\n<result>\n");
printf("receive count is %d.\n", rcount);
printf("send count is %d.\n", wcount);
exit(0);
}
printf("Perent, Input your string(max 29) : ");
//__fpurge(stdin);
fgets(buf, BUFSIZE, stdin);
//__fpurge(stdin);
write(fd2[1], buf, BUFSIZE); // 자식 프로세스에게 메시지 전송
wcount++; // 송신 횟수 증가
buf[strlen(buf)-1] = 0x00;
if(strcmp(buf, "quit") == 0)
{
wait();
printf("\nprogram close...\n<result>\n");
printf("receive count is %d.\n", rcount);
printf("send count is %d.\n", wcount);
exit(0);
}
else
sleep(1); // 자식이 수신하여 출력할 시간을 벌기 위해
}
}
return 0;
}
이 코드를 작성한 이유는 아래와 같은 상황이 연출되기 때문이다.
입력 받기 전에 남아 있는 표준 입력 버퍼를 비워서 이 문제를 해결하고 싶은데
좋은 방법이 없을까.
__fpurge() 함수를 테스트하기 위해 아래와 같은 코드를 작성해보았으나
역시나 동작하지 않는다. 무슨 문제일까.