]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
tests: add helper program and test for lib/pidutils.c
authorChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Tue, 7 Apr 2026 17:33:39 +0000 (13:33 -0400)
committerChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Wed, 8 Apr 2026 13:44:26 +0000 (09:44 -0400)
Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
13 files changed:
lib/Makemodule.am
lib/pidutils.c
meson.build
tests/commands.sh
tests/expected/lib/pidutils-flag-negative [new file with mode: 0644]
tests/expected/lib/pidutils-flag-negative.err [new file with mode: 0644]
tests/expected/lib/pidutils-flag-unset [new file with mode: 0644]
tests/expected/lib/pidutils-flag-unset.err [new file with mode: 0644]
tests/expected/lib/pidutils-flag-zero [new file with mode: 0644]
tests/expected/lib/pidutils-flag-zero-negative [new file with mode: 0644]
tests/expected/lib/pidutils-flag-zero-negative.err [new file with mode: 0644]
tests/expected/lib/pidutils-flag-zero.err [new file with mode: 0644]
tests/ts/lib/pidutils [new file with mode: 0755]

index 7626e76798d0e13ac202ee80469ca5d0c4ca57f5..4fbe602a242aac238aaafc56d9971870a44c9df7 100644 (file)
@@ -104,7 +104,8 @@ check_PROGRAMS += \
        test_ttyutils \
        test_timeutils \
        test_c_strtod \
-       test_logindefs
+       test_logindefs \
+       test_parsepid
 
 
 if LINUX
@@ -161,6 +162,10 @@ test_colors_LDADD = $(LDADD) libtcolors.la
 test_randutils_SOURCES = lib/randutils.c
 test_randutils_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_RANDUTILS
 
+test_parsepid_SOURCES = lib/pidutils.c
+test_parsepid_CFLAGS = $(AM_CFLAGS) -DTEST_PROGRAM_PARSEPID
+test_parsepid_LDADD = $(LDADD) libcommon.la
+
 if HAVE_OPENAT
 if HAVE_DIRFD
 test_path_SOURCES = lib/path.c lib/fileutils.c
index ea4156cfa9dd29e232af7ae3603616d37040afd6..f725f1292270bbe3ec7ea95d9a12bf7dba7f23cb 100644 (file)
@@ -88,3 +88,64 @@ void ul_parse_pid_str_or_err(char *pidstr, pid_t *pid_num, uint64_t *pfd_ino, in
                err(EXIT_FAILURE, N_("failed to parse PID argument '%s'"), pidstr);
        }
 }
+
+
+#ifdef TEST_PROGRAM_PARSEPID
+
+#include <getopt.h>
+
+static void __attribute__((__noreturn__)) usage(void)
+{
+       fprintf(stdout, " %s [options] <pidstr>\n\n", program_invocation_short_name);
+       fputs(" -z, --zero         allow zero (0) as value for <pidstr>\n", stdout);
+       fputs(" -n, --negative     allow negative number as value for <pidstr>\n", stdout);
+
+       exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv)
+{
+       int c, flags = 0, rc = 0;
+       uint64_t pidfd_ino = 0;
+       pid_t pid_num = 0;
+       char *str = NULL;
+
+       static const struct option longopts[] = {
+               { "zero",       0, NULL, 'z' },
+               { "negative",   0, NULL, 'n' },
+               { "help",       0, NULL, 'h' },
+               { NULL, 0, NULL, 0 },
+       };
+
+       while((c = getopt_long(argc, argv, "nhz", longopts, NULL)) != -1) {
+               switch(c) {
+               case 'n':
+                       flags |= UL_PID_NEGATIVE;
+                       break;
+               case 'z':
+                       flags |= UL_PID_ZERO;
+                       break;
+               case 'h':
+                       usage();
+                       break;
+               default:
+                       err(EXIT_FAILURE, "try --help");
+               }
+       }
+
+       if (optind == argc)
+               errx(EXIT_FAILURE, "missing <pidstr> argument");
+       str = argv[optind];
+
+       rc = ul_parse_pid_str(str, &pid_num, &pidfd_ino, flags);
+       if (rc)
+               err(EXIT_FAILURE, "failed to parse PID '%s'", str);
+
+       printf("PID: %d\n", pid_num);
+       if (pidfd_ino)
+               printf("inode: %"PRIu64"\n", pidfd_ino);
+
+       return EXIT_SUCCESS;
+}
+
+#endif /* TEST_PROGRAM_PARSE_PID */
index 88c6bdf5f6f64f9bb4421db0358c8612e3e91d52..f5b0ba7c17070d7461f72cfd7fc15b19f83f4cd1 100644 (file)
@@ -3551,6 +3551,17 @@ if not is_disabler(exe)
   exes += exe
 endif
 
