patch: “bad file descriptor” em combinação com pipe e LD_PRELOAD / libtrash

1

Resumo muito curto: cat "$file" | patch produz um Bad file descriptor -error, mas patch < "$file" funciona, quando a libtrash é pré-carregada com LD_PRELOAD e somente em projetos maiores.

Descrição: Para este exemplo, eu trabalho nas fontes de kernel vanilla linux-3.18.21 como baixadas de [1] (e extraí o arquivo, é claro).

Eu quero fazer o patch com o TuxOnIce como baixado von [2] e extraído.

Neste exemplo, mostro um projeto grande, já que com arquivos pequenos tudo funciona bem.

Eu trabalho no diretório de origem do Linux de nível superior e, a partir daí, o patch está localizado em ../patches/tuxonice-for-linux-3.18.21-2015-09-08.patch . Não há links simbólicos envolvidos, tudo no mesmo sistema de arquivos.

O seguinte acontece:

$ cat ../patches/tuxonice-for-linux-3.18.21-2015-09-08.patch | patch -p1 --dry-run
patch: **** can't open file Documentation/kernel-parameters.txt : Bad file descriptor

(código de saída: 2)

mas :

$ patch -p1 --dry-run < ../patches/tuxonice-for-linux-3.18.21-2015-09-08.patch 
checking file Documentation/kernel-parameters.txt
checking file Documentation/power/tuxonice-internals.txt
[...]

(é executado com sucesso).

O problema tem algo a ver com libtrash.so carregado por meio da variável de ambiente LD_PRELOAD :

  • Por padrão, eu tenho export LD_PRELOAD=/usr/lib/libtrash.so . [3]
  • Se eu export LD_PRELOAD='' ou unset LD_PRELOAD , funciona bem.
  • Se eu apenas desligar o funcionamento do libtrash (mas mantê-lo pré-carregado), por export TRASH_OFF=YES , que é o caminho fornecido pelo libtrash, os problemas persistem.
  • Definitivamente tem a ver com libtrash e não com LD_PRELOAD , já que quando eu export LD_PRELOAD='/usr/lib/libgtk3-nocsd.so.0' (o arquivo existe) o patch com cat $file | patch funciona.

Na verdade, espero que cat "$file" | "$programme" resulte o mesmo que "$programme" < "$file" , mas isso não acontece.

É um incômodo prático, já que na prática, em vez de usar cat , eu usaria coisas como xzcat ou bzcat nos arquivos de correção compactados para não precisar descompactá-los em uma etapa extra primeiro .

Eu uso bash , mas isso não importa (dentro de zsh o mesmo). patch é a versão do patch GNU 2.7.5, glib-config --version mostra 1.2.10, eu uso uma distribuição arch linux e esse problema persistiu por pelo menos vários meses, incluindo atualizações. Kernel 3.18.21.

Aqui estão duas saídas com strace , uma vez strace -ing cat , uma vez strace -ing patch , com export LD_PRELOAD=/usr/lib/libtrash.so e export TRASH_OFF=YES :

Comando:

$ strace cat ../patches/tuxonice-for-linux-3.18.21-2015-09-08.patch | patch -p1 --dry-run

Saída:

link

Comando:

$ cat ../patches/tuxonice-for-linux-3.18.21-2015-09-08.patch | strace patch -p1 --dry-run

Saída:

link

(Desculpe por vinculá-lo, se eu colocasse diretamente o stackexchange não aceitaria o meu post sem me dizer por quê).

Eu não estou familiarizado com links dinâmicos, strace e assim por diante.

Alguém sabe o que acontece? Se isso é um bug em algum lugar, onde seria? (patch, libc, libtrash, linker dinâmico, ..., ...,?)

xzcat /usr/src/linux-3.18.21.tar.xz | tar -xv funciona (mas xzcat some.patch.xz | patch não), então tem pelo menos alguma especificidade com patch .

[1] kernel do Linux: link

[2] TuxOnIce: link

[3] libtrash: link

    
por Golar Ramblar 08.02.2016 / 14:04

2 respostas

1

libtrash está quebrado:

Por exemplo, em helpers.c :

char* make_absolute_path_from_dirfd_relpath(int dirfd, const char *arg_pathname)
{
   char *abs_path = NULL;

   if (arg_pathname == NULL)
     {
    return NULL;
     }
   else if (arg_pathname[0] == '/' || dirfd == AT_FDCWD)
     {
    return arg_pathname;
     }
   else if (dirfd <= 0)
     {
    errno = EBADF;
    return NULL;
     }

Um valor de 0 para um descritor de arquivo é perfeitamente legítimo. Como você está usando o redirecionamento, está lendo em stdin , que é o descritor de arquivo 0 . Eu suspeito que é o que está quebrando em algum lugar em libtrash .

    
por 09.02.2016 / 17:09
1

Como Andrew Henle apontou, isso foi devido a um bug no libtrash. Acabei de lançar uma nova versão que deve corrigir esse comportamento.

    
por 25.03.2018 / 21:48