Hi Theo,

Theo de Raadt wrote on Wed, Jul 26, 2017 at 08:07:53AM -0600:
> Ingo Schwarze wrote:

>> 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.

Ooops, i overlooked the last sentence, sorry.

Some *do* set errno.

For example, the PRINT() macro calls __sprint() which calls
__sfvwrite() in fvwrite.c which contains:

        _base = recallocarray(fp->_bf._base,
            fp->_bf._size + 1, _size + 1, 1);
        if (_base == NULL)
                goto err;

and

        w = (*fp->_write)(fp->_cookie, p, w);
        if (w <= 0)
                goto err;

and

  err:
        fp->_flags |= __SERR;
        return (EOF);

and then PRINT() does

        if (__sprint(fp, &uio)) \
                goto error; \

  error:
        va_end(orgap);
        if (__sferror(fp))
                ret = -1;
        goto finish;

And invalid multibyte sequences in the format string cause
short operations, returning -1 and setting EILSEQ.  Same for
invalid wide character codes in %lc and %ls arguments.

__find_arguments() in GETASTER() is yet another example of a case
that can cause a short operation by mmap(2) failure, returning -1
and setting errno.

Looking through the code, i failed to find any case of a short
operation that allows printf to still succeed apart from the four
dtoa() instances we are discussing right now, and none at all that
do not set errno.  (Not absolutely sure because the code is of
substantial size.)


So not only does errno get set on typical short operations, but -1
gets returned as well, both for malloc(3) and write(3) failure and
EILSEQ and EOVERFLOW, even if something was already written earlier.

That seems like yet another argument to always return -1 on
malloc(3) failure, answering the good question that kettenis@
asked: Should *printf() fail or succeed?  I say, fail.

Yours,
  Ingo

Reply via email to