补丁:“错误文件描述符”与管道和 LD_PRELOAD/libtrash 结合使用

补丁:“错误文件描述符”与管道和 LD_PRELOAD/libtrash 结合使用

非常简短的总结: cat "$file" | patch产生一个Bad file descriptor错误,但当 patch < "$file"libtrash 预加载 和 时才有效LD_PRELOAD,并且仅在较大的项目上。

描述: 对于此示例,我使用从 [1] 下载的普通 linux-3.18.21 内核源代码(当然,还提取了存档)。

我想使用下载的 von [2] 中的 TuxOnIce 对其进行修补并解压。

在这个例子中,我展示了一些大项目,因为只有小文件一切正常。

我在顶级 Linux 源目录中工作,补丁位于../patches/tuxonice-for-linux-3.18.21-2015-09-08.patch.不涉及符号链接,所有内容都在同一文件系统上。

发生以下情况:

$ 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

(退出代码:2)

:

$ 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
[...]

(运行成功)。

libtrash.so该问题与通过环境变量加载有关LD_PRELOAD

  • 默认情况下,我有export LD_PRELOAD=/usr/lib/libtrash.so. [3]
  • 如果我export LD_PRELOAD=''unset LD_PRELOAD,它工作得很好。
  • export TRASH_OFF=YES如果我只是通过 libtrash 提供的方式关闭 libtrash 的功能(但保持其预加载),问题仍然存在。
  • 它肯定与 libtrash 有关,而不是与LD_PRELOAD它本身有关,因为当我export LD_PRELOAD='/usr/lib/libgtk3-nocsd.so.0'(文件存在)时,修补cat $file | patch工作有效。

事实上,我希望cat "$file" | "$programme"得到与 相同的结果"$programme" < "$file",但事实并非如此。

这是一个实际的麻烦,因为在实践中cat,我不会使用 ,而是在压缩的补丁文件上使用诸如xzcat或 之类的东西bzcat,这样我就不需要首先在额外的步骤中解压缩它们。

我使用bash,但这并不重要(在zsh同一范围内)。patch是GNU补丁版本2.7.5,glib-config --version显示1.2.10,我使用arch linux发行版,这个问题确实已经持续了至少几个月,包括更新。内核 3.18.21。

以下是两个输出,分别为strace、 一次strace-ing cat、一次strace-ing patchexport LD_PRELOAD=/usr/lib/libtrash.soexport TRASH_OFF=YES

命令:

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

输出:

http://pastebin.com/TD81znz6

命令:

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

输出:

http://pastebin.com/snvN3YCu

(抱歉链接它,如果我直接把它放在 stackexchange 不会接受我的帖子而不告诉我原因)。

strace我对动态链接等不熟悉。

有谁知道发生了什么事吗?如果这是某个地方的错误,那会是哪里? (补丁、libc、libtrash、动态链接器、...、...、?)

xzcat /usr/src/linux-3.18.21.tar.xz | tar -xv有效(但xzcat some.patch.xz | patch无效),因此它至少与patch.

[1]Linux内核:https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.18.21.tar.xz

[2] 冰上燕尾服:http://tuxonice.nigelcunningham.com.au/downloads/all/tuxonice-for-linux-3.18.21-2015-09-08.patch.bz2

[3] 库垃圾:http://pages.stern.nyu.edu/~marriaga/software/libtrash/

答案1

libtrash被打破:

例如,在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;
     }

0文件描述符的值是完全合法的。由于您使用的是重定向,因此您正在读取stdin,即文件描述符0。我怀疑这就是 中某个地方发生的问题libtrash

答案2

正如 Andrew Henle 指出的那样,这是由于 libtrash 中的错误造成的。我刚刚发布了新版本这应该可以解决此行为。

相关内容