tty* 장치를 읽고 쓰는 방법은 무엇입니까?

tty* 장치를 읽고 쓰는 방법은 무엇입니까?

USB를 통해 내 컴퓨터로 정보를 보내는 장치가 있습니다. Arch Linux ttyUSB0/dev/. 나는 GTKterm이 들어오는 정보를 수신하고 이를 에뮬레이트된 터미널 창에 표시하는 데 사용하고 있습니다 .

내 질문은 GTKterm이 파일을 정확히 어떻게 읽고 쓸 수 있는지 ttyUSB0, 유사한 기능을 구현하는 방법을 어디서 배울 수 있는지입니다. 즉, 가장 기본적인 형태로 문자를 에 쓰거나 ttyUSB0반대로 바이트를 받아 파일에 쓰는 방법은 무엇입니까?

답변1

TTY는 다른 파일과 마찬가지로 사용할 수 있는 파일입니다. 해당 언어의 표준 파일 열기 도구를 사용하여 해당 파일을 열고 읽거나 쓸 수 있습니다. "일반" 파일과 다른 특별한 동작이 있지만 기본 사항은 동일합니다. 마지막에 몇 가지 특별한 경우를 다루겠습니다. 먼저 실험을 해보겠습니다.

일반 터미널에서 바로 할 수 있는 흥미로운 일 중 하나입니다. 실행하면 tty다음과 같은 줄이 인쇄됩니다.

/dev/pts/2

이것이 터미널이 실행 중인 TTY 장치입니다. 해당 터미널에 무언가를 쓸 수 있습니다.

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

당신은 그것을 읽을 수도 있습니다 :

$ read X < /dev/pts/2
hello
$ echo $X
hello
$

( read Xsh의 "표준 입력에서 변수 X로 한 줄 읽기" 명령입니다. <는 /dev/pts/2를 읽기 명령의 표준 입력으로 사용하는 것입니다. 첫 번째 "hello"를 입력하고 두 번째가 인쇄되었습니다) .

screen또는 를 사용하여 다른 셸을 열면 해당 셸에서 xtermrun 을 실행하여 echo spooky > /dev/pts/2원래 터미널에 텍스트가 나타나도록 할 수 있으며 다른 명령에도 동일하게 표시됩니다. 이 모든 것은 파일이 TTY인지 모르고 파일을 여는 쉘일 뿐입니다.


다음은 요청한 작업을 수행하고 /dev/pts/3에 단일 문자를 쓴 다음 다시 단일 바이트를 읽는 매우 간단한 C 프로그램입니다.

#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\n", byte);
    return 0;
}

셸이나 터미널 에뮬레이터에 연결된 실제 TTY 장치는 흥미로운 동작을 가지지만 뭔가를 다시 얻어야 합니다.


터미널에 액세스하려면 해당 터미널을 사용할 수 있는 권한이 필요합니다. 이는 여러분이 보고 ls -l설정한 표준 파일 권한일 뿐입니다 chmod. 파일을 열고 읽으려면 읽기 권한이 필요하고, 파일에 쓰려면 쓰기 권한이 필요합니다. 터미널을 뒷받침하는 TTY는 귀하가 소유하지만 다른 사용자의 TTY는 소유하지 않으며, USB 장치용 TTY는 구성에 따라 소유할 수도 있고 그렇지 않을 수도 있습니다. 언제나와 같은 방법으로 권한을 변경할 수 있습니다.

이를 사용할 프로그램을 작성하는 한, 특별한 작업을 많이 수행할 필요는 없습니다. 예를 보면 한 가지 사실을 알 수 있습니다.~하지 않다해야 할 일은 상대방이 데이터를 읽을 수 있도록 매번 파일을 닫는 것입니다. TTY 파일은 파이프라인처럼 작동하여 데이터가 들어올 때 양방향으로 푸시합니다. TTY에 텍스트를 쓰면 즉시 나타납니다. 나중에 읽어보니 이미 나를 기다리는 것은 아무것도 없었습니다. 그것은~ 아니다데이터가 디스크에 저장되는 일반 파일에 쓰는 것과 같습니다. 데이터는 즉시 상대방에게 전달되거나 누군가가 읽을 때까지 메모리에 저장됩니다.

당신은선택하다기능을 사용하면 장치가 무언가를 말할 때까지 기다리는 동안 다른 작업을 할 수 있습니다. 하지만 데이터가 전달될 때까지 기다리는 것이 즐겁다면 차단 읽기를 사용하고 OS가 리프팅을 수행하도록 할 수 있습니다.

한 가지 명심해야 할 점은 커널에는 버퍼 크기가 제한되어 있을 수 있으며, 한 번에 많은 양의 데이터를 쓰면 의도치 않게 차단될 수도 있다는 것입니다. 문제가 될 가능성이 있는 경우 다음을 사용하세요.비차단 IO와 함께 open("/dev/...", O_RDWR | O_NONBLOCK). 어느 쪽이든 원칙은 동일합니다.

관련 정보