This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Implement C11 annex K?
- From: Rich Felker <dalias at libc dot org>
- To: Paul Eggert <eggert at cs dot ucla dot edu>
- Cc: Russ Allbery <eagle at eyrie dot org>, libc-alpha at sourceware dot org
- Date: Thu, 14 Aug 2014 13:46:16 -0400
- Subject: Re: Implement C11 annex K?
- Authentication-results: sourceware.org; auth=none
- References: <Pine dot LNX dot 4 dot 64 dot 1408132054090 dot 16622 at digraph dot polyomino dot org dot uk> <53EBD7D9 dot 1040008 at cs dot ucla dot edu> <20140813213520 dot GQ12888 at brightrain dot aerifal dot cx> <53EBEACD dot 3070000 at googlemail dot com> <87k36cc559 dot fsf at windlord dot stanford dot edu> <20140814022501 dot GT12888 at brightrain dot aerifal dot cx> <87r40jbq2p dot fsf at windlord dot stanford dot edu> <20140814054610 dot GV12888 at brightrain dot aerifal dot cx> <87ha1fbnrp dot fsf at windlord dot stanford dot edu> <53ECD392 dot 30904 at cs dot ucla dot edu>
On Thu, Aug 14, 2014 at 08:19:46AM -0700, Paul Eggert wrote:
> Russ Allbery wrote:
> >I would really like ... for someone to explain to me why I'm wrong
> >in the form of more readable and maintainable code
> >that doesn't use strlcpy/strlcat.
>
> It seems that our emails crossed; please take a look at
> https://sourceware.org/ml/libc-alpha/2014-08/msg00226.html
>
> Here's another (untested) way to skin the cat, also considerably
> nicer than the strlcpy+strlcat version:
>
> char *
> vector_join(const struct vector *vector, const char *sep)
> {
> char *string;
> size_t size;
> FILE *f = xopen_memstream(&string, &size);
> for (size_t i = 0; i < vector->count; i++)
> xfprintf(f, "%s%s", i ? sep : "", vector->strings[i]);
> xfclose(f);
> return string;
> }
>
> This may help to explain why POSIX didn't standardize strlcpy.
Actually open_memstream (without the x, uhg) is a really nice solution
to the problem, because it allows you to isolate your checks for
failure to two places:
1. Failure of the initial open_memstream() call
2. A single ferror() check before fclose().
Since the error flag is sticky and it's not an error to attempt to
write to a stream that already has errors, there's no need to check
individual write operations.
I think the synchronization overhead is a bit heavier than desired
(POSIX makes it difficult or impossible to implement open_memstream
without putting the memstream in the global open file list) but this
might be a small price to pay for the convenience and avoidance of the
major cons (like constantly having to check for errors, or worse,
built-in abort-on-fail) of other 'string library' solutions.
Rich