c语言syscall函数,C写调用和Go syscall.Write之间的区别

本文详细解析了C语言中的write系统调用,重点讨论了其返回值(0、正数或-1)的意义,errno状态,以及特殊情况如零长度写入的处理。通过示例代码展示了如何正确处理write操作及其潜在错误处理策略。
摘要由CSDN通过智能技术生成

小编典典

使用write,只有两种情况需要考虑:

如果失败,则结果为-1并被errno设置。

如果成功,则结果为0或更大errno且未设置。

除非您对历史上的Unix实现感兴趣,否则没有其他情况可以考虑。

write可能返回0 的原因是因为输入缓冲区可能为空。

然而,C的手册页write呼叫大致介绍了errno 可能 ,如果我们写零长度的缓冲区没有解释任何细节也可以设置,但不确定。

所有这一切意味着0长度写入可能会失败。如果失败,则返回-1并设置errno。如果成功,则返回0且不设置errno。手册页中刚刚提到了这与其他任何写入操作相同的行为,因为人们可能会惊讶地发现0长度写入可能会失败。

errno如果write针对文件,非阻塞套接字或阻塞套接字的调用返回0 的状态是什么?

在这种情况下,errno未设置,因为write没有失败。仅当输入缓冲区为零字节时才会发生这种情况。

什么时候以及如何write调用返回0而errno不是0?

这不会发生。errno设置要么返回值为-1,要么errno未设置返回值为0或更大。

errnoif write通话返回正数的状态如何?会否定的?

该errno值将不会被设置。它的值将与write调用前相同。

还有其他系统调用可能会遇到相同的情况吗?

通常,系统调用将返回错误 或 成功。他们不会两者兼而有之。查看其他手册页的“返回值”部分,您将发现它们与大致相同write。

此代码是安全的。

func writeAll(fd int, buffer []byte) bool {

length := len(buffer)

for length > 0 {

written, err := syscall.Write(fd, buffer)

if err != nil { // here

return false

}

length -= written

buffer = buffer[written:]

}

return true

}

请注意,这有点多余,我们可以这样做:

func writeAll(fd int, buf []byte) bool {

for len(buf) > 0 {

n, err := syscall.Write(fd, buf)

if err != nil {

return false

}

buf = buf[n:]

}

return true

}

关于C的注释

从技术上讲,write它既是系统调用又是C函数(至少在许多系统上)。但是,C函数只是一个调用系统调用的存根。Go不会调用此存根,而是直接调用系统调用,这意味着此处不涉及C(嗯,直到您进入内核为止)。

手册页显示了C存根的调用约定和行为write。Go选择将其行为复制到自己的存根中syscall.Write。实际的系统调用本身仅具有汇编语言界面。

2020-07-02

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值