Re: strncpy clarify result may not be null terminated

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

 



On 2023-11-10 11:52, Alejandro Colomar wrote:

Do you have any numbers?

It depends on size of course. With programs like 'tar' (one of the few programs that actually needs something like strncpy) the destination buffer is usually fairly small (32 bytes or less) though some of them are 100 bytes. I used 16 bytes in the following shell transcript:

$ for i in strnlen+strcpy strnlen+memcpy strncpy stpncpy strlcpy; do echo; echo $i:; time ./a.out 16 100000000 abcdefghijk $i; done

strnlen+strcpy:

real	0m0.411s
user	0m0.411s
sys	0m0.000s

strnlen+memcpy:

real	0m0.392s
user	0m0.388s
sys	0m0.004s

strncpy:

real	0m0.300s
user	0m0.300s
sys	0m0.000s

stpncpy:

real	0m0.326s
user	0m0.326s
sys	0m0.000s

strlcpy:

real	0m0.623s
user	0m0.623s
sys	0m0.000s


... where a.out was generated by compiling the attached program with gcc -O2 on Ubuntu 23.10 64-bit on a Xeon W-1350.

I wouldn't take these numbers all that seriously, as microbenchmarks like these are not that informative these days. Still, for a typical case one should not assume strncpy must be slower merely because it has more work to do; quite the contrary.
#include <stdlib.h>
#include <string.h>


int
main (int argc, char **argv)
{
  if (argc != 5)
    return 2;
  long bufsize = atol (argv[1]);
  char *buf = malloc (bufsize);
  long n = atol (argv[2]);
  char const *a = argv[3];
  if (strcmp (argv[4], "strnlen+strcpy") == 0)
    {
      for (long i = 0; i < n; i++)
	{
	  if (strnlen (a, bufsize) == bufsize)
	    return 1;
	  strcpy (buf, a);
	}
    }
  else if (strcmp (argv[4], "strnlen+memcpy") == 0)
    {
      for (long i = 0; i < n; i++)
	{
	  size_t alen = strnlen (a, bufsize);
	  if (alen == bufsize)
	    return 1;
	  memcpy (buf, a, alen + 1);
	}
    }
  else if (strcmp (argv[4], "strncpy") == 0)
    {
      for (long i = 0; i < n; i++)
	if (strncpy (buf, a, bufsize)[bufsize - 1])
	  return 1;
    }
  else if (strcmp (argv[4], "stpncpy") == 0)
    {
      for (long i = 0; i < n; i++)
	if (stpncpy (buf, a, bufsize) == buf + bufsize)
	  return 1;
    }
  else if (strcmp (argv[4], "strlcpy") == 0)
    {
      for (long i = 0; i < n; i++)
	if (strlcpy (buf, a, bufsize) == bufsize)
	  return 1;
    }
  else
    return 2;
}

[Index of Archives]     [Kernel Documentation]     [Netdev]     [Linux Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux