• 转 tty 设备读写


    转自https://feng-qi.github.io/2017/05/04/how-to-read-write-to-tty-device/

        <p>这是 StackExchange 上的一个问答,在这里翻译一下原文地址为:<br><a href="https://unix.stackexchange.com/questions/138342/how-to-read-write-to-tty-device" target="_blank" rel="noopener">How to read/write to tty* device?</a></p>
    

    问题描述

    我有一个设备通过 USB 传输信息到我的计算机。Arch Linux 通过在/dev/下建立了一个
    名为ttyUSB0的文件来设置这台设备。我一直使用GTKterm来接收信息并将信息显示在一
    个模拟终端窗口上。

    我的问题是:GTKterm具体是怎样读/写ttyUSB0这个文件的,我从哪儿能学到实现相似
    功能的技术?即,从最简单的情况来说,我怎么写一个字符到ttyUSB0,或者从它接收一
    个字节并写入到文件中去?

    Michael Homer 的回答

    你可以像使用其他文件一样使用 TTYs 文件。你可以用你所用语言打开文件的一般方法来打
    开它们并读写。他们是相比于其他“普通”文件是有一些特殊行为,但基本来说是一样的。我
    会在文末说到一些特殊情况,但还是先看一些实验吧。

    你可以在一个普通终端做的一件有趣的事情是,运行tty它就会打印和下面相似的一行输出:

    1
    /dev/pts/2

    这是你的终端运行所依赖的 TTY 设备,你可以向那个终端写点什么:

    1
    2
    3
    $ echo Hello > /dev/pts/2
    Hello
    $

    你甚至可以从它读取信息:

    1
    2
    3
    4
    5
    $ read X < /dev/pts/2
    hello
    $ echo $X
    hello
    $

    (read Xsh用来“从标准输入读取一行并保存到变量 X”的命令;<表示使用/dev/pts/2
    作为 read 命令的标准输入;第一个“hello”是我键入的,第二个是终端输出的)。

    如果你用screenxterm打开另一个 shell,你可以在新打开的那个 shell 里运行
    echo spooky > /dev/pts/2,这些文本会在你原来的 shell 里显示出来,对其他命令来
    说也是一样的。


    以下这个很简单的 C 程序就可以做到你想做的事,向/dev/pts/3写入一个字符,然后从
    它那儿读取一个字节:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    int main() {
    char byte;
    int fd = open("/dev/pts/3", O_RDWR);
    write(fd, "X", 1);
    ssize_t size = read(fd, &byte, 1);
    printf("Read byte %c ", byte);
    return 0;
    }

    一个绑定到 shell 或终端模拟器的真实 TTY 设备会产生一些有趣的行为,但你应该能得到
    一些反馈(get something back)。


    想要存取一个终端你需要有相应的权限。这些只是标准的文件权限,就和你用ls -l看到
    还有用chmod设置的一样:你需要读的权限来打开文件并读取它,写的权限来写入它。在
    你终端后面的 TTY 将属于你的,但其他用户的并不,而对应于 USB 设备的TTY 可能属于也
    可可能不属于你,这取决于你的配置。你可以用与平常相同的方法改变权限。

    只要所写的程序可以与之正常交互,你就不需要做什么特殊的设置。你可以在例子中看到你
    并不需要为了让另一头读取你写入的数据而每次都关闭文件:TTY 文件表现得像管道,只要
    数据来了只管从两端传入。当我向 TTY 写文本时立马就能显示出来,所以当我后来从中读
    取的时候已经没有数据等着我了。这并不跟写入一个普通文件时数据会保存到磁盘上一样——
    它会直接被传送到另一端,或者保存到内存中直到被读取。

    你可能会想用select这个函数,它让你可以在等待设备传入数据的做些其他事,当然如果
    你就是想等待数据到来那你也可以使用阻塞的方式读取,而让操作系统做相关的调度。

    需要时刻注意的一件事是内核中缓冲区的大小是有限的,如果你一次写入的数据太多可能会
    导致你不希望发生的阻塞。如果这是一个问题的话,可以使用非阻塞 IO 如
    open("/dev/...",O_RDWR|O_NONBLOCK)。 不管哪种方式原则都是一样的。

    </div>
  • 相关阅读:
    Vue2 后台管理系统解决方案
    vuejs 和 element 搭建的一个后台管理界面
    Composer 是什么
    解决无限 This file is indented with tabs instead of 4 spaces
    (七)boost库之单例类
    (六)boost库之内存管理shared_ptr
    (五)boost库之随机数random
    (四)boost库之正则表达式regex
    (二)boost库之字符串格式化
    (一)boost库之日期、时间
  • 原文地址:https://www.cnblogs.com/sdu20112013/p/11234365.html
Copyright © 2020-2023  润新知