[go-nuts] How to handle EINTR from syscall.Dup2
(I've asked the same question already, but probably in the wrong thread, sorry for the repost.) What to do on EINTR from syscall.Dup2 (Linux)? 1) It never happen. 2) Retry. 3) Take it as irrecoverable. 4) Take it as success. I know this is more of an OS question, but it all started with the asynchronous preemption announcement, and I don't know where else to get help. In the signal(7) man page, dup2 is neither mentioned in the "affected by SA_RESTART" list, nor in the other list. Is it affected or not? According to [1][2], dup2 can close newfd and still fail, therefore it should *never* be retried because a retry would cause a dangerous race. This would mean that a signal during dup2 (nothing out of the ordinary) would produce an irrecoverable condition! The man page says that close+dup is done "atomically", but it isn't clear whether "close and fail" is a possibility or not. Someone also hypothesizes that EINTR from dup2 can actually mean success, because it comes from the implicit close(2) and EINTR from close is not a failure indication on Linux (there are plans to change it to EINPROGRESS), see also [3][4]. I hope someone can shed some light on this, thanks. [1] https://github.com/libuv/libuv/issues/462 [2] https://www.python.org/dev/peps/pep-0475 [3] https://stackoverflow.com/questions/15930013/can-dup2-really-return-eintr [4] https://lwn.net/Articles/576478 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/ec07c211-4b69-4791-9e8f-1b4122130424%40googlegroups.com.
Re: [go-nuts] Re: Lot's of test errors in package zmq4 with Go version 1.14, no errors with earlier versions
How should I handle EINTR from syscall.Dup2 (Linux)? - The effect of SA_RESTART on dup2(2) is undocumented. - If dup2 returns EINTR, can I be sure that nothing has been done? (Otherwise retrying is racy.) - libuv uv__dup2_cloexec [1] never retries the syscall but treats EINTR as a failure. - Python os.dup2 [2] also never retries, but it seems that it treats EINTR as success ("ignores EINTR error"). - See also unresolved question: https://stackoverflow.com/questions/15930013/can-dup2-really-return-eintr All very confusing. Also, can os.File.Close / syscall.Close return EINTR? Is it affected by SA_RESTART? [1] https://github.com/libuv/libuv/issues/462 [2] https://www.python.org/dev/peps/pep-0475 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/9c8cc343-48f0-4f14-9e32-9b14647bacd0%40googlegroups.com.
[go-nuts] Re: Error checking in Go: The `try` keyword
Hi, as I recently mentioned in another thread, you can already use this error handling stye without language changes: https://play.golang.org/p/nDnXxPXeb-- (The function is named "check", not "try".) See error decoration at the bottom. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/7d5b40ba-c2ab-49da-a9d0-f56e5106a54b%40googlegroups.com.
[go-nuts] Re: Experience report on a large Python-to-Go translation
> === Catchable exceptions require silly contortions === I think the community is aware of the problem but still trying to find a more Go-like solution. Take a look at some of the proposals if you haven't: https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling.md https://github.com/golang/go/labels/error-handling As you know, what we usually use now is a chain of: x, err = f(y); if err != nil { /* handle err */ } where *handle err* usually involves a return/goto/break, so that the nesting level is independent of the number of steps. But one can also use the panic/recover mechanism locally to shorten the above into something like this: x, err = f(y); check(err) Example here: https://play.golang.org/p/Gli8_bgyuDS (Variations are possible, including error decoration and callback handlers.) Sometimes panic/recover across different functions (like you did) is more appropriate. The convention is not to use it across package boundaries. > And all it would take to get there is two minor loosenings of restrictions. > > 1. The panic function has a new property, "terminating". [...] log.Fatal and os.Exit have the same problem. They are not "terminating statements", so if you want them at the bottom of a function with result parameters you have to add a panic("unreachable"). But I think it's very rare not to have one of the "success" paths at the end; in 8 years it happened to me like a couple of times. Do you really expect to have throw() at the bottom of functions? > 2. A recover() call is no longer required to be within the lexical frame of a defer(). Would it be less ugly like this? (with recover in the catch func.) | defer catch("recoverable", func(err error) { | fmt.Println("Recover:", err) | }) > === Absence of iterators === Interesting proposal. The new expression accepted by "range" would be of type "func() (T, bool)", called repeatedly to get the next element until false. While the available solution is verbose and uses 2 more variables, I don't think its readability is so bad: | for f := repo.commits();; { | commit, ok := f() | if !ok { | break | } | do_stuff_to(commit) | } Of course if you need the index you have to add yet more cruft. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/d5115a08-aadb-420e-912c-9145ea7ae611%40googlegroups.com.
[go-nuts] Ignoring errors from os.File.Close
Hello, Up until now I've been in the habit of checking Close errors on files written to, but I never closed os.Stdout after use (for the purpose of error reporting), and now I'm thinking that's inconsistent. In this commit message [1], Ian Lance Taylor wrote: "Programs should always check the error return of Close for a file opened for writing." Does this imply that if I use os.Stdout I need to Close it and check the error? If no, why is that different? I see no reason to expect weaker error reporting for stdout than any other file opened by the program itself. For example gofmt doesn't close stdout, therefore this command could silently produce an incomplete output on a close-only error: $ gofmt foo.go >bar.go On the contrary, the Gnu coreutils for example, always close stdout and check the error, therefore this cat would report it and exit non-zero: $ gofmt foo.go | cat >bar.go It seems inconvenient to always Close and check os.Stdout after use: I would have to arrange for it in the majority of my programs, even the most simple. But if I don't do that, why should I bother to check any os.File.Close error at all? In a class of equally important errors, if I'm ignoring some of them for no particular reason, I might as well ignore all of them. What's your opinion? In this old thread [2], Rob Pike wrote: "If the situation requires you to handle errors on close, handle them. If it does not, you can defer the close. That's all there is to it." Specific situations may call for specific error handling, but unfortunately in the vast majority of cases there is little assumptions I can make. If the data is not on its way to the disc I want to tell the user, but not at the cost of much boilerplate if the condition is rare enough. I want to meet general expectations and be consistent. (Telling the user usually means to print a message and/or make sure the exit status is non-zero.) "defer f.Close()" is common in the wild, even for files written to. Many new users learn it as a general pattern because the read-only "requirement" is rarely discussed (for example Effective Go doesn't mention it in its "defer f.Close()" example). It seems that, with most filesystem drivers, an EIO error that is not reported by Write has a high chance to be missed by Close too (unless you also call Sync), because a Close doesn't necessarily initiate any writeback from the kernel. So I wouldn't worry about EIO from Close (unless I also use Sync) because I already accepted the compromise, therefore I'm left with ENOSPC or EDQUOT (i.e. "no space left" errors). Is it possible that Write doesn't report ENOSPC or EDQUOT but Close does? According to the Linux close(2) man page, yes, on NFS; what about anything else? The same man page was changed from: "Not checking the return value of close() is a common but nevertheless serious programming error" to: "A careful programmer will check the return value of close()". Now, that is helpful! :D In summary I'm looking for a rule of thumb: should I check the Close error for files written to? Should I Close and check os.Stdout after use (for the purpose of error reporting)? For consistency I would expect either yes to both questions or no to both questions. Thanks to anyone who read this far. [1] https://github.com/golang/go/commit/6cbd737c8e4a5aa5a8e85895c5ee6ff53a358622 [2] https://groups.google.com/d/topic/golang-nuts/Hj7-HV-W_iU/discussion -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/21eff98e-a2b1-4cf1-8a90-e3d489e47b76%40googlegroups.com.