read () не читает данные из pty, несмотря на то, что они - PullRequest
0 голосов
/ 03 февраля 2019

Моя программа должна эмулировать внешнее устройство, которое обычно подключается через COM-порт (/ dev / ttyUSB0).Программа открывает pty и ждет команды.Вот код:

HostPty::HostPty(const string & HostPty_name)
{
    char name[100] = {0};
    int res = openpty(&_master, &_slave, name, NULL, NULL);
    printf("Name: %s\n", name);
}

string HostPty::nextString()
{
    static const int BUF_SIZE = 4096;
    char buf[BUF_SIZE];
    size_t idx = 0;

    while(true)
    {
        // Read symbols one by one until new line is found
        size_t received_size = read(_master, buf + idx, 1);
        printf("Received a symbol: %02x\n", buf[idx]);

        // Stopping at new line
        if(buf[idx] == '\n')
            break;

        idx++;
    }

    return string(buf, idx);
}

Чтобы проверить этот код, я использую эмулятор терминала miniterm.py, подключающийся к / dev / pty / 6 (или что-либо еще созданное с помощью openpty), и отправляю там текстовые команды.

Когда я набираю команды вручную, все работает нормально - я получаю символы один за другим, как и ожидалось.Но когда я вставляю фрагмент многострочного текста, этот код получает только первый байт, пока я не вставлю символ новой строки (хотя в тексте, который я вставляю, есть несколько символов новой строки).

Есть идеи, как это исправить?

1 Ответ

0 голосов
/ 03 февраля 2019

Есть идеи, как это исправить?

Я не знаю, какой у вас Unix.Я просто попытался воспроизвести вашу проблему под Linux;но строки вставки на моем компьютере работают нормально, поэтому я не могу воспроизвести проблему.

Если в вашем варианте Unix есть трассировщик системных вызовов (Linux: strace, SunOS / Solars: truss, FreeBSD: strace, MacOS: dtruss (?)), Я бы отслеживал системные вызовы:

strace -f -o file_myprog.out ./my_program

miniterm /dev/pty/6

(обратите внимание на -f, что означает, что системные вызовы подпроцессов, создаваемых fork(),также отладка. Это необходимо, потому что Python будет создавать такие подпроцессы.)

Теперь воспроизведите ситуацию, когда программа работает неправильно и завершает работу my_program, используя pkill -KILL my_program.(Отправьте сигнал -KILL, чтобы убедиться, что my_program убит немедленно.)

Сделайте это снова - на этот раз отладка miniterm и убийство miniterm в «неправильной ситуации»:

./my_program

strace -f -o file_miniterm.out miniterm /dev/pty/6

В конце двух выходных файлов (file_myprog.out и file_miniterm.out) вы можете увидеть последние «действия», которые выполняли две программы перед тем, как вы их убили.Возможны различные сценарии:

  • miniterm отправлял данные на /dev/pty/6, но ваша программа не получила никаких данных.В этом случае возникает проблема с самой виртуальной консолью.
  • miniterm по какой-то причине не отправило данные на /dev/pty/6.В этом случае у вас есть проблема с miniterm.
  • miniterm, даже не получили данные, вставленные с использованием read() ...
...