-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
os: wrong os.File.Write return values at device end #6855
Labels
Milestone
Comments
ktrace shows the difference between write to a file and direct write to a character device. Writing 10 MiB blocks to a file shows the following ktrace dump: ... (omitting the successful previous writes) ... RET write 10485760/0xa00000 CALL write(0x3,0xc201ec9000,0xa00000) RET write -1 errno 28 No space left on device Writing to the character device shows: ... (omitting the successful previous writes) ... CALL write(0x3,0xc2014b8000,0xa00000) RET write 8388608/0x800000 CALL write(0x3,0xc201cb8000,0x200000) RET write 0 The difference is: - For a regular file on a file system, the syscall returns -1 if the write cannot complete and sets errno 28 - For a short write at the end of a character device, the syscall returns the number of bytes successfully written. In subsequent attempts to write to that device, zero is returned (as can be seen above). Never -1 gets returned and never any errno is set. FreeBSD base system tools, dd for instance, check for a short write on a device due to this behaviour of write(2). If os.File.Write() is supposed to behave like the documentation suggests, the method must be extended such that it actually does set err a non-nil error when n != len(b). |
yes. Go 1.2 doesn't change anything in this aspect. I don't have FreeBSD installation available, but I tested vnconfig(1) created character device on NetBSD and confirmed that the behavior is the same (no errors reported for (*os.File).Write). So I suspect this behavior is common to all BSDs. The remaining problem is wether the error is in code or docs? Labels changed: added priority-later, removed priority-triage, os-freebsd. Status changed to Accepted. |
I would expect that this case is not really mainstream, otherwise we would have had the issue earlier. Also, the go documentation is crystal clear on the behaviour of Write: "Write returns a non-nil error when n != len(b)." So, existing go code that relies on this specific behaviour of *BSD's write syscall should not have been written that way in the first place. |
I believe this was fixed by https://golang.org/cl/36800043 (which was committed as part of https://golang.org/cl/36930044). |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
by thomas.e.zander:
The text was updated successfully, but these errors were encountered: