> > From: "Theo de Raadt" <dera...@openbsd.org> > > Date: Wed, 26 Jul 2017 08:07:53 -0600 > > > > > The current behaviour of our implementation is to return the number > > > of characters printed *and* set errno = ENOMEM. > > > > I expect it should not set errno. As a general rule, errno should > > only be set if an error has been indicated. Other short operations > > don't set errno. > > POSIX says: > > "The value of errno should only be examined when it is indicated to > be valid by a function's return value." > > So clobbering errno when not returning a negative number is allowed.
I disagree. Many years ago, malloc would trash errno along the way. It was pretty disruptive, and it got fixed. save_errno changes went in throughout the tree, not just around signal handlers. We don't need more functions doing it wrong. Inverting what POSIX says, thread-local errno should not be changed unless the caller is told to examine it. It should only be changed if the caller is observing it. It is pointless to change errno if it isn't being inspected in relationship to the failed function, so now it can accidentally interferere in buggy code. How about we pick 50 libc functions, and have them set errno=EPERM even upon success. Do you think the software ecosystem would survive that? It's permitted by the rule you layed out, but I think it a vast number of bugs would surface, due to code authors inspecting errno not immediately upon error indication but later. What authors really should do in such circumstances is is assign errno to a temporary at the moment of errno notification, and inspect the temporary later on. But they won't in all cases, so bugs will surface. So unless we want to break existing code, I think my interpretation is safer: A function should only set errno if it is going to return an indicator which will cause inspection. > The real question here is if we should report (partial) success if we > encounter an error halfway through printing/formatting. Sure, but error indication should happen with return value -1.