2010-09-24 17 views
6

ISO/IEC 2022 definiuje the C0 and C1 control codes. Zestaw C0 są na znanych kodów między 0x00 i 0x1f ASCII, ISO 8859-1 i UTF-8 (np. ESC, CR, LF).Czy mogę określić, czy terminal interpretuje kody kontrolne C1?

Niektóre emulatory terminali VT100 (np. screen(1), PuTTY) również obsługują zestaw C1. Są to wartości między 0x80 i 0x9f (na przykład 0x84 przesuwa kursor w dół linii).

Wyświetlane są dane wprowadzane przez użytkownika. Nie chcę, aby dane wprowadzone przez użytkownika były w stanie zmienić stan terminala (np. Przesunąć kursor). Aktualnie odfiltrowuję kody znaków w zbiorze C0; jednak chciałbym również warunkowo odfiltrować zestaw C1, jeśli terminal zinterpretuje je jako kody kontrolne.

Czy istnieje sposób na uzyskanie tych informacji z bazy danych, takiej jak termcap?

Odpowiedz

2

Jedynym sposobem na to, że mogę myśleć używa żądania C1 i testowanie wartości zwracanej:

$ echo `echo -en "\x9bc"` 
^[[?1;2c 
$ echo `echo -e "\x9b5n"` 
^[[0n 
$ echo `echo -e "\x9b6n"` 
^[[39;1R 
$ echo `echo -e "\x9b0x" ` 
^[[2;1;1;112;112;1;0x 

Powyższe nich to:

CSI c  Primary DA; request Device Attributes 
CSI 5 n DSR; Device Status Report 
CSI 6 n CPR; Cursor Position Report 
CSI 0 x DECREQTPARM; Request Terminal Parameters 

terminfo/termcap że ESR utrzymuje (link) kilka żądań w ciągach użytkownika 7 i 9 (użytkownik 7/u7, użytkownik 9/u9):

 
# INTERPRETATION OF USER CAPABILITIES 
# 
# The System V Release 4 and XPG4 terminfo format defines ten string 
# capabilities for use by applications, .... In this file, we use 
# certain of these capabilities to describe functions which are not covered 
# by terminfo. The mapping is as follows: 
# 
#  u9  terminal enquire string (equiv. to ANSI/ECMA-48 DA) 
#  u8  terminal answerback description 
#  u7  cursor position request (equiv. to VT100/ANSI/ECMA-48 DSR 6) 
#  u6  cursor position report (equiv. to ANSI/ECMA-48 CPR) 
# 
# The terminal enquire string should elicit an answerback response 
# from the terminal. Common values for will be ^E (on older ASCII 
# terminals) or \E[c (on newer VT100/ANSI/ECMA-48-compatible terminals). 
# 
# The cursor position request() string should elicit a cursor position 
# report. A typical value (for VT100 terminals) is \E[6n. 
# 
# The terminal answerback description (u8) must consist of an expected 
# answerback string. The string may contain the following scanf(3)-like 
# escapes: 
# 
#  %c  Accept any character 
#  %[...] Accept any number of characters in the given set 
# 
# The cursor position report() string must contain two scanf(3)-style 
# %d format elements. The first of these must correspond to the Y coordinate 
# and the second to the %d. If the string contains the sequence %i, it is 
# taken as an instruction to decrement each value after reading it (this is 
# the inverse sense from the cup string). The typical CPR value is 
# \E[%i%d;%dR (on VT100/ANSI/ECMA-48-compatible terminals). 
# 
# These capabilities are used by tac(1m), the terminfo action checker 
# (distributed with ncurses 5.0). 

Przykład:

$ echo `tput u7` 
^[[39;1R 
$ echo `tput u9` 
^[[?1;2c 

Oczywiście, jeśli tylko chcą zapobiec uszkodzeniu wyświetlacza, można użyć less podejście, i niech wyłącznik użytkownika pomiędzy wyświetlania/nie wyświetlania znaków sterujących (-R i -R opcje w less). Ponadto, jeśli znasz swój zestaw znaków wyjściowych, zestawy znaków ISO-8859 mają zarezerwowany zakres C1 dla kodów sterujących (więc nie mają znaków do wydrukowania w tym zakresie).

1

W rzeczywistości PuTTY nie wydaje się obsługiwać elementów sterujących C1.

Najczęstszym sposobem testowania tej funkcji jest funkcja vttest, która zapewnia osobne wpisy do zmiany wejścia i wyjścia w celu użycia 8-bitowych elementów sterujących. PuTTY nie sprawdza poprawności dla każdego z tych wpisów w menu, a jeśli kontrola jest wyłączona, wynik potwierdza, że ​​PuTTY nie honoruje tych kontroli.

-1

Nie sądzę, że istnieje prosty sposób sprawdzenia, czy terminal obsługuje je. Możesz wypróbować nieprzyjemne, hackowe obejścia (takie jak je wydrukuj, a następnie zapytaj o pozycję kursora), ale naprawdę nie polecam niczego wzdłuż tych linii.

Myślę, że można bezwarunkowo odfiltrować te kody C1. Unicode deklaruje zakres U + 0080 .. U + 009F jako znaki kontrolne, nie sądzę, że powinieneś używać ich do czegokolwiek innego.

(Uwaga: użyto przykład 0x84 dla kursora na dół, to jest w rzeczywistości U+0084 zakodowany w zależności od tego, terminal używa kodowania, np 0xC2 0x84 UTF-8..)

0

Wykonanie w 100% automatycznie stanowi wyzwanie w najlepszym przypadku. Wiele, jeśli nie większość, interfejsów Unix jest inteligentnych (xtermy i inne), ale w rzeczywistości nie wiesz, czy jest podłączony do ASR33 lub komputera z systemem MSDOS.

enter image description here

można spróbować niektóre z końcowych sekwencji przesłuchanie ewakuacyjnych oraz timeout jeśli nie ma odpowiedzi. Ale wtedy może będziesz musiał wrócić i może zapytać użytkownika, jakiego rodzaju terminal używa.