2010-02-05 2 views
0

내가 터미널에 아무것도 입력하지 한 다음 코드신호를 무시하는 STDIN_FILENO에서 선택하는 방법은 무엇입니까?

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <termios.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <signal.h> 
#include <sys/time.h> 
#include <time.h> 

#define CLOCKID CLOCK_REALTIME 
#define SIG SIGRTMIN 
int reset = 0; 
void changemode(int); 
int kbhit(void); 
int pfds[2]; 

static void handler(int sig, siginfo_t *si, void *uc) 
{ 
    write(pfds[1], "reset", 6); 
} 

int main(void) 
{ 
    int ch; 
    timer_t timerid; 
    struct sigaction sa; 
    struct itimerspec its; 
    struct sigevent sev; 
    long long freq_nanosecs; 
    char buf[30]; 

    pipe(pfds); 

    sa.sa_flags = 0; 
    sa.sa_sigaction = handler; 
    sigemptyset(&sa.sa_mask); 
    if (sigaction(SIG, &sa, NULL) == -1) 
    { 
     printf("Error\n"); 
     exit(1); 
    } 

    changemode(1); 

    sev.sigev_notify = SIGEV_SIGNAL; 
    sev.sigev_signo = SIG; 
    sev.sigev_value.sival_ptr = &timerid; 
    if (timer_create(CLOCKID, &sev, &timerid) == -1) 
    { 
     printf("Error timer_create"); 
     exit(1); 
    } 

    its.it_value.tv_sec = 1; 
    its.it_value.tv_nsec = 0; 
    its.it_interval.tv_sec = its.it_value.tv_sec; 
    its.it_interval.tv_nsec = its.it_value.tv_nsec; 

    if (timer_settime(timerid, 0, &its, NULL) == -1) 
    { 
     printf("Error timer_settime"); 
     exit(1); 
    } 

    while(1) 
    { 
     if (kbhit()) 
     { 
      ch = getchar(); 
      printf("%d %c\n", ch, ch); 
      if (ch == 'q') 
      { 
       printf("\nQuitting...\n"); 
       break; 
      } 
     } 
     else 
     { 
      memset(buf, 0, 30); 
      read(pfds[0], buf, 6); 
      printf("\n%s", buf); 
     } 
    } 

    changemode(0); 
    return 0; 
} 

void changemode(int dir) 
{ 
    static struct termios oldt, newt; 

    if (dir == 1) 
    { 
     tcgetattr(STDIN_FILENO, &oldt); 
     newt = oldt; 
     newt.c_lflag &= ~(ICANON | ECHO); 

     tcsetattr(STDIN_FILENO, TCSANOW, &newt); 
    } 
    else 
     tcsetattr(STDIN_FILENO, TCSANOW, &oldt); 
} 

int kbhit (void) 
{ 
    fd_set rdfs; 

    FD_ZERO(&rdfs); 
    FD_SET (STDIN_FILENO, &rdfs); 
    FD_SET (pfds[0], &rdfs); 

    select(FD_SETSIZE, &rdfs, NULL, NULL, NULL); 
    return FD_ISSET(STDIN_FILENO, &rdfs); 

} 

그러나 신호 SIGRTMIN가 발생 STDIN_FILENO이 설정 될 때마다 (FD_ISSET) althought을 확인하시기 바랍니다. SIGRTMIN이 타이머에 의해 생성 될 때 선택을 STDIN_FILENO 무시하는 방법?

+0

코드가 너무 많으면 제대로 작동하지 않는 것을 격리하고 특정 코드에 대해 특정 질문을하십시오. 문제를 격리함으로써 해결할 수 있습니다. –

답변

1

Linux를 사용하는 경우 select 대신 pselect를 사용해야합니다.

그렇지 않은 경우 select에서 반환 한 오류 코드를 확인해야합니다. EINTR이면 fds의 상태를 확인하기 위해 select를 다시 호출해야 할 수도 있습니다 (확실하지 않습니다).

+0

감사합니다. pselect를 잊어 버렸습니다! :) – bluegenetic

관련 문제