#c #bash #input #barcode-scanner
Вопрос:
В настоящее время у меня есть программа на C/C , которая использует сканер штрих-кода в качестве клавиатуры, улавливает ввод и что-то с ним делает. Вот соответствующие части кода:
int get_InStream() {
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(amp;fds);
FD_SET(STDIN_FILENO, amp;fds);
select(STDIN_FILENO 1, amp;fds, NULL, NULL, amp;tv);
return FD_ISSET(STDIN_FILENO, amp;fds);
}
void nonblock(int state) {
struct termios ttystate;
tcgetattr(STDIN_FILENO, amp;ttystate);
if (state == 1) {
// ~ICANON: turn off canonical mode
// ~ECHO: not display character
//~ ttystate.c_lflag amp;= ~ECHO; // (ICANON amp; ECHO);
tcgetattr( 0, amp;ttystate); /* read curr. setting */
original_mode = ttystate; /* remember these */
ttystate.c_lflag amp;= ~ICANON; /* no buffering */
//~ ttystate.c_lflag amp;= ~ECHO; /* no echo either */
tcsetattr( 0 , TCSANOW, amp;ttystate); /* install settings */
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state == 0) {
//~ // turn on canonical mode
//~ ttystate.c_lflag |= ECHO;
tcsetattr(0, TCSANOW, amp;original_mode); /* undo -icanon, -echo */
}
// set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, amp;ttystate);
}
bool keyState(int key) { // Uses ASCII table
bool pressed = false;
int i = get_InStream(); // Allows to read from terminal
if (i != 0) {
char c = fgetc(stdin);
if (c == (char) key) {
pressed = true;
} else {
pressed = false;
char string_key = c;
pthread_mutex_lock(amp;id_mutex);
// Append character to content buffer
strcat(content, string_key);
pthread_mutex_unlock(amp;id_mutex);
}
}
return pressed;
}
void* get_inputContent(void* arg) {
pthread_detach(pthread_self());
nonblock(1);
while (1) {
// if this returns True, content contains data
if (keyState(0x0A)) { // 0x0A in ASCII table corresponds to New Line
pthread_mutex_lock(amp;id_mutex);
printf("Read this %d characters through barcode scanner: %sn", strlen(content), content); //DEBUG
// doSomething()
strcpy(content, ""); // empty out content
pthread_mutex_unlock(amp;id_mutex);
}
}
nonblock(0);
pthread_exit(NULL);
}
Прямо сейчас это хорошо работает как отдельный поток от основной программы, но если я открою другой терминал во время работы основной программы и оставлю фокус на новом, ввод штрих-кода не будет пойман потоком.
Поэтому я хотел бы, либо в C/C , либо в Bash, скажем, разделить входные данные между различными терминалами, чтобы мой поток мог их использовать. Есть ли какой-нибудь способ сделать это?
Я искал различные варианты:
- еще один дескриптор для использования в
select()
- использование
export
в Bash - запись в общий файл, но я не уверен ни в одном из них. Есть какие-нибудь предложения?
РЕДАКТИРОВАТЬ: программа запускается на ОС Raspberry Pi, ранее Raspbian, если я не ошибаюсь
Комментарии:
1. ОС Raspberry Pi, предыдущая версия. Raspbian-это разновидность GNU/Linux.
Ответ №1:
Это проблемная ситуация XY прямо здесь. Ваша проблема » X » заключается в том, что
Как я могу получить доступ к клавиатурному устройству, в качестве которого сканер штрих-кода представляется системе независимо от текущего состояния системы?
Но вы думаете, что, решив проблему «У»
Как я могу ввести keygrab, направленный на другой терминал?
Проблема Y сложна, потому что она имеет последствия для безопасности. Проблема X проста, но ее решение зависит от используемой операционной системы.
Вы упомянули файловый дескриптор в стиле bash и POSIX. Так что я предполагаю, что вы используете какой-то вид Linux. И с этим проблему легко решить! Каждое устройство ввода представляет себя как evdev
устройство под /dev/input/event<X>
. Ваш сканер штрих — кода также появится там.
Вы можете либо реализовать evdev
протокол самостоятельно. Или просто используйте libinput для выполнения тяжелой работы.
И то, что он присутствует в качестве независимого устройства ввода, позволяет вам делать несколько вещей:
- Используйте udev, чтобы контролировать, какие учетные записи пользователей получают к нему доступ.
- Используйте udev, чтобы фактически отсоединить его от терминалов, чтобы сканер штрих-кода нельзя было использовать для ввода (возможно, вредных) команд.
Комментарии:
1. оперативники, забыли упомянуть мою операционную систему! Я добавлю это в поток, но я на Raspberry Pi OS! что касается остального, я действительно был осведомлен о проблемах безопасности, но не знал/не думал о том, что вы предложили! Я изучу это и, надеюсь, сообщу о своих результатах, спасибо!
2. Я смог добиться того, чего хотел, благодаря библиотеке libinput , спасибо! Мне пришлось сопоставить раскладку клавиатуры (не проблема с другой клавиатурой, так как программа всегда будет выполняться на одной и той же машине), но это было не так сложно! Спасибо вам 🙂