C 字节不会发送到串行驱动程序缓冲区

C 字节不会发送到串行驱动程序缓冲区,c,posix,C,Posix,我有这个计划: // C headers #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <stdint.h> // POSIX headers #include <unistd.h> #include <sys/ioctl.h> // Other headers #include &

我有这个计划:

// C headers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>

// POSIX headers
#include <unistd.h>
#include <sys/ioctl.h>

// Other headers
#include "ZL_sleep.h"
#include "ZL_utf8.h"
#include "ZL_serial.h"

#define BS 4 // Buffer size

int main(int argc, char * argv[]){

    int32_t p; // Port
    int32_t r; // Read finished
    uint8_t b[BS]; // Buffer
    uint32_t n; // Number of bytes to be read from driver buffer

    if(argc != 2){
        printf("ERROR: Supply a \"serial port\" device file.");
        exit(EXIT_FAILURE);
    }

    p = ZL_open_tty(argv[1]);
    if(p < 0){
        perror("ERROR: open()");
        exit(EXIT_FAILURE);
    }

    while(1){
        memset(b, '\0', BS);
        r = read(p, b, BS);

        if(r < 0){
            if(errno == EAGAIN){
            }
            else{
                perror("ERROR: read()");
                close(p);
                exit(EXIT_FAILURE);
            }
        }
        ZL_utf8_print_bytes(b, BS);
        putchar('\n');

    }

    close(p);
    return EXIT_SUCCESS;
}
之后,我的程序进入一个无休止的while循环,
read()
阻塞,直到我在键盘焦点位于
/dev/pts/1
时输入任何键

我面临的问题是,有时我在
/dev/pts/1
中按下一个键,使用该键注册的字节不会传输到驱动程序缓冲区?!字节只保留在
/dev/pts/1
中。这发生在ASCII(1字节)字符和UTF8(多字节)字节中

我知道
read()
尝试从驱动程序缓冲区读取请求的字节量(
BS
)。但是,如果驱动程序缓冲区中没有可用的
BS
字节,那么它读取的字节就会更少。所以如果某些字节稍后到达,它可以稍后读取它们。但由于某些原因,这些字节永远不会到达驱动程序缓冲区

是什么原因导致字节未到达驱动程序缓冲区并永久保留在
/dev/pts/1


当虚拟终端连接到系统(通常是
ssh
)时,会创建
pts
pts
被连接为
stdin
/
stdout
,用于启动连接的外壳,因此您已经有一个进程连接到
pts
并从中读取

一旦附加了应用程序,就可以在两个进程(应用程序和shell)之间有效地开始竞争,因此速度更快的人将收到缓冲区的内容。字符没有保留在
pts
的缓冲区中,而是由连接到
pts
的外壳读取


为了能够在不中断连接进程的情况下读取数据,您需要通过通知主多路复用器ptmx来拦截pts的缓冲区,请参阅中的详细信息。您可以研究如何在

模式下完成,您不也需要禁用规范模式吗?我添加了
fo.c|lflag&=~(ICANON | ECHO | ECHO | ISIG)ZL_open_tty()
中使用code>禁用规范模式,结果相同。即使我尝试只请求读取
1
字节,如so
r=read(p,b,1)有些字节没有传输到串行驱动程序缓冲区,因此无法读取。非常感谢先生!
uint32_t ZL_open_tty(const char * terminal){

    uint32_t fd; // File's descriptor
    uint32_t fl; // File's flags
    struct termios fo; // File's options

    fd = open(terminal, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if(fd < 0){
        return -1;
    }
    
    fl = fcntl(fd, F_GETFL, 0);
    if(fl < 0){
        perror("ERROR: fcntl():");
        return -1;
    }
    fcntl(fd, F_SETFL, fl & ~(O_NONBLOCK | O_APPEND | O_DSYNC | O_RSYNC | O_SYNC));
    
    tcgetattr(fd, &fo);
    fo.c_cc[VMIN] = 1;
    fo.c_cc[VTIME] = 0;
    tcsetattr(fd, TCSANOW, &fo);

    fputs("───────────────────────────────────────────────────  terminal settings\n", stdout);
    printf("VMIN = %d\n", fo.c_cc[VMIN]);
    printf("VTIME = %d\n", fo.c_cc[VTIME]);
    putchar('\n');
    return(fd);