错误:设备的ioctl不适当:程序可以工作,但在〈()内部执行时不能

b5lpy0ml  于 2023-03-17  发布在  其他
关注(0)|答案(2)|浏览(167)

我有一个简单的程序,可以逐行读取文件,并打印每一行。该程序的核心是:

while ((size = getline(&line, &len, f)) != -1)
    printf("%s", line);

现在我有以下问题:
这是可行的:

./test zz

这也适用于:

/bin/cat <(./test zz)

但是当我把输出通过管道传输到其他程序时,它不起作用:

/bin/cat <(./test zz) | /bin/cat

没有输出。当我比较strace时,一个有效,一个无效:

/bin/cat <(strace ./test zz)

/bin/cat <(strace ./test zz) | /bin/cat

我看到这个错误:-1 ENOTTY (Inappropriate ioctl for device)

ioctl(0, TCGETS, 0x7ffc302104d0)        = -1 ENOTTY (Inappropriate ioctl for device)
brk(NULL)                               = 0x55b4e1fd3000
brk(0x55b4e1ff4000)                     = 0x55b4e1ff4000
fstat(0, {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x3), ...}) = 0
ioctl(0, TCGETS, 0x7ffc30210350)        = -1 ENOTTY (Inappropriate ioctl for device)
read(0, "", 4096)                       = 0
close(0)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

编辑:

下面是我概念证明代码:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <unistd.h>

int main(int argc, char **argv) {

    FILE *f;
    char *line = NULL;
    size_t len = 0;
    ssize_t size, cut;

    if (!isatty(STDIN_FILENO) || argc < 2 || (argv[1] == "-"))
        f = stdin;
    else
        if (!(f = fopen(argv[1], "r"))) {
            perror(argv[1]);
            return 1;
        }

    while ((size = getline(&line, &len, f)) != -1)
    printf("%s", line);

    fflush(stdout);
    fclose(f);
    if (line)
        free(line);
    exit(EXIT_SUCCESS);
}

编辑2:

我已删除部件:(!isatty(STDIN_FILENO),这样就解决了这个问题。但是我不明白发生了什么。
我最初添加了这个,这样我的程序就可以将filename作为参数./test zz,或者从管道cat zz | ./test获取输入。

llew8vvj

llew8vvj1#

如果满足以下任一条件,程序将使用stdin作为输入:

  • 标准输入未连接终端。
  • 未提供任何论据。
  • 第一个参数是-

在您展示的场景中,stdin没有连接到终端[1],因此test从stdin读取,但由于您想从文件zz读取,因此没有得到所需的结果。
第一个条件(!isatty(STDIN_FILENO))没有意义。删除它是正确的。其余两个条件足以使cat zz | ./test工作。
1.我不知道为什么。但这并不重要。很多时候stdin不是终端。例如,守护进程的stdin不是终端,因此守护进程启动的程序的stdin也不是终端,除非守护进程采取措施使其成为终端。

lp0sw83n

lp0sw83n2#

应该对stdout执行刷新,而不是对您正在阅读的文件执行刷新。

相关问题