为什么标准输出不能被取代? [英] why stdout can't be substituted?

查看:128
本文介绍了为什么标准输出不能被取代?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为教育目的,我试图替代标准流标准输出,标准输入和stderr。我第一次抬头流的数据类型,这是我上溯到具有以下成员的结构_IO_FILE(GDB p型_IO_FILE):

for educational purposes, i'm trying to substitute the standard streams stdout, stdin, and stderr. i first looked up the data type of the streams, which i traced back to the struct _IO_FILE with the following members (gdb ptype _IO_FILE):

type = struct _IO_FILE {
    int _flags;
    char *_IO_read_ptr;
    char *_IO_read_end;
    char *_IO_read_base;
    char *_IO_write_base;
    char *_IO_write_ptr;
    char *_IO_write_end;
    char *_IO_buf_base;
    char *_IO_buf_end;
    char *_IO_save_base;
    char *_IO_backup_base;
    char *_IO_save_end;
    struct _IO_marker *_markers;
    struct _IO_FILE *_chain;
    int _fileno;
    int _flags2;
    __off_t _old_offset;
    short unsigned int _cur_column;
    signed char _vtable_offset;
    char _shortbuf[1];
    _IO_lock_t *_lock;
    __off64_t _offset;
    void *__pad1;
    void *__pad2;
    void *__pad3;
    void *__pad4;
    size_t __pad5;
    int _mode;
    char _unused2[20];
}

然后我试图复制的标准输出指针的内存内容:

then i tried to duplicate the memory content of the stdout pointer:

_IO_FILE f1 = {._flags = -72540028, ._offset = -1, ._old_offset = -1, ._fileno = 1, ._chain = stdin, ._lock = stdout->_lock, .__pad2 = stdout->__pad2 };
_IO_FILE *f2 = stdout;
_IO_FILE *f3 = malloc(sizeof(_IO_FILE));
memcpy(f3, stdout, sizeof(_IO_FILE));

fprintf(&f1, "f1\n"); // doesn't work 
fprintf(f2, "f2\n"); // works
fprintf(f3, "f3\n"); // doesn't work

但是,只有指针赋值不会崩溃。我比较通过GDB存储器内容,并都有着相同的结构体成员的内容。

however, only the pointer assignment doesn't crash. i compared the memory content via gdb and all share the same struct member content.

虽然这个问题可能是依赖于平台的:做fprintf中,其他库函数只是指针比较标准流

although this question is likely platform-dependent: do fprintf and the other library functions just compare the pointer to the standard streams?

编辑:我怀疑,这是一个实现或依赖于平台的问题,因为所有的意见建议,这是,我接受这表明了问题的一个可能的原因,答案

edit: i suspected, that this is an implementation or platform dependent issue and since all opinions suggest, that it is, i accepted the answer which suggests one possible cause of the problem.

EDIT2:缩小问题的范围:我使用与12.04版64位的Ubuntu和2.15 EGLIBC版本

edit2: to narrow down the scope of the problem: i am using a 64 bit ubuntu with version 12.04 and an EGLIBC version of 2.15.

推荐答案

每从乌鸦座评论,在莱纳斯系统,锁与该流关联,所以复制文件的数据结构的锁语义干扰。

Per a comment from Corvus, on a Linus system, a lock is associated with the stream, so copying the FILE data structure interferes with lock semantics.

(我认为这个答案没有立即接受,给乌鸦座的时间,进入一个答案。)

(I suggest this answer not be accepted immediately, to give Corvus time to enter an answer.)

旧假设:

我怀疑,在你的C实现,一个文件对象的位置,作为它的意义的一部分。例如,可以存在他们的阵列,和一个指针数组的第一个元素是从指针中减去一个FILE对象找到其在阵列中的索引。那么这个指数被用作系统中的文件号码呼叫,如

I suspect, in your C implementation, the location of a FILE object is used as part of its meaning. E.g., there may be an array of them, and a pointer to the first element of the array is subtracted from the pointer to a FILE object to find its index in the array. Then this index is used as the file number in system calls such as write.

在分配新空间,不是这个数组,指针运算给出错误的结果。

When you allocate new space, it is not in this array, and the pointer arithmetic gives the wrong result.

这篇关于为什么标准输出不能被取代?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