2

ここにいくつかのコード サンプルがありますが、問題は、'putty' を使用してシリアル ライン上で 'break' が送信されたときに、シグナル ハンドラが呼び出されないことです。

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

void signal_handler(int status);

int main(void)
{
    FILE* f = fopen("/dev/ttyS0", "r+b");

    struct sigaction saio; /* definition of signal action */
    saio.sa_handler = signal_handler;
    // saio.sa_mask = 0;
    saio.sa_flags = 0;
    saio.sa_restorer = NULL;
    sigaction(SIGINT,&saio,NULL);

    struct termios options;

    tcgetattr (fileno(f), &options);

    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);

    options.c_iflag &= ~IGNBRK; // & ~IGNPAR;
    options.c_iflag |= BRKINT; // | PARMRK | INPCK;
    options.c_cc[VMIN] = 0;
    options.c_cc[VTIME] = 1;

    if (tcsetattr(fileno(f), TCSAFLUSH, &options) == -1)
    {
        printf("port setup failure\n");
        return -1;
    }

    ioctl(fileno(f), TIOCSCTTY, (char *)NULL);
    while (1) {
        int ch = fgetc(f);
        switch (ch) {
        case EOF: break;
        case EAGAIN: printf("[EAGAIN]"); break;
        case EBADF: printf("[EBADF]"); break;
        case EINTR: printf("[EINTR]"); break;
        case EIO: printf("[EIO]"); break;
        case EOVERFLOW: printf("[EOVERFLOW]"); break;
        default:
            if (isprint(ch))
                putchar(ch);
            else
                printf("[%02x]", ch);
        }
    }
}

void signal_handler(int status)
{
    printf("received SIGINT %d signal.\n", status);
    exit(0);
}

ここに私のstty設定があります:

user@dev:~/$ sudo stty -F /dev/ttyS0
speed 9600 baud; line = 0;
intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>; start = <undef>; stop = <undef>; susp = <undef>; rprnt = <undef>; werase = <undef>;
lnext = <undef>; flush = <undef>; min = 0; time = 1;
-imaxbel
-opost -onlcr
-icanon -iexten -echo -echoe -echok -echoctl -echoke

何が足りないのですか / 信号を受信できないのはなぜですか? USB-2-Serial コンバーターを使用しており、ブレークが送信されていることがわかりますが、このクライアント エンドでは何もトリガーされません。

4

1 に答える 1

1

straceの監視下で試してみてください。tcgetattrの後にへの呼び出しを追加し、要求しtcsetattrたすべての変更が行われたことを確認し
ます。また、新しいものを取得する前に、制御している tty を取り除く必要があります。man tty-ioctl によると:

   Controlling tty
       TIOCSCTTY int arg
              Make  the given tty the controlling tty of the calling process.  The calling process must be a session leader and not have a controlling tty already.  If
              this tty is already the controlling tty of a different session group then the ioctl fails with EPERM, unless the caller is root  and  arg  equals  1,  in
              which case the tty is stolen, and all processes that had it as controlling tty lose it.

       TIOCNOTTY void
              If  the  given tty was the controlling tty of the calling process, give up this controlling tty.  If the process was session leader, then send SIGHUP and
              SIGCONT to the foreground process group and all processes in the current session lose their controlling tty.
于 2009-06-11T07:24:46.903 に答える