您在堆栈上分配只读数据的副本。这是危险的,因为堆栈空间可能是有限的。(在 Linux 中,只有原始堆栈会动态增长;线程堆栈的大小是固定的,而且通常非常小。)
然后您使用 stdio.hprintf()
函数将指定数据的第二个字节(即使count
可能是 1)输出到标准输出,因此您很可能访问临时数组之外的内容。
大多数printf()
实现write()
在内部调用以刷新缓冲区。根据链接的不同,这最终可能是递归的(你的函数调用printf
调用你的函数调用printf
等等),用尽进程可用的所有 RAM,然后崩溃。
以上没有任何意义。
首先,如果您需要复制输入数据,请使用malloc()
and动态复制memcpy()
,然后再复制free()
。这样你就不会突然开始在多线程程序中导致崩溃(除了 Linux 中的原始进程,堆栈空间是有限且固定的)。
其次,您需要使用write_func
通过链接器获得的原始文件。
第三,您需要保留errno
以避免在客户端程序中出现不可预见的问题。只需使用临时本地int
来存储它。请记住,不仅write()
,而且可能修改,malloc()
并且您必须对调用者隐藏这些更改。free()
errno
第四,返回类型write()
is ssize_t
, not size_t
。前者是签名的,后者可能是未签名的。
第五,总是允许短写。您永远不能依赖获得“完整”块;应用程序进行内部处理,尤其是在使用套接字时,以奇数大小刷新它(特别是 TCP/IP 和 UDP/IP 的 MTU 的倍数)。您对输入/输出的“修改”必须是无状态的。更糟糕的是,如果您的修改更改了缓冲区长度,并且描述符是非阻塞的,并且write_func()
调用在修改部分的中间返回一个简短的写入,它没有明智地映射到任何原始字节,你将如何处理它?你不能重试,真的,因为描述符是非阻塞的;原始应用程序可能会挂起——例如,如果以协同处理方式使用,同时从具有严格排序要求的对等进程发送和接收数据——因为当应用程序逻辑级别不允许添加时,您的添加将重新发出写入。
简而言之,您的计划行不通。您可能会让它与一些特定的简单应用程序一起工作,但它可能会严重破坏其他应用程序。无论你想达到什么目标,都有更好的方法。
我希望我不会太直率,但我强烈建议您先了解低级 POSIX I/O 的来龙去脉,然后再围绕它们创建包装器。Linux 手册页项目是我可以推荐的一个很好的参考,但我认为您可能需要先从一些教程开始。