syscall write returns -1 and set errno is a trivial case. I am interested in the status of errno if C write call returning zero or positive. The wrapper syscall.Write in Go simply returns err if errno is not zero for any case, which also includes the case of write call returns positive.
However, the man page of C write call roughly describes errno may also be set but unspecified if we write zero length buffer without explaining any detail.
Thus, the following cases seem unclear:
- What is the status of
errnoifwritecall returning 0 for a file, a non-blocking socket, or a blocking socket? - When and how
writecall returning 0 anderrnois not 0? - What is the status of
errnoifwritecall returning positive? Will it be negative? - Is there any other syscall may encounter the same situation?
I think the above description points to the difference between C write call and Go syscall.Write, which is unclear for developers, here are my thoughts:
According to the man page, returning zero is clearly defined in C write call for to files and for non-blocking sockets, but it's unclear whether there are non-error conditions for a blocking socket which would result in a write() not blocking, returning 0, and (presumably) possibly succeeding later if retried.
Indeed Go directly wraps system call write. However, the following code snippet seems not safe because written equals to zero is a case that may trigger err but we don't want to break the loop:
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
}
Is there any wrong in my suspicion?