Re: [PATCH 1/7] config: avoid "write_in_full(fd, buf, len) < len" pattern
From: Jonathan Nieder <hidden>
Date: 2017-09-13 17:47:36
Hi, Jeff King wrote:
I scoured the code base for cases of this, but it turns out that these two in git_config_set_multivar_in_file_gently() are the only ones. This case is actually quite interesting: we don't have a size_t, but rather use the subtraction of two pointers. Which you might think would be a signed ptrdiff_t, but clearly both gcc and clang treat it as unsigned (possibly because the conditional just above guarantees that the result is greater than zero).
Do you have more detail about this? I get worried when I read something like this that sounds like a compiler bug. C99 sayeth: When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined, and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header. How can I reproduce the problem?
We can avoid the whole question by just checking for a negative return value directly, as write_in_full() will never return any value except -1 or the full count. There's no addition to the test suite here, since you need to convince write() to fail in order to see the problem. The simplest reproduction recipe I came up with is to trigger ENOSPC (this only works on Linux, obviously):
Does /dev/full make it simpler to reproduce? Thanks, Jonathan