Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syscall: errno handling for write call may inappropriate #26907

Closed
changkun opened this issue Aug 9, 2018 · 3 comments
Closed

syscall: errno handling for write call may inappropriate #26907

changkun opened this issue Aug 9, 2018 · 3 comments

Comments

@changkun
Copy link
Member

changkun commented Aug 9, 2018

syscall write returns -1 and set errno is a trivial case. I am interested in the status of errno if write call returning zero or positive. The wrapper of Go simply returns err if errno is not zero, which also includes the case of write call returns positive.

if e1 != 0 {

However, the man page of write call roughly describes errno may also be set but unspecified if returns zero without explaining any detail.

Thus, the following cases seem unclear:

  1. What is the status of errno if write call returning 0?
  2. When and how write call returning 0 and errno is not 0?
  3. What is the status of errno if write call returning positive?
  4. Is there any other syscall may encounter the same situation?
  5. How do above influences Go syscall wrapper?
@ianlancetaylor
Copy link
Contributor

We don't use the issue tracker for questions. Please see https://golang.org/wiki/Questions . Thanks.

In reading the man page, you are confusing the behavior of the C library function write with the system call write. Go's syscall package invokes the system call directly. The system call in effect returns two values: the number of bytes written, and an error value. Those translate directly into the values returned by syscall.Write.

Closing because there is no action to take.

@changkun
Copy link
Member Author

changkun commented Aug 26, 2018

Hi @ianlancetaylor, thanks for your clarification. I think this issue points to the difference between C write call and Go syscall.Write, which is unclear for developers.

According to the man page, the 0 return 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
}

@ianlancetaylor
Copy link
Contributor

If you are speculating, please use a forum; see https://golang.org/wiki/Questions . If you are reporting a bug, please include a complete test program that we can use to reproduce the problem. Thanks.

@golang golang locked and limited conversation to collaborators Aug 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants