git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: ERANGE strikes again on my Windows build; RFH

From
Johannes Sixt <j6t@kdbg.org>
Date
Dec 29, 2019, 18:08 UTC
Message-ID
<b6e3fc5b-1d16-f7c9-0069-a2938b00f0fc@kdbg.org>
In-Reply-To
<a32e075b-9e6c-2b6a-8619-0330501eee97@gmail.com>
Am 29.12.19 um 18:25 schrieb Alban Gruin:
Show 46 quoted lines
> Le 29/12/2019 à 15:29, Torsten Bögershausen a écrit :
>> On Sat, Dec 28, 2019 at 04:41:42PM +0100, Johannes Sixt wrote:
>>> In sha1-file.c:read_object_file_extended() we have the following pattern:
>>>
>>> 	errno = 0;
>>> 	data = read_object(r, repl, type, size);
>>> 	if (data)
>>> 		return data;
>>>
>>> 	if (errno && errno != ENOENT)
>>> 		die_errno(_("failed to read object %s"), oid_to_hex(oid));
>>>
>>> That is, it is expected that read_object() does not change the value of
>>> errno in the non-error case. I find it intriguing that we expect a quite
>>> large call graph that is behind read_object() to behave this way.
>>>
>>> What if a subordinate callee starts doing
>>>
>>> 	if (some_syscall(...) < 0) {
>>> 		if (errno == EEXIST) {
>>> 			/* never mind, that's OK */
>>> 			...
>>> 		}
>>> 	}
>>>
>>> Would it be required to reset errno to its previous value in this
>>> failure-is-not-an-error case?
>>>
>>> The problem in my Windows build is that one of these subordinate
>>> syscalls is vsnprintf() (as part of a strbuf_add variant, I presume),
>>> and it fails with ERANGE when the buffer is too short. Do I have to
>>> modify the vsnprintf emulation to restore errno?
>>
>> If you ask me: I think so, yes.
>> At least the documentation about vsnprintf does not mention that errno is touched at all.
>> That is the man pages for Linux and Mac OS, or see here:
>> https://linux.die.net/man/3/vsnprintf
>>
>> It would make sense to analyze the complete callstack, I think.
>> Is your problem reproducable ?
>>
>> Changing the function strbuf_vaddf() strbuf.c seems to be straight forward to me.
>>
> 
> According to the standard, vsnprintf() _can_ change errno[1] (and the
> BSDs do so[2][3][4].)  But apparently, not to ERANGE.

I am not worried about errno being set (or to what value) when there actually is an error. I am asking what to do when there is actually *no* error. In my vsnprintf emulation, the case where ERANGE happens is *not* an error as far as the emulation is concerned.

What if in the huge call graph behind read_object() some function changes errno to, say, EEXIST, EISDIR, or ENODIR and the condition under which this happens is *not* an error in that context? Is the function required to restore the original errno?

Consider the task to create file "foo/bar.c". We would have to mkdir("foo"), but it is *not* an error when mkdir() fails with errno == EEXIST. Are we required to reset errno back to its old value?

(I know, read_object() is unlikely to allocate files, but I think I have to explain in some way that the context may define that there is no error -- even though a lower-level function failed and modified errno.)

-- Hannes
Previous: Alban GruinNext: Junio C Hamano
Message 5 of 10 in “ERANGE strikes again on my Windows build; RFH”
  1. Johannes SixtDec 28, 2019
  2. Torsten BögershausenDec 29, 2019
  3. Andreas SchwabDec 29, 2019
  4. Alban GruinDec 29, 2019
  5. Johannes SixtDec 29, 2019
  6. Junio C HamanoDec 30, 2019
  7. Jonathan NiederDec 30, 2019
  8. Johannes SixtDec 30, 2019
  9. Jonathan NiederDec 30, 2019
  10. Michal SuchánekJan 5, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.