Skip to content

Add strncpytail_a(), and use it instead of its pattern - #1304

Open
alejandro-colomar wants to merge 3 commits into
shadow-maint:masterfrom
alejandro-colomar:strncpytail
Open

Add strncpytail_a(), and use it instead of its pattern#1304
alejandro-colomar wants to merge 3 commits into
shadow-maint:masterfrom
alejandro-colomar:strncpytail

Conversation

@alejandro-colomar

@alejandro-colomar alejandro-colomar commented Jul 18, 2025

Copy link
Copy Markdown
Collaborator

Cc: @Karlson2k , @uecker


Revisions:

v1b
  • Rebase
$ git range-diff 17a3bb51df92^..gh/strncpytail shadow/master..strncpytail 
1:  17a3bb51 = 1:  52ed2fb5 lib/string/strcpy/: strncpytail(), STRNCPYTAIL(): Add APIs
2:  0747fecc = 2:  25ed13db lib/utmp.c: Use STRNCPYTAIL() instead of its pattern
v1c
  • Rebase
$ git rd 
1:  52ed2fb5 = 1:  a9207ca3 lib/string/strcpy/: strncpytail(), STRNCPYTAIL(): Add APIs
2:  25ed13db ! 2:  22ce0a47 lib/utmp.c: Use STRNCPYTAIL() instead of its pattern
    @@ lib/utmp.c
      #include "string/strdup/xstrdup.h"
      #include "string/strdup/xstrndup.h"
     @@ lib/utmp.c: prepare_utmp(const char *name, const char *line, const char *host,
    -   if (NULL != ut) {
    +       && ('\0' != ut->ut_id[0])) {
                STRNCPY(utent->ut_id, ut->ut_id);
        } else {
     -          STRNCPY(utent->ut_id, strnul(line) - MIN(strlen(line), countof(utent->ut_id)));
v1d
  • Rebase
$ git range-diff a9207ca3^..22ce0a47 5f7630f8^..6b0a0ac0
1:  a9207ca3 = 1:  5f7630f8 lib/string/strcpy/: strncpytail(), STRNCPYTAIL(): Add APIs
2:  22ce0a47 = 2:  6b0a0ac0 lib/utmp.c: Use STRNCPYTAIL() instead of its pattern
v1e
  • Rebase
$ git rd 
1:  5f7630f8 = 1:  4fc3f696 lib/string/strcpy/: strncpytail(), STRNCPYTAIL(): Add APIs
2:  6b0a0ac0 = 2:  df8b604d lib/utmp.c: Use STRNCPYTAIL() instead of its pattern
v1f
  • Rebase
$ git rd 
1:  4fc3f696 = 1:  163d8535 lib/string/strcpy/: strncpytail(), STRNCPYTAIL(): Add APIs
2:  df8b604d ! 2:  95ab3cb6 lib/utmp.c: Use STRNCPYTAIL() instead of its pattern
    @@ Commit message
     
      ## lib/utmp.c ##
     @@
    - #include "string/strcmp/streq.h"
    + #include "string/strcmp/strneq.h"
      #include "string/strcmp/strprefix.h"
      #include "string/strcpy/strncpy.h"
     +#include "string/strcpy/strncpytail.h"
v1g
  • Rebase
$ git rd 
1:  163d8535 ! 1:  4638da01 lib/string/strcpy/: strncpytail(), STRNCPYTAIL(): Add APIs
    @@ lib/Makefile.am: libshadow_la_SOURCES = \
     +  string/strcpy/strncpytail.h \
        string/strcpy/strtcpy.c \
        string/strcpy/strtcpy.h \
    -   string/strdup/strndupa.c \
    +   string/strdup/strdup.c \
     
      ## lib/string/strcpy/strncpytail.c (new) ##
     @@
2:  95ab3cb6 ! 2:  cd8af171 lib/utmp.c: Use STRNCPYTAIL() instead of its pattern
    @@ lib/utmp.c
      #include "string/strcpy/strncpy.h"
     +#include "string/strcpy/strncpytail.h"
      #include "string/strcpy/strtcpy.h"
    - #include "string/strdup/xstrdup.h"
    - #include "string/strdup/xstrndup.h"
    + #include "string/strdup/strdup.h"
    + #include "string/strdup/strndup.h"
     @@ lib/utmp.c: prepare_utmp(const char *name, const char *line, const char *host,
            && ('\0' != ut->ut_id[0])) {
                STRNCPY(utent->ut_id, ut->ut_id);
v2
  • Rename s/STRNCPYTAIL/strncpytail_a/.
  • Improve comments.
$ git rd 
1:  4638da014 ! 1:  f498a3873 lib/string/strcpy/: strncpytail(), STRNCPYTAIL(): Add APIs
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    lib/string/strcpy/: strncpytail(), STRNCPYTAIL(): Add APIs
    +    lib/string/strcpy/: strncpytail[_a](): Add APIs
     
         This works similar to strncpy(3), except that it truncates from the
         start of the string if the string doesn't fit.  It is useful for utmp(5)
    @@ lib/string/strcpy/strncpytail.h (new)
     +#include "string/strchr/strnul.h"
     +
     +
    -+#define STRNCPYTAIL(dst, src)  strncpytail(dst, src, countof(dst))
    ++// strncpytail_a - nonstring copy tail-of-string array
    ++#define strncpytail_a(dst, src)  strncpytail(dst, src, countof(dst))
     +
     +
     +ATTR_STRING(2)
    @@ lib/string/strcpy/strncpytail.h (new)
     +    size_t dsize);
     +
     +
    -+// nonstring copy tail-of-string
    ++// strncpytail - nonstring copy tail-of-string
     +inline char *
     +strncpytail(char *restrict dst, const char *restrict src, size_t dsize)
     +{
2:  cd8af171e ! 2:  36c4c50ef lib/utmp.c: Use STRNCPYTAIL() instead of its pattern
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    lib/utmp.c: Use STRNCPYTAIL() instead of its pattern
    +    lib/utmp.c: Use strncpytail_a() instead of its pattern
     
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
    @@ lib/utmp.c: prepare_utmp(const char *name, const char *line, const char *host,
                STRNCPY(utent->ut_id, ut->ut_id);
        } else {
     -          STRNCPY(utent->ut_id, strnul(line) - MIN(strlen(line), countof(utent->ut_id)));
    -+          STRNCPYTAIL(utent->ut_id, line);
    ++          strncpytail_a(utent->ut_id, line);
        }
      #if defined(HAVE_STRUCT_UTMPX_UT_NAME)
        STRNCPY(utent->ut_name, name);
v2b
  • Update lib/string/README.
$ git rd 
1:  f498a3873 ! 1:  593027522 lib/string/strcpy/: strncpytail[_a](): Add APIs
    @@ lib/Makefile.am: libshadow_la_SOURCES = \
        string/strcpy/strtcpy.h \
        string/strdup/strdup.c \
     
    + ## lib/string/README ##
    +@@ lib/string/README: strcpy/ - String copying
    +     strncpytail()
    +   Like strncpy(), but when truncating, the tail of the string is
    +   kept instead of the beginning.  This is useful for ut_id.
    +-    STRNCPYTAIL()
    ++    strncpytail_a()
    +   Like strncpytail, but takes an array.
    + 
    +     STRNCAT()  // To be removed
    +
      ## lib/string/strcpy/strncpytail.c (new) ##
     @@
     +// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
2:  36c4c50ef = 2:  982f944a5 lib/utmp.c: Use strncpytail_a() instead of its pattern
v2c
  • Rebase
$ git rd 
1:  593027522 = 1:  4404b232e lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  982f944a5 ! 2:  7d6800182 lib/utmp.c: Use strncpytail_a() instead of its pattern
    @@ lib/utmp.c
      #include "string/strcmp/strprefix.h"
      #include "string/strcpy/strncpy.h"
     +#include "string/strcpy/strncpytail.h"
    - #include "string/strcpy/strtcpy.h"
      #include "string/strdup/strdup.h"
      #include "string/strdup/strndup.h"
    + 
     @@ lib/utmp.c: prepare_utmp(const char *name, const char *line, const char *host,
            && ('\0' != ut->ut_id[0])) {
                STRNCPY(utent->ut_id, ut->ut_id);
v2d
  • Rebase
$ git rd 
1:  4404b232e = 1:  e2c0cd3d7 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  7d6800182 = 2:  e78027182 lib/utmp.c: Use strncpytail_a() instead of its pattern
v2e
  • Rebase
$ git rd 
1:  e2c0cd3d7 ! 1:  485973f1a lib/string/strcpy/: strncpytail[_a](): Add APIs
    @@ lib/string/README: strcpy/ - String copying
     +    strncpytail_a()
        Like strncpytail, but takes an array.
      
    -     STRNCAT()  // To be removed
    +     strncat_a()  // To be removed
     
      ## lib/string/strcpy/strncpytail.c (new) ##
     @@
2:  e78027182 ! 2:  4ffb5bc27 lib/utmp.c: Use strncpytail_a() instead of its pattern
    @@ lib/utmp.c
      
     @@ lib/utmp.c: prepare_utmp(const char *name, const char *line, const char *host,
            && ('\0' != ut->ut_id[0])) {
    -           STRNCPY(utent->ut_id, ut->ut_id);
    +           strncpy_a(utent->ut_id, ut->ut_id);
        } else {
    --          STRNCPY(utent->ut_id, strnul(line) - MIN(strlen(line), countof(utent->ut_id)));
    +-          strncpy_a(utent->ut_id, strnul(line) - MIN(strlen(line), countof(utent->ut_id)));
     +          strncpytail_a(utent->ut_id, line);
        }
      #if defined(HAVE_STRUCT_UTMPX_UT_NAME)
    -   STRNCPY(utent->ut_name, name);
    +   strncpy_a(utent->ut_name, name);
v2f
  • Rebase
$ git rd 
1:  485973f1a = 1:  0d001eb2b lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  4ffb5bc27 = 2:  5bccdef18 lib/utmp.c: Use strncpytail_a() instead of its pattern
v2g
  • Rebase
$ git rd 
1:  0d001eb2b = 1:  559ac55c6 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  5bccdef18 = 2:  cf1424804 lib/utmp.c: Use strncpytail_a() instead of its pattern
v2h
  • Rebase
$ git rd 
1:  559ac55c6 = 1:  5c06da618 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  cf1424804 = 2:  2f4793faa lib/utmp.c: Use strncpytail_a() instead of its pattern
v2i
  • Rebase
$ git rd 
1:  5c06da618 = 1:  63d4e4ac0 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  2f4793faa = 2:  22b11999a lib/utmp.c: Use strncpytail_a() instead of its pattern
v2j
  • Rebase
$ git rd 
1:  63d4e4ac0 = 1:  136b63d95 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  22b11999a = 2:  c33c3d5c0 lib/utmp.c: Use strncpytail_a() instead of its pattern
v3
  • Use strneq_a() instead of its pattern.
$ git range-diff shadow/master c33c3d5c0044 HEAD
1:  136b63d95 = 1:  136b63d95 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  c33c3d5c0 = 2:  c33c3d5c0 lib/utmp.c: Use strncpytail_a() instead of its pattern
-:  --------- > 3:  e950aa7b1 lib/utmp.c: Use strneq_a() instead of its pattern
v3b
  • Rebase
$ git rd 
1:  136b63d95 = 1:  f102f5586 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  c33c3d5c0 = 2:  dc7d35898 lib/utmp.c: Use strncpytail_a() instead of its pattern
3:  e950aa7b1 = 3:  6a97a418b lib/utmp.c: Use strneq_a() instead of its pattern
v3c
  • Rebase
$ git rd 
1:  f102f5586 = 1:  7163e0365 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  dc7d35898 = 2:  9d24cf8a3 lib/utmp.c: Use strncpytail_a() instead of its pattern
3:  6a97a418b = 3:  760f6b1db lib/utmp.c: Use strneq_a() instead of its pattern
v3d
  • Rebase
$ git rd 
1:  7163e0365637 ! 1:  5832c049d908 lib/string/strcpy/: strncpytail[_a](): Add APIs
    @@ lib/Makefile.am: libshadow_la_SOURCES = \
     +  string/strcpy/strncpytail.h \
        string/strcpy/strtcpy.c \
        string/strcpy/strtcpy.h \
    -   string/strdup/strdup.c \
    +   string/strdup/memdup.c \
     
      ## lib/string/README ##
     @@ lib/string/README: strcpy/ - String copying
2:  9d24cf8a3169 ! 2:  2473dffe0b85 lib/utmp.c: Use strncpytail_a() instead of its pattern
    @@ lib/utmp.c
      #include "string/strcmp/strprefix.h"
      #include "string/strcpy/strncpy.h"
     +#include "string/strcpy/strncpytail.h"
    + #include "string/strdup/memdup.h"
      #include "string/strdup/strdup.h"
      #include "string/strdup/strndup.h"
    - 
     @@ lib/utmp.c: prepare_utmp(const char *name, const char *line, const char *host,
            && ('\0' != ut->ut_id[0])) {
                strncpy_a(utent->ut_id, ut->ut_id);
3:  760f6b1db1b1 = 3:  500ff245cdd5 lib/utmp.c: Use strneq_a() instead of its pattern
v3e
  • Rebase
$ git rd 
1:  5832c049 = 1:  d4eb7969 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  2473dffe = 2:  1532dbcd lib/utmp.c: Use strncpytail_a() instead of its pattern
3:  500ff245 = 3:  0c7decf8 lib/utmp.c: Use strneq_a() instead of its pattern
v3f
  • Rebase
$ git rd
1:  d4eb7969 = 1:  4eab81f2 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  1532dbcd = 2:  d41c2740 lib/utmp.c: Use strncpytail_a() instead of its pattern
3:  0c7decf8 = 3:  2251bbd8 lib/utmp.c: Use strneq_a() instead of its pattern
v3g
  • Rebase
$ git rd 
1:  4eab81f25668 = 1:  7ebd8a18affd lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  d41c27406926 = 2:  b7bfe85054ad lib/utmp.c: Use strncpytail_a() instead of its pattern
3:  2251bbd8cc49 = 3:  9eaf0ae3955c lib/utmp.c: Use strneq_a() instead of its pattern
v3h
  • Rebase
$ git rd 
 1:  3af81f598574 =  1:  1781d0d7fa72 lib/logind.c: Fix style
 2:  8d5bb01d3e0c =  2:  d8fa47da16b5 lib/logind.c: Remove dead initializations
 3:  1aaa11a73d84 !  3:  d0552ddd4958 lib/: Move utmp.c and logind.c prototypes to new "session_management.h" header
    @@ lib/utmp.c
     
      ## src/login.c ##
     @@
    - #include "getdef.h"
    + #include "io/fprintf.h"
      #include "prototypes.h"
      #include "pwauth.h"
     +#include "session_management.h"
 4:  8507b3d84fd5 =  4:  2aef494855a1 lib/logind.c: get_session_host(): free() earlier, to avoid a goto
 5:  cdfb40d1847b =  5:  dbaff831cc43 lib/logind.c: Wrap libsystemd function in our wrapper get_session()
 6:  b6e7134e97b8 =  6:  41dc548502b5 lib/logind.c: Wrap libsystemd function in our wrapper session_get_remote_host()
 7:  4a0633c9869a =  7:  2c698463cbec configure.ac, lib/utmp.c: Assume utmpx(5) has ut_host
 8:  481b6acecd22 =  8:  aff3bcd25b67 lib/, src/: get_session_host(): Return the host
 9:  7868607ef562 =  9:  def7dafe282b lib/utmp.c: get_session_host(): Don't exit from library code
v3i
  • Rebase
$ git rd 
1:  7ebd8a18affd = 1:  04a0d5f4b814 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  b7bfe85054ad = 2:  82bed05771c2 lib/utmp.c: Use strncpytail_a() instead of its pattern
3:  9eaf0ae3955c = 3:  f329bd7a9288 lib/utmp.c: Use strneq_a() instead of its pattern
v3j
  • Rebase
$ git rd 
1:  04a0d5f4b814 = 1:  d8876fa89605 lib/string/strcpy/: strncpytail[_a](): Add APIs
2:  82bed05771c2 = 2:  140f3b837e60 lib/utmp.c: Use strncpytail_a() instead of its pattern
3:  f329bd7a9288 = 3:  11dc1b2f8b1c lib/utmp.c: Use strneq_a() instead of its pattern
v4
  • Include <memory.h> for strncpy(3).
$ git rd 
1:  d8876fa89605 ! 1:  a4820c9a2095 lib/string/strcpy/: strncpytail[_a](): Add APIs
    @@ lib/string/strcpy/strncpytail.h (new)
     +
     +#include "config.h"
     +
    ++#include <memory.h>
     +#include <stddef.h>
     +#include <string.h>
     +#include <sys/param.h>
2:  140f3b837e60 = 2:  55e24c70b935 lib/utmp.c: Use strncpytail_a() instead of its pattern
3:  11dc1b2f8b1c = 3:  7ed78c5da107 lib/utmp.c: Use strneq_a() instead of its pattern
v5
  • Move API to a new lib/memory/. [@ikerexxe ]
$ git rd --creation-factor=99
1:  a4820c9a2095 ! 1:  32b835a4bcdc lib/string/strcpy/: strncpytail[_a](): Add APIs
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    lib/string/strcpy/: strncpytail[_a](): Add APIs
    +    lib/memory/memcpy/: strncpytail[_a](): Add APIs
     
         This works similar to strncpy(3), except that it truncates from the
         start of the string if the string doesn't fit.  It is useful for utmp(5)
    @@ Commit message
     
      ## lib/Makefile.am ##
     @@ lib/Makefile.am: libshadow_la_SOURCES = \
    -   string/strcpy/strncat.h \
    -   string/strcpy/strncpy.c \
    -   string/strcpy/strncpy.h \
    -+  string/strcpy/strncpytail.c \
    -+  string/strcpy/strncpytail.h \
    -   string/strcpy/strtcpy.c \
    -   string/strcpy/strtcpy.h \
    -   string/strdup/memdup.c \
    +   lockpw.c \
    +   loginprompt.c \
    +   mail.c \
    ++  memory/memcpy/strncpytail.c \
    ++  memory/memcpy/strncpytail.h \
    +   motd.c \
    +   myname.c \
    +   nss.c \
     
    - ## lib/string/README ##
    -@@ lib/string/README: strcpy/ - String copying
    -     strncpytail()
    -   Like strncpy(), but when truncating, the tail of the string is
    -   kept instead of the beginning.  This is useful for ut_id.
    --    STRNCPYTAIL()
    -+    strncpytail_a()
    -   Like strncpytail, but takes an array.
    - 
    -     strncat_a()  // To be removed
    -
    - ## lib/string/strcpy/strncpytail.c (new) ##
    + ## lib/memory/memcpy/strncpytail.c (new) ##
     @@
    -+// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
    ++// SPDX-FileCopyrightText: 2025-2026, Alejandro Colomar <alx@kernel.org>
     +// SPDX-License-Identifier: BSD-3-Clause
     +
     +
     +#include "config.h"
     +
    -+#include "string/strcpy/strncpytail.h"
    ++#include "memory/memcpy/strncpytail.h"
     +
     +#include <stddef.h>
     +
    @@ lib/string/strcpy/strncpytail.c (new)
     +extern inline char *strncpytail(char *restrict dst, const char *restrict src,
     +    size_t dsize);
     
    - ## lib/string/strcpy/strncpytail.h (new) ##
    + ## lib/memory/memcpy/strncpytail.h (new) ##
     @@
    -+// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
    ++// SPDX-FileCopyrightText: 2025-2026, Alejandro Colomar <alx@kernel.org>
     +// SPDX-License-Identifier: BSD-3-Clause
     +
     +
    -+#ifndef SHADOW_INCLUDE_LIB_STRING_STRCPY_STRNCPYTAIL_H_
    -+#define SHADOW_INCLUDE_LIB_STRING_STRCPY_STRNCPYTAIL_H_
    ++#ifndef SHADOW_INCLUDE_LIB_MEMORY_MEMCPY_STRNCPYTAIL_H_
    ++#define SHADOW_INCLUDE_LIB_MEMORY_MEMCPY_STRNCPYTAIL_H_
     +
     +
     +#include "config.h"
    @@ lib/string/strcpy/strncpytail.h (new)
     +
     +
     +#endif  // include guard
    +
    + ## lib/string/README ##
    +@@ lib/string/README: strcpy/ - String copying
    +     strncpytail()
    +   Like strncpy(), but when truncating, the tail of the string is
    +   kept instead of the beginning.  This is useful for ut_id.
    +-    STRNCPYTAIL()
    ++    strncpytail_a()
    +   Like strncpytail, but takes an array.
    + 
    +     strncat_a()  // To be removed
2:  55e24c70b935 ! 2:  75f21c72ec08 lib/utmp.c: Use strncpytail_a() instead of its pattern
    @@ Commit message
     
      ## lib/utmp.c ##
     @@
    - #include "string/strcmp/strneq.h"
    - #include "string/strcmp/strprefix.h"
    - #include "string/strcpy/strncpy.h"
    -+#include "string/strcpy/strncpytail.h"
    - #include "string/strdup/memdup.h"
    - #include "string/strdup/strdup.h"
    - #include "string/strdup/strndup.h"
    + #include "alloc/malloc.h"
    + #include "attr.h"
    + #include "io/syslog.h"
    ++#include "memory/memcpy/strncpytail.h"
    + #include "sizeof.h"
    + #include "string/strchr/strnul.h"
    + #include "string/strcmp/streq.h"
     @@ lib/utmp.c: prepare_utmp(const char *name, const char *line, const char *host,
            && ('\0' != ut->ut_id[0])) {
                strncpy_a(utent->ut_id, ut->ut_id);
3:  7ed78c5da107 = 3:  b95da0678ae4 lib/utmp.c: Use strneq_a() instead of its pattern

@alejandro-colomar
alejandro-colomar force-pushed the strncpytail branch 2 times, most recently from 9acb3e0 to 0747fec Compare July 18, 2025 13:31
@Karlson2k

Copy link
Copy Markdown
Contributor

Nice.
Improves code readability.

@Karlson2k

Karlson2k commented Jul 18, 2025

Copy link
Copy Markdown
Contributor

For the records.
The next code could be faster:

inline char *
strncpytail(char *restrict dst, const char *restrict src, size_t dsize)
{
  size_t src_len;
  src_len = strlen(src);

  if (dsize > src_len)
    return memcpy (dst, src, src_len + 1);

  return memcpy (dst, src + (src_len - dsize), dsize);
}

Large strings / buffers can be processed much faster.

But if performance is not an issue, the code in the PR will work fine.

Note: the binary is still a few bytes larger.

@alejandro-colomar

Copy link
Copy Markdown
Collaborator Author

For the records. The next code could be faster:

inline char *
strncpytail(char *restrict dst, const char *restrict src, size_t dsize)
{
  size_t src_len;
  src_len = strlen(src);

  if (dsize > src_len)
    return memcpy (dst, src, src_len + 1);

  return memcpy (dst, src + (src_len - dsize), dsize);
}

Large strings / buffers can be processed much faster.

But if performance is not an issue, the code in the PR will work fine.

Note: the binary is still a few bytes larger.

Indeed, since this API is designed for short strings (ut_id), I'll optimize for readability for now.

@alejandro-colomar alejandro-colomar added the Simpler A good issue for a new beginner label Jul 20, 2025
Comment thread lib/string/strcpy/strncpytail.h Outdated
@alejandro-colomar

Copy link
Copy Markdown
Collaborator Author

@hallyn The term nonstring comes from https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute. (To avoid you having to read the lengthy discussion in the other thread.)

@hallyn

hallyn commented Aug 11, 2025

Copy link
Copy Markdown
Member

@hallyn The term nonstring comes from https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute. (To avoid you having to read the lengthy discussion in the other thread.)

Thanks

@Karlson2k

This comment was marked as off-topic.

@hallyn

hallyn commented Aug 12, 2025

Copy link
Copy Markdown
Member

@hallyn The term nonstring comes from https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute. (To avoid you having to read the lengthy discussion in the other thread.)

Also need to mention that GCC means by this term "do not use strlen() and other string-based function because the data MAY be not NUL-terminated or could be binary data", but here, in this project, it means different: "it is a text data in fixed size buffer/array, which terminates at the end of the array without NUL-termination or terminated early by first NUL".

Hm, do we need to define a new term?

@Karlson2k

Karlson2k commented Aug 12, 2025

Copy link
Copy Markdown
Contributor

@hallyn The term nonstring comes from https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute. (To avoid you having to read the lengthy discussion in the other thread.)

Also need to mention that GCC means by this term "do not use strlen() and other string-based function because the data MAY be not NUL-terminated or could be binary data", but here, in this project, it means different: "it is a text data in fixed size buffer/array, which terminates at the end of the array without NUL-termination or terminated early by first NUL".

Hm, do we need to define a new term?

Probably.
@alejandro-colomar insisting that it is perfectly described by "fixed size array with zero-padded data". It also assumed that zero-padding must not be checked and data reading must be stopped at the first zero. Also assumed that the data cannot have zeros because zero is used for padding.
I'm trying to convince Alejandro that what is described is not zero-padding, but is just optional early zero-termination.

I any case, I think both terms "non-string" and "zero-padded array" are confusing and not fully describe this kind of entities.

@Karlson2k

This comment was marked as off-topic.

@alejandro-colomar

Copy link
Copy Markdown
Collaborator Author

Please, do not continue the discussion unthreaded. That makes it impossible to follow the page. If you want to have a lengthy discussion, open a comment on any line of code, which can be hidden easily.

Comment thread lib/string/strcpy/strncpytail.h Outdated
Comment thread lib/memory/memcpy/strncpytail.h
@alejandro-colomar
alejandro-colomar force-pushed the strncpytail branch 2 times, most recently from cd8af17 to 36c4c50 Compare October 31, 2025 09:23
@alejandro-colomar alejandro-colomar changed the title Add STRNCPYTAIL(), and use it instead of its pattern Add strncpytail_a(), and use it instead of its pattern Oct 31, 2025
@alejandro-colomar
alejandro-colomar force-pushed the strncpytail branch 2 times, most recently from 982f944 to 7d68001 Compare November 4, 2025 12:05
@Karlson2k

Copy link
Copy Markdown
Contributor

Besides used terms, the code is OK.

@alejandro-colomar

Copy link
Copy Markdown
Collaborator Author

Besides used terms, the code is OK.

Thanks!

@alejandro-colomar

Copy link
Copy Markdown
Collaborator Author

Cc: @kees

This works similar to strncpy(3), except that it truncates from the
start of the string if the string doesn't fit.  It is useful for utmp(5)
ut_id, where the tail of the string is more useful and distinctive.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New API Simpler A good issue for a new beginner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants