[go-nuts] How to handle EINTR from syscall.Dup2

2020-02-28 Thread pboampong5
(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

2020-02-26 Thread pboampong5
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

2020-02-07 Thread pboampong5
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

2020-01-26 Thread pboampong5
> ===  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

2020-01-12 Thread pboampong5
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.