Linux ttycontrol 程序接收信号中断
如果控制 /dev/ttyS2 的进程在串行端口上收到 BREAK,我希望收到 SIGINT。我从 shell 运行这个程序。据我所知,“终端是前台进程组的控制终端,它将导致 SIGINT 发送到该前台进程组”,我尝试制作终端的进程控制器,但失败了。
#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;
}
I would like to receive SIGINT if my process controlling /dev/ttyS2 receives BREAK on a serial port. I run this program from a shell. From what I discovered only "the terminal is the controlling terminal of a foreground process group, it will cause a SIGINT to be sent to this foreground process group" I tried make process making controller of terminal but it fails.
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我终于找到了我的问题的答案。我正在使用自定义板,因此它不必总是工作,但是当正确配置串行端口时,用户可以通过 cat /proc/tty/device/serial 获得串行端口的中断次数,我希望获得这种功能
I finally found answer to my problem. I am using custom board so it don't have to work always but when serial port is configured correctly user can get number of breaks by serial port by cat /proc/tty/device/serial, that kind of functionality I was hoping to get
#define _POSIX_SOURCE 1
无效,除非它位于#include
。使用 C99 编译器,您可以
#include
而不是#define
您自己的TRUE
和FALSE
。前台进程组由
tcsetpgrp
,您似乎缺少它。#define _POSIX_SOURCE 1
has no effect unless it precedes the#include
s.With a C99 compiler, you may
#include <stdbool.h>
instead of#define
your ownTRUE
andFALSE
.The foreground process group is set by
tcsetpgrp
, which you appear to be missing.