2009-09-29 69 views
0

如果我的進程控制/ dev/ttyS2在串行端口接收到BREAK,我希望收到SIGINT。我從一個shell運行這個程序。從我發現的只有「終端是前臺進程組的控制終端,它會導致一個SIGINT被髮送到這個前臺進程組」我嘗試了終端製作過程製作控制器,但它失敗了。ttycontrol程序的Linux接收信號中斷

#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/ioctl.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <termios.h> 
#include <errno.h> 
#include <stdio.h> 
#include <signal.h> 
#include <string.h> 

#define BAUDRATE B115200 
#define MODEMDEVICE "/dev/ttyS2" 
#define _POSIX_SOURCE 1 /* POSIX compliant source */ 
#define FALSE 0 
#define TRUE 1 


__sighandler_t sighandle(int signum, __sighandler_t h) { 
    fprintf(stderr, "BREAK DETECTED\n"); 
    signal(SIGINT, (__sighandler_t) sighandle); 
    return SIG_IGN; 
} 
volatile int STOP=FALSE; 

int main() 
{ 
    int fd,c, res; 
    struct termios oldtio,newtio; 
    char buf[255]; 
    pid_t pid; 
    signal(SIGINT, (__sighandler_t) sighandle); 

    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY); 
    if (fd <0) {perror(MODEMDEVICE); return (-1); } 


    tcgetattr(fd,&oldtio); /* save current port settings */ 

    memset(&newtio, 0,sizeof(newtio)); 
    newtio.c_cflag |= BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD | BRKINT; 
    newtio.c_iflag &= ~IGNBRK ; 
    newtio.c_oflag = 0; 

    /* set input mode (non-canonical, no echo,...) */ 
    newtio.c_lflag = 0; 

    newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ 
    newtio.c_cc[VMIN]  = 1; /* blocking read until 5 chars received */ 

    tcflush(fd, TCIFLUSH); 
    tcsetattr(fd,TCSANOW,&newtio); 

    if(ioctl(fd, TIOCSCTTY, 1) <0) 
    { 
     printf("Error number: %d\n", errno); 
    } 
    if (tcsetpgrp(fd, tcgetpgrp(0)) < 0) 
    { 
    syslog(LOG_PERROR,"tcsetpgrp failed: %d " ,errno); 
    syslog(LOG_PERROR,"EBADF is %d " ,EBADF);  
    syslog(LOG_PERROR,"EINVAL is %d " ,EINVAL); 
    syslog(LOG_PERROR,"ENOTTY is %d " ,ENOTTY);  
    syslog(LOG_PERROR,"EPERM is %d " ,EPERM); 
    } 
    while (STOP==FALSE) {  /* loop for input */ 
     res = read(fd,buf,255); /* returns after 5 chars have been input */ 
     buf[res]=0;    /* so we can printf... */ 

     printf(":%s:%d\n", buf, res); 
     if (buf[0]=='z') {STOP=TRUE;} 
    } 
    tcsetattr(fd,TCSANOW,&oldtio); 
    return 0; 
} 
+0

1的_POSIX_SOURCE正在調用POSIX 1990;你可能會用'#define _XOPEN_SOURCE 600'(或者可能是500)做得更好。你可能會用sigaction()在signal()上做得更好。然而,這些都不能說明你沒有看到什麼。 – 2009-09-29 16:13:54

回答

0

#define _POSIX_SOURCE 1沒有影響,除非它先於#include秒。

使用C99編譯器,您可能需要#include <stdbool.h>而不是#define您自己的TRUEFALSE

/* from signal.h, */ 
typedef void(*sighandler_t)(int); 
/* which means the handler must be declared thusly */ 
void sighandle(int); 
/* as a result, no casting is necessary */ 
sighandler_t p_sighandle = &sighandle; 

前景進程組由tcsetpgrp設置,您似乎錯過了它。

+0

我編輯了代碼,並添加了 如果(tcsetpgrp(fd,tcgetpgrp(0))<0) {LOG_PERROR,「tcsetpgrp失敗:%d」,errno); syslog(LOG_PERROR,「EBADF是%d」,EBADF); syslog(LOG_PERROR,「EINVAL is%d」,EINVAL); syslog(LOG_PERROR,「ENOTTY is%d」,ENOTTY); syslog(LOG_PERROR,「EPERM is%d」,EPERM); } 但是 tcsetpgrp失敗 ENOTTY – CrazyChris 2009-09-29 15:30:21

+0

不記錄errno值!這不是Windows,預計用戶將谷歌錯誤數字!使用「%m」(GNU擴展名)或等效的「%s」,strerror(errno)。 – 2009-12-09 22:57:30

1

我終於找到了我的問題的答案。我正在使用自定義板,因此它不必總是工作,但是當串行端口配置正確時,用戶可以通過串行端口獲得cat/proc/tty/device/serial的中斷次數,這是我希望獲得的功能

相關問題