C中的显示缓冲区

时间:2012-07-04 20:29:59

标签: c

我正在尝试显示缓冲区,但它正在显示特殊字符。这是我的代码:

size_t write(int fd, const void *buf, size_t count)
{

    static size_t (*write_func)(int, const void *, size_t) = NULL;
    if (!write_func)
        write_func = (size_t(*)(int, const void *, size_t)) dlsym(RTLD_NEXT, "write");


    char tmp[count];  

    memcpy(tmp,buf,count);
    printf("  %c \n",tmp[1]);

您对如何解决此问题有任何想法吗?非常感谢你!

1 个答案:

答案 0 :(得分:0)

您在堆栈上分配只读数据的副本。这很危险,因为堆栈空间可能有限。 (在Linux中,只有原始堆栈会动态增长;线程堆栈的大小固定,通常非常小。)

然后使用stdio.h printf()函数将指定数据的第二个字节(即使count可能是1)输出到标准输出,因此您可能会访问无论如何临时阵列。

大多数printf()实现在内部调用write()来刷新缓冲区。根据链接,这可能最终是递归的(您的函数调用printf调用您的函数调用printf等),耗尽进程可用的所有RAM,然后崩溃。

以上都没有意义。

首先,如果您需要复制输入数据,请使用malloc()memcpy()动态执行,然后再使用free()。这样你就不会突然开始在多线程程序中造成崩溃(除了Linux中的原始进程之外,堆栈空间是有限的并且已经修复了所有这些)。

其次,您需要使用使用链接器获得的原始write_func

第三,您需要保留errno以避免客户端程序中出现无法预料的问题。只需使用临时本地int即可存储它。请注意,不仅write(),而且malloc()free()可能会修改errno,您必须隐藏调用者的这些更改。

第四,write()的返回类型为ssize_t,而不是size_t。前者是签名的,后者可能是未签名的。

第五,总是允许短写。你永远不能依靠得到一个“完整”的块;应用程序执行内部处理,特别是在使用套接字时,以奇数大小(特别是TCP / IP和UDP / IP的MTU的倍数)刷新它。您对输入/输出的“修改”必须是无状态的。更糟糕的是,如果你的修改改变了缓冲区长度,并且描述符是非阻塞的,并且write_func()调用返回一个简短的写入,只是在修改后的部分中间没有合理地映射到任何原始字节,你怎么样处理它?真的,你不能重试,因为描述符是非阻塞的;原始应用程序可能会挂起 - 例如,如果以协处理方式使用,同时从具有严格排序要求的对等进程发送和接收数据 - 因为当在应用程序逻辑级别不允许写入时,您的添加将重新发出写入。 / p>

简单地说,你的计划不会起作用。您可能会使用某些特定的简单应用程序,但它可以打破其他可怕的应用程序。无论你想要实现什么,都有更好的方法。

我希望我不是太生硬,但我认真地建议你先创建低级POSIX I / O的细节,然后再创建包装器。 Linux man-pages project是我推荐的一个很好的参考,但我想你可能需要先从一些教程开始。