Сделайте так, чтобы канал fd возвращал true для is_atty () в дочернем процессе - PullRequest
1 голос
/ 11 ноября 2019

Я создаю несколько каналов и передаю их дочернему процессу fork () / exec () как FD stdout и stderr. Но дочерняя программа не выводит цвета ANSI.

Например, команда gcc может выводить диагностику с цветами. Но когда я создаю его как дочернюю часть моей программы и передаю переданные по трубопроводу FD, они не отправляют генерирующие цвета.

С небольшим наблюдением я обнаружил, что он тестирует isatty(STDERR_FILENO) и не отправляетЦветовые коды ANSI, когда он возвращает ложь. Есть ли способ заставить мои каналы обрабатываться как TTYs в дочернем процессе?

PS Также, пожалуйста, не знаю, что я unbuffer команда оболочки, которая была рекомендована для аналогичного вопроса. Я ищу C / POSIX API решение, которое можно было бы переносить на другие устройства. Не только Linux.

Ответы [ 2 ]

3 голосов
/ 11 ноября 2019

Есть два ответа на ваш вопрос, прямой ответ и ответ на вашу проблему XY. Во-первых, последний. Как правило, программы, которые могут выводить цвет / форматирование, подходящее для терминала, или обычный текст, выбирают их по умолчанию на основе isatty, но позволяют передавать явный параметр, чтобы включить или отключить его. Для GCC это -fdiagnostics-color=always. Это почти наверняка то, что вы должны использовать.

Но чтобы ответить на ваш первоначальный вопрос, способ сделать это не использовать канал, а вместо этого псевдо-tty (pty). Для этого используются следующие интерфейсы POSIX: posix_openpt, grantpt, unlockpt и ptsname (чтобы получить имя открываемого устройства). Но есть гораздо более приятный нестандартизированный интерфейс, openpty, который делает все за вас за один вызов, и сопровождающий forkpty, который автоматически разветвляется и подключается к нему через stdin / out / err ребенка. Я бы использовал один из них, если он доступен (они доступны в glibc и musl в системах Linux и в большинстве / во всех системах BSD).

0 голосов
/ 11 ноября 2019

Короткий ответ - нет. Более длинный ответ заключается в том, что вместо конвейера вы можете установить псевдотерминал и запустить в нем команду, которая фиксирует выходные данные компилятора. Это много работы. Man 7 pty для подробного описания.

Вы можете использовать другой подход и определить свое собственное отображение диагностики в цвета для различных команд. Пожалуйста, сделайте мир без наркоманов одолжением и предоставьте возможность не украшать текст ....

...