bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: alternatives to 'strlcpy'


From: Bruno Haible
Subject: Re: alternatives to 'strlcpy'
Date: Thu, 28 Sep 2017 20:39:23 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-93-generic; KDE/5.18.0; x86_64; ; )

Paul Eggert wrote:
> If you really want a function whose semantics are like strlcpy's but has 
> __warn_unused_result__ semantics ..., then I suppose we could 
> invent one and use it for Gnulib. But we should not call it strlcpy

Yes, I do want such a function for copying a string to a bounded memory area.

What you don't like about strlcpy:
  - The name.
  - The return value: why compute strlen(src) when the function does not
    otherwise need it?

The reason for this design is that in BSD, it is common practice to try
a call with a fixed-size stack-allocated or statically allocated buffer,
and try dynamic memory only when this first attempt fails. The return value
is thus useful for the second step. For system calls this is a reasonable
design, but not here: the caller can call strlen(src) by himself. It is
strange design to do the first part of the second step in the function
which is supposed to do the first step. My take on this is that such
an algorithm should be abstracted in a facility of its own, like
<scratch-buffer.h> or <linebuffer.h>.

Other things I don't like about strlcpy:
  - It's hard to remember whether the return value should be tested
    as >= dstsize, > dstsize, <= dstsize, < dstsize. As Jim writes [1]
    "Some of us forget to read documentation. Or read it, and then forget
     details."
  - The argument order: while snprintf, strftime, strfmon, and others
    receive the destination buffer size immediately following the
    destination buffer address, strlcpy wants it as third argument.
    Which is against the principle "keep together what belongs together".

Dmitry suggested to look at strscpy [2]. About this one I don't like
  - The return value convention: It's suitable for in-kernel APIs only.
  - The mixed use of ssize_t vs. size_t.
  - The argument order.

Here's my take:

/* Copies the string SRC, possibly truncated, into the bounded memory area
   [DST,...,DST+DSTSIZE-1].
   If the result fits, it returns 0.
   If DSTSIZE is 0, it returns -1 and sets errno to EINVAL.
   If DSTSIZE is nonzero and the result does not fit, it produces a NUL-
   terminated truncated result, and returns -1 and sets errno to E2BIG.  */
extern int strgcpy (char *__dst, size_t __dstsize, const char *__src)
  __attribute__ ((__nonnull__ (1, 3)))
  __attribute__ ((__warn_unused_result__));

Bruno

[1] https://meyering.net/crusade-to-eliminate-strncpy/
[2] https://www.kernel.org/doc/htmldocs/kernel-api/API-strscpy.html




reply via email to

[Prev in Thread] Current Thread [Next in Thread]