Compound literals also have the ability of converting values, but they
don't have the unwanted effects on safety --casts disable most useful
diagnostics--.
Compound literals are lvalues, which means their address can be taken,
and they can also be assigned to. To avoid this, we force lvalue
conversion through a statement expression.
Iker Pedrosa [Tue, 19 Aug 2025 09:26:18 +0000 (11:26 +0200)]
tests/system/tests/test_groupmems.py: add user to group as root user
This is the transformation to Python of the test located in
`tests/grouptools/groupmems/01_groupmems_root_add_user/groupmems.test`,
which checks that `groupmems` is able to add a user to a group running
as the root user.
Iker Pedrosa [Fri, 8 Aug 2025 15:08:20 +0000 (17:08 +0200)]
tests/system/tests/test_newusers.py: create multiple users using file input
This is the transformation to Python of the test located in
`tests/newusers/20_multiple_users/newusers.test`, which checks that
`newusers` is able to create new users from file.
Iker Pedrosa [Fri, 8 Aug 2025 15:05:42 +0000 (17:05 +0200)]
tests/system/tests/test_newusers.py: create multiple users from stdin
This is the transformation to Python of the test located in
`tests/newusers/35_read_from_stdin/newusers.test`, which checks that
`newusers` is able to create new users from stdin.
[Serge: preference to keep the names as a comment, but ok] Reviewed-by: Serge Hallyn <serge@hallyn.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/, src/ tests/: Unname unused parameters in callbacks
[Serge: preference to keep the names as a comment, but ok] Reviewed-by: Serge Hallyn <serge@hallyn.com> Signed-off-by: Alejandro Colomar <alx@kernel.org>
Antonio Terceiro [Sun, 24 Aug 2025 13:59:07 +0000 (10:59 -0300)]
newusers: allow not passing a password
A possible use case for this is wanting to add subuid/subgid entries for
an existing user. This change makes it possible to pass `username::::::`
to newusers; the empty password will be ignored an everything else will
be done. Currently this fails miserably, as PAM errors out on a empty
password.
Signed-off-by: Antonio Terceiro <terceiro@debian.org>
This macro is like typeof(), but requires that the input is a type name.
This macro is useful because it parenthesizes the type name, which
allows one to create pointers to arbitrary types. The following code
works for simple types:
T x;
T *p;
For example, that would work fine for 'int':
int x;
int *p;
However, that wouldn't work for types such as 'int[3]':
int[3] x;
int[3] *p;
But if we do instead
typeas(T) x;
typeas(T) *p;
now we can use 'int[3]' just fine:
typeof((int[3]){}) x;
typeof((int[3]){}) *p;
To understand this, we create a compound literal of type int[3], with
default values (zero, zero, zero), then get it's type, which is
obviously int[3]. And then we use that to declare a variable x of that
type, and a pointer p, which has type 'int(*)[3]'.
This would also work with something simpler. One could use typeof(T)
directly:
typeof(T) x;
typeof(T) *p;
However, typeof() doesn't require that the input is a type; it accepts
arbitrary input. The following is valid C:
typeof(42) x;
For our macro MALLOC(), where we want the second argument to be a type
name, we want to require that the argument is a type name. For that, we
need to use typeas().
src/: Fix uninitialized flags, and use const appropriately
In all these functions, we were setting the flags to 'true' in
process_flags() if the appropriate command-line flag was specified.
However, they were never being defined to 'false', which should be the
default value. Initialize these flags to false.
Initialize option_flags structure to prevent garbage memory values in
`flags.chroot` and `flags.prefix` fields. Uninitialized memory caused
architecture-specific failures where process_selinux evaluation
differed between x86_64 and aarch64, leading to `pw_close()` failures
when SELinux contexts weren't properly managed.
src/usermod.c: $user_newhome: Remove all trailing '/'s
FTR: I'm not entirely sure if an empty string can arrive here. It might
be that the streq() check is dead code, but I'm not sure, so I put it.
It also makes the code more robust.
configure.ac, Makefile.am: Propagate ./configure flags to 'distcheck'
'make distcheck' runs ./configure (among other things). That command
should inherit the flags passed on the command line, as they are the
flags necessary to build in the current system.
This also allows testing different configurations in the same system.
Until now, we only tested the default automagic configuration. With
this change, one can test the same default automagic configuration, by
not passing any flags to ./configure, or they can test more specific
configurations, by passing flags.
This allows removing the hardcoded AM_DISTCHECK_CONFIGURE_FLAGS in the
"Makefile.am".
memcpy(3) is overkill, and much more dangerous than simple assignment.
Simple assignment adds type safety, and removes any possibility of
buffer overflow due to accidentally specifying a wrong size.
tests/unit/test_xaprintf.c: Use assert_string_equal()
This produces more useful test results.
With assert_true(streq(...)), we only see the line of code that
triggered the failure, while assert_string_equal() shows the contents
of the strings. See the following example:
The differences between the actual patch and the approximation via the
semantic patch from above are includes, whitespace, braces, and a case
where there was an implicit pointer-to-bool comparison which I made
explicit. When reviewing, it'll be useful to use git-diff(1) with '-w'
and '--color-words=.'.
The differences between the actual patch and the approximation via the
semantic patch from above are whitespace only. When reviewing, it'll
be useful to diff with '-w'.
Iker Pedrosa [Tue, 26 Aug 2025 08:48:15 +0000 (10:48 +0200)]
doc/contributions/tests.md: add Python system tests
Document the new Python system tests:
- Benefits
- Contribution guidance
- How to setup the testing environment
- Test configuration and execution
- Advanced testing features
- Development patterns
- Debugging information
- Troubleshooting & FAQs
This name better reflects that it handles arrays, and doesn't shout.
This case is slightly different, as this macro does a little bit more
than just enforcing arrays. It changes the return value too. However,
that is related-enough to the handling of arrays that I'm inclined to
accept it as a minor inconsistency.
lib/atoi/: a2i(): Re-implement with a statement expression
Synopsis
int a2i(typename T, T *restrict n, QChar *s,
QChar **_Nullable restrict endp, int base,
T min, T max);
Description
This macro converts the initial portion of the string pointed to
by 's' to an integer of base 'base', ensure that the number is
in the range [min, max], and store it in *n.
It is similar to NetBSD's strtoi(3) and strtou(3), which
themselves are similar to strtol(3) and strtoul(3).
Arguments
T
The integer type used for the number.
n
A pointer to an integer. The parsed number will be
stored there.
s
See strtol(3).
endp
See strtol(3). A difference with strtol(3) is that this
macro is const-correct. If 's' has type 'const char *',
then 'endp' must have type 'const char **', whereas if
's' has type 'char *', 'endp' must have type 'char **'.
base
See strtol(3).
min
max
See strtoi(3) and strtou(3).
An important difference with NetBSD's strtou(3) is that
a2i() (with an unsigned type T) doesn't intepret any
negative numbers as if they were large positive numbers.
a2i() respects the limits [min, max] as one would
intuitively expect.
Return value
On success, 0 is returned.
On error, -1 is returned and errno is set to indicate the error.
sgakerru [Tue, 11 Nov 2025 20:22:06 +0000 (00:22 +0400)]
useradd: fix test `69_useradd_default_GROUPS_name`
Missing files have been added for the test to work: `gshadow`, `passwd`, `shadow`.
Without them, the foo user was created with a different UID and thus the test failed.
And other minor improvements, such as removing extra spaces and adding empty lines.
tests/unit/test_exit_if_null.c: Test through XMALLOC() instead of xaprintf()
Both are indirect tests for exit_if_null(), but through XMALLOC() we
can test it more robustly, as we don't need to wrap vasprintf(3) to
make it fail. It's trivial to make MALLOC(3) fail: pass a huge size.
The tests with xaprintf() were failing on Nix. I suspect the compiler
was inlining aggressively, and as a result, the interposition of
vasprintf(3) in cmocka wasn't actually working. The approach with
XMALLOC() seems to work on Nix, as we don't need to interpose malloc(3).
We still need to interpose exit(3), but for some reason that works fine.