LINUX.ORG.RU

Проверка активности pipe


0

1

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

$echo $data > $pipe

как побороть сею беду или предварительно чекнуть пайп на активность? Заранее благодарен!


Ответ на: комментарий от anonymous

Не самое удачное решение, хотелось бы всетаки чекнуть пайп на активность и в случае неактивности его удалить...

AlexDi
() автор топика

На C знаю, как это сделать (см. fifo(7) про ENXIO), на каком-нибудь перлопитоне тоже скорее всего можно. Простого решения на шелле и утилитах не могу придумать (к сожалению, в читателе до прибытия писателя open не завершается — так бы fuser можно было проверить открытость пайпа, но он «ещё не открыт»).

Как должна работать такая утилита, вкратце: открыть пайп open с O_NONBLOCK|O_WRONLY, если вернулся ENXIO — читателя нет, пайп можно удалять, если же открылся — отключить O_NONBLOCK через fcntl(F_SETFL) и дальше уже писать что задумали (например, сделать exec того, что указано в командной строке, и отдать ему в наследство наш пайп в качестве stdout)

LeninGad
()
Последнее исправление: LeninGad (всего исправлений: 2)
Ответ на: комментарий от LeninGad
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

int main(int argc, char *argv[])
{
  int fd;
  if (argc<2) {
    fprintf(stderr,"Usage: %s fifo command args...\n",argv[0]);
    return 2;
  }
  do {
    fd = open(argv[1],O_WRONLY|O_NONBLOCK);
  } while (fd<0 && errno == EINTR);
  if (fd<0) {
    if (errno == ENXIO) {
      unlink(argv[1]);
      return 1;
    } else {
      perror("Pipe open");
      return 3;
    }
  } else {
    fcntl(fd,F_SETFL,0);  /* disable O_NONBLOCK */
    dup2(fd,1);           /* replace stdout */
    close(fd);
    execvp(argv[2],argv+2);
  }
  return 0;
}

Назвать можно trypipe, запускать trypipe my/pipe echo muahaha.

LeninGad
()
Последнее исправление: LeninGad (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.