Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ 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/strdup.c \
Expand Down
13 changes: 13 additions & 0 deletions lib/string/strcpy/strncpytail.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#include "config.h"

#include "string/strcpy/strncpytail.h"

#include <stddef.h>


extern inline char *strncpytail(char *restrict dst, const char *restrict src,
size_t dsize);
36 changes: 36 additions & 0 deletions lib/string/strcpy/strncpytail.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <[email protected]>
// SPDX-License-Identifier: BSD-3-Clause


#ifndef SHADOW_INCLUDE_LIB_STRING_STRCPY_STRNCPYTAIL_H_
#define SHADOW_INCLUDE_LIB_STRING_STRCPY_STRNCPYTAIL_H_


#include "config.h"

#include <stddef.h>
#include <string.h>
#include <sys/param.h>

#include "attr.h"
#include "sizeof.h"
#include "string/strchr/strnul.h"


#define STRNCPYTAIL(dst, src) strncpytail(dst, src, countof(dst))


ATTR_STRING(2)
inline char *strncpytail(char *restrict dst, const char *restrict src,
size_t dsize);


// nonstring copy tail-of-string
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hallyn

I'm standing by this term. For the mnemonic comment explaining the name, nonstring is the most appropriate thing to use. You can think of strn as "string-non".

Copy link
Collaborator Author

@alejandro-colomar alejandro-colomar Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

We already have "fixed-width null-padded character array", which is what utmp(5) members are.

nonstring is a more generic thing, which englobes this and other creatures. But for this mnemonic use case, nonstring is easier to remember.

@Karlson2k Please do not respond here. I already know your opinion, and am not going to agree with it. Anyone interested in it, can read the lengthy thread above.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hallyn Please merge when you're happy with the name. Feel free to close all conversations, if you need that to be able to merge.

inline char *
strncpytail(char *restrict dst, const char *restrict src, size_t dsize)
{
return strncpy(dst, strnul(src) - MIN(strlen(src), dsize), dsize);
}


#endif // include guard
3 changes: 2 additions & 1 deletion lib/utmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "string/strcmp/strneq.h"
#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"
Expand Down Expand Up @@ -298,7 +299,7 @@ prepare_utmp(const char *name, const char *line, const char *host,
&& ('\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)));
STRNCPYTAIL(utent->ut_id, line);
}
#if defined(HAVE_STRUCT_UTMPX_UT_NAME)
STRNCPY(utent->ut_name, name);
Expand Down
Loading