Как к чтению-записи к tty* устройство?

К моему знанию там не существует функция Vim, которая выполняет то, что Вы просите. Но я придумал мой s:Get_file_perm функционируйте, чей результат я присваиваю w:file_perm переменная:

" ...
let w:file_perm=<sid>Get_file_perm()
" ...
function! s:Get_file_perm()
  let a=getfperm(expand('%:p'))
  if strlen(a)
    return a
  else
     let b=printf("%o", xor(0777,system("umask")))
     let c=""
     for d in [0, 1, 2]
       let c.=and(b[d], 4) ? "r" : "-"
       let c.=and(b[d], 2) ? "w" : "-"
       let c.=and(b[d], 1) ? "x" : "-"
     endfor
     return c
   endif
 endfunction

Функциональные проверки (if) видеть если полномочия (getfperm) для текущего пути к файлу ('%:p') существуйте (strlen). В случае нового файла ("") else- блок поразрядно вычитает (xor) восьмеричное umask от восьмеричного литерала 0777 (rwxrwxrwx) – все биты полномочий установлены.

Для владельца - (0), группа - (1) и полномочия для других (2) это многократно (for) проверки на каждое чтение - (4), запишите - (2) и выполнитесь (1) бит, что это установлено (and). Если соответствующий бит установлен, он добавляет (.=) "r", "w" и "x" к c переменная, соответственно. Еще "-" добавляется для символизации этого, соответствующая операция не разрешена.

32
21.06.2014, 12:57
1 ответ

TTY - это файлы, которые можно использовать, как и любые другие. Вы можете открывать их с помощью стандартных средств открытия файлов вашего языка и читать или писать из них. У них есть особое поведение, отличное от "обычных" файлов, но основы те же. В конце я расскажу о некоторых особых случаях, но сначала об эксперименте.

Одна интересная вещь, которую вы можете сделать прямо из обычного терминала. Запустите tty , и он напечатает такую ​​строку:

/dev/pts/2

Это устройство TTY, на котором работает ваш терминал. Вы можете записать что-нибудь в этот терминал:

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

Вы даже можете прочитать из него:

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

( read X - это команда sh «прочитать строку из стандартного ввода в переменную X»; <означает использовать / dev / pts / 2 в качестве стандартного ввода для команды чтения; первое «привет», которое я набрал , а второй был распечатан).

Если вы откроете другую оболочку, например, используя screen или xterm , вы можете запустить run echo spooky> / dev / pts / 2 в этом shell, чтобы текст отображался в исходном терминале, и то же самое для других команд. Все это просто ваша оболочка, открывающая файл, не зная, что это TTY.


Вот очень простая программа на C, которая делает именно то, что вы просили, и записывает один символ в / dev / pts / 3, а затем считывает из него один байт:

#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 другого пользователя не будут, а TTY для USB-устройств могут быть или не быть, в зависимости от вашей конфигурации. Вы можете изменить разрешения так же, как и всегда.

Что касается написания программы для работы с ней, вам не нужно делать ничего особенного. В этом примере вы можете видеть, что одна вещь, которую вам не нужно делать, - это закрывать файл каждый раз, чтобы ваши данные считывались на другом конце: файлы TTY действуют как конвейеры, просто отправляя данные в оба. направления по мере поступления. Когда я написал текст в TTY, он появился сразу, а когда я прочитал его потом, меня уже ничего не ждало. Это не как запись в обычный файл, где данные сохраняются на диске - они немедленно передаются другой стороне или сохраняются в памяти, пока кто-нибудь их не прочитает.

Вы можете использовать функцию select , чтобы вы могли заниматься другими делами, пока ждете, пока устройство что-то скажет, но если вы счастливы просто дождаться поступления данных, вы можете просто используйте блокирующее чтение и позвольте ОС сделать подъем.

Следует иметь в виду, что размер буфера в ядре может быть ограничен, и если вы напишете много данных за один раз, вы можете в конечном итоге заблокировать его, не желая этого. Если это может быть проблемой, используйте неблокирующий ввод-вывод с open ("/ dev / ...", O_RDWR | O_NONBLOCK) . В любом случае принцип будет одним и тем же.

41
27.01.2020, 19:37

Теги

Похожие вопросы