+exe = executable(
+  'test_parsepid',
+  'lib/pidutils.c',
+  c_args : ['-DTEST_PROGRAM_PARSEPID'],
+  include_directories : dir_include,
+  link_with : lib_common,
+  build_by_default: program_tests)
+if not is_disabler(exe)
+  exes += exe
+endif
+
 if conf.get('HAVE_OPENAT').to_string() == '1' \
    and conf.get('HAVE_DIRFD').to_string() == '1'
   exe = executable(
index 32e343bf9af959faad79b8a5e2147c69b91923e3..e68d0b3e363d2d1bdc46fc621537509f5e7ff7a6 100644 (file)
@@ -68,6 +68,7 @@ TS_HELPER_TIMEUTILS="${ts_helpersdir}test_timeutils"
 TS_HELPER_KILL_PIDFDINO="${ts_helpersdir}test_kill_pidfdino"
 TS_HELPER_SCOLS_TERMREDUCE="${ts_helpersdir}test_scols_termreduce"
 TS_HELPER_OPEN_TWICE="${ts_helpersdir}test_open_twice"
+TS_HELPER_PARSEPID="${ts_helpersdir}test_parsepid"
 
 # paths to commands
 TS_CMD_ADDPART=${TS_CMD_ADDPART:-"${ts_commandsdir}addpart"}
diff --git a/tests/expected/lib/pidutils-flag-negative b/tests/expected/lib/pidutils-flag-negative
new file mode 100644 (file)
index 0000000..d843f9a
--- /dev/null
@@ -0,0 +1,5 @@
+PID: 1
+PID: 1
+inode: 122
+PID: -2147
+PID: 2147
diff --git a/tests/expected/lib/pidutils-flag-negative.err b/tests/expected/lib/pidutils-flag-negative.err
new file mode 100644 (file)
index 0000000..139fbdf
--- /dev/null
@@ -0,0 +1,7 @@
+test_parsepid: failed to parse PID '1:': EINVAL
+test_parsepid: failed to parse PID '-1:0': EINVAL
+test_parsepid: failed to parse PID '1:-122': ERANGE
+test_parsepid: failed to parse PID '1:0': ERANGE
+test_parsepid: failed to parse PID '-1:122': EINVAL
+test_parsepid: failed to parse PID '-2147:78': EINVAL
+test_parsepid: failed to parse PID '0': ERANGE
diff --git a/tests/expected/lib/pidutils-flag-unset b/tests/expected/lib/pidutils-flag-unset
new file mode 100644 (file)
index 0000000..cf3b089
--- /dev/null
@@ -0,0 +1,4 @@
+PID: 1
+PID: 1
+inode: 122
+PID: 2147
diff --git a/tests/expected/lib/pidutils-flag-unset.err b/tests/expected/lib/pidutils-flag-unset.err
new file mode 100644 (file)
index 0000000..39e8795
--- /dev/null
@@ -0,0 +1,6 @@
+test_parsepid: failed to parse PID '1:': EINVAL
+test_parsepid: failed to parse PID '1:0': ERANGE
+test_parsepid: failed to parse PID '-1:122': ERANGE
+test_parsepid: failed to parse PID '-2147': ERANGE
+test_parsepid: failed to parse PID '1:-122': ERANGE
+test_parsepid: failed to parse PID '0': ERANGE
diff --git a/tests/expected/lib/pidutils-flag-zero b/tests/expected/lib/pidutils-flag-zero
new file mode 100644 (file)
index 0000000..5845d8b
--- /dev/null
@@ -0,0 +1,5 @@
+PID: 1
+PID: 1
+inode: 122
+PID: 2147
+PID: 0
diff --git a/tests/expected/lib/pidutils-flag-zero-negative b/tests/expected/lib/pidutils-flag-zero-negative
new file mode 100644 (file)
index 0000000..0f447db
--- /dev/null
@@ -0,0 +1,7 @@
+PID: 1
+PID: -1443
+PID: 1
+inode: 122
+PID: -2147
+PID: 2147
+PID: 0
diff --git a/tests/expected/lib/pidutils-flag-zero-negative.err b/tests/expected/lib/pidutils-flag-zero-negative.err
new file mode 100644 (file)
index 0000000..8c508c9
--- /dev/null
@@ -0,0 +1,4 @@
+test_parsepid: failed to parse PID '1:': EINVAL
+test_parsepid: failed to parse PID '1:0': ERANGE
+test_parsepid: failed to parse PID '1:-122': ERANGE
+test_parsepid: failed to parse PID '-1:122': EINVAL
diff --git a/tests/expected/lib/pidutils-flag-zero.err b/tests/expected/lib/pidutils-flag-zero.err
new file mode 100644 (file)
index 0000000..7d4bcd7
--- /dev/null
@@ -0,0 +1,5 @@
+test_parsepid: failed to parse PID '1:': EINVAL
+test_parsepid: failed to parse PID '1:0': ERANGE
+test_parsepid: failed to parse PID '-1:122': ERANGE
+test_parsepid: failed to parse PID '-2147': ERANGE
+test_parsepid: failed to parse PID '1:-122': ERANGE
diff --git a/tests/ts/lib/pidutils b/tests/ts/lib/pidutils
new file mode 100755 (executable)
index 0000000..7b5e051
--- /dev/null
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+# This file is part of util-linux.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# Copyright (C) 2026 Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
+TS_TOPDIR="${0%/*}/../.."
+TS_DESC="pidutils"
+
+. "$TS_TOPDIR/functions.sh"
+ts_init "$*"
+
+ts_check_test_command "$TS_HELPER_PARSEPID"
+ts_check_test_command "$TS_HELPER_STRERROR"
+
+ts_init_subtest "flag-unset"
+
+"$TS_HELPER_PARSEPID" 1 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" 1: >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" 1:0 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" 1:122 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" -- -1:122 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" -- -2147 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" '1:-122' >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" 2147 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" -- 0 >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+sed -i -e "s@$($TS_HELPER_STRERROR EINVAL)@EINVAL@" $TS_OUTPUT $TS_ERRLOG
+sed -i -e "s@$($TS_HELPER_STRERROR ERANGE)@ERANGE@" $TS_OUTPUT $TS_ERRLOG
+
+ts_finalize_subtest
+
+ts_init_subtest "flag-zero"
+
+"$TS_HELPER_PARSEPID" --zero 1 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero 1: >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero 1:0 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero 1:122 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero -- -1:122 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero -- -2147 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero '1:-122' >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero 2147 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero 0 >> $TS_OUTPUT 2>> $TS_ERRLOG
+sed -i -e "s@$($TS_HELPER_STRERROR EINVAL)@EINVAL@" $TS_OUTPUT $TS_ERRLOG
+sed -i -e "s@$($TS_HELPER_STRERROR ERANGE)@ERANGE@" $TS_OUTPUT $TS_ERRLOG
+
+ts_finalize_subtest
+
+ts_init_subtest "flag-negative"
+
+"$TS_HELPER_PARSEPID" --negative 1 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative 1: >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative -- -1:0 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative 1:122 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative '1:-122' >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative 1:0 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative -- -1:122 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative -- -2147 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative -- '-2147:78' >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative 2147 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --negative 0 >> $TS_OUTPUT 2>> $TS_ERRLOG
+sed -i -e "s@$($TS_HELPER_STRERROR EINVAL)@EINVAL@" $TS_OUTPUT $TS_ERRLOG
+sed -i -e "s@$($TS_HELPER_STRERROR ERANGE)@ERANGE@" $TS_OUTPUT $TS_ERRLOG
+
+
+ts_finalize_subtest
+
+ts_init_subtest "flag-zero-negative"
+
+"$TS_HELPER_PARSEPID" --zero --negative 1 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero --negative 1: >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero --negative -- -1443 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero --negative 1:0 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero --negative 1:122 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero --negative '1:-122' >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero --negative -- -1:122 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero --negative -- -2147 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero --negative 2147 >> $TS_OUTPUT 2>> $TS_ERRLOG
+"$TS_HELPER_PARSEPID" --zero --negative 0 >> $TS_OUTPUT 2>> $TS_ERRLOG
+sed -i -e "s@$($TS_HELPER_STRERROR EINVAL)@EINVAL@" $TS_OUTPUT $TS_ERRLOG
+sed -i -e "s@$($TS_HELPER_STRERROR ERANGE)@ERANGE@" $TS_OUTPUT $TS_ERRLOG
+
+
+ts_finalize_subtest
+
+
+ts_finalize