2011-12-20 3 views
0

Я модифицировал GNU tee к cycleteeSource Code (Вы можете загрузить двоичный файл из https://github.com/vls/cycletee/tree/master/bin)llseek возвращает ESPIPE при вызове zcat all.tgz | ./cycletee

Что это может быть объяснено в следующем примере:

seq 10 | cycletee 1.txt 2.txt 3.txt 
cat 1.txt // prints 1, 4, 7, 10 
cat 2.txt // prints 2, 5, 8 
cat 3.txt // prints 3, 6, 9 

Тогда существует all.tgz (См. Приложение для сценария здания)

all.tgz имеет три текстовых файла и всего 9000000 строк.

Все в порядке. Как:

seq 10000000 | ./cycletee 1.txt 2.txt 3.txt 

zcat all.tgz | tee 1.txt > /dev/null 

zcat all.tgz | tail // got 9000000 at the last line 

кроме вызова:

zcat all.tgz | ./cycletee 1.txt 2.txt 3.txt 

, когда он читает No.3000000 линию, она завершает свою работу.

Трассирование это я получил это сообщение, и он вышел:

_llseek(2, 0, 0xffbec3d0, SEEK_CUR)  = -1 ESPIPE (Illegal seek) 

Вопрос

  • Любой человек может указать на проблему моего исходного кода?

  • Любая методика отладки для выяснения проблемы будет оценена по достоинству. Я не знаю, как использовать gdb в этой ситуации.

Приложение

  • all.tgz может быть построен с помощью этого Python sciprt https://gist.github.com/1500742

  • среды: Ubuntu 10.04 32bit, CentOS 5.4 64-битной

ответ

1

Из источника:

read: 
    buffer[0] = '\0'; 
    ptr = fgets(buffer, (int) sizeof buffer, stdin); 
    if(NULL == ptr) { 
     if(ferror(stdin)) { 
      error (0, errno, "%s", _("standard input")); 
      ok = false; 
     } 
     flag_break = true; 
     break; 
    } 
    bytes_read = strlen(buffer); 


     if (bytes_read < 0 && errno == EINTR) 
     { 
      flag_continue = true; 
      backup_i = i; 
      break; 
     } 
     if (bytes_read <= 0) { 
      flag_break = true; 
      break; 
     } 

    if (descriptors[0] 
      && fwrite(buffer, bytes_read, 1, descriptors[0]) != 1) 
      { 
       error (0, errno, "%s", files[0]); 
       descriptors[0] = NULL; 
       ok = false; 
      } 
... 

Я не думаю, что это будет работать на двоичный вход (вход, который содержит NULs). [Учитывая подписанность bytes_read, у меня есть сильное подозрение, что fread() был заменен на fgets() + strlen(); ] Это может быть или не быть причиной ошибки PIPE, но это выглядит очень неправильно.

+0

Вы правы. 'zcat' выдавал некоторые двоичные данные при переходе к следующему файлу. Я использую 'fgets' +' memchr' для определения прочитанных байтов. Он хорошо работает – ukessi

1

Вы не можете позвонить llseek или ftell на трубе или в розетке, они не являются файлами, доступными для поиска.

Вы можете использовать отладчик, например gdb (его действительно стоит изучить, а GDB очень хорошо documented) и, например, поставить точку останова на _llseek

Вы также можете использовать strace или ltrace

 Смежные вопросы

  • Нет связанных вопросов^_^