Узнайте, блокируется ли конец чтения канала - PullRequest
1 голос
/ 16 января 2009

Я пытаюсь выяснить, ожидает ли дочерний процесс ввода данных от пользователя (без разбора его выходных данных). Возможно ли в C на Unix определить, имеет ли конец чтения канала в настоящий момент блокировку вызова read ()?

Дело в том, что я не контролирую программы, выполняемые в дочерних процессах. Они печатают все виды многословного мусора, который я обычно хотел бы перенаправить в / dev / null. Иногда, хотя кто-то предложит пользователю что-то. (С подсказкой, не имеющей надежного формата.) Поэтому моя идея была:

  • В цикле:
    • Слейте стандартный вывод ребенка, добавьте его во временный буфер.
    • Проверьте (не знаю, как), запрашивает ли ребенок ввод пользователя, и в этом случае буфер выводится на стандартный вывод.
  • Когда ребенок выходит, выбросьте буфер.

Ответы [ 6 ]

1 голос
/ 20 января 2009

Звучит так, как будто вы пытались контролировать dpkg, когда иногда какой-то скрипт post-inst запрашивает администратора, может ли он переопределить какой-либо файл конфигурации.

В любом случае, вы можете посмотреть, как работает strace:

strace -f -etrace=read your.program

Конечно, вам нужно следить за тем, какие fds являются каналами, о которых вы пишете, но в любом случае вам, вероятно, нужен только stdin.

1 голос
/ 18 января 2009

У вас есть следующие варианты:

  • если вы знаете, что ребенку понадобится определенный ввод (например, оболочка, которая будет читать команду), просто напишите в канал
  • если вы предполагаете, что ребенок обычно ничего не читает, но может делать это иногда, вам, вероятно, понадобится что-то вроде управления заданиями в оболочке (используйте терминал для связи с ребенком, используйте группы процессов и TIOCSPGRP ioctl на терминале чтобы перевести ребенка в фоновый режим, он получит SIGTTIN при попытке чтения с терминала, и вы можете ждать () для этого). Вот как bash обращается с такими вещами, как "(sleep 10; read a;)&"
  • если вы не знаете, что написать, или у вас больше возможностей, вам придется проанализировать вывод
1 голос
/ 16 января 2009

Дело в том, что я не контролирую программы, выполняемые в дочерних процессах. Они печатают все виды многословного мусора, который я обычно хотел бы перенаправить в / dev / null. Иногда, хотя кто-то предложит пользователю что-то. (С подсказкой, не имеющей надежного формата.) Поэтому моя идея была:

  • В цикле:
    • Слейте стандартный вывод ребенка, добавьте его во временный буфер.
    • Проверьте (не знаю, как), запрашивает ли ребенок ввод пользователя, и в этом случае буфер выводится на стандартный вывод.
  • Когда ребенок выходит, выбросьте буфер.
0 голосов
/ 16 января 2009

Обычно вы просто пишете в канал, или используете select или poll. Если вам нужен механизм рукопожатия, вы можете сделать это внеплановым способом или придумать внутренний протокол.

Я не знаю, есть ли встроенный способ узнать, блокирует ли читатель на другом конце. Зачем тебе это знать?

0 голосов
/ 16 января 2009

Я не думаю, что это правда: например, прямо перед вызовом read () на стороне читателя, у канала будет читатель, который на самом деле не читает.

0 голосов
/ 16 января 2009

Если я правильно помню, у вас не может быть канала без ридера, что означает, что у вас всегда есть ожидающий чтения (2) или выбора (2) syscal.

...