Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162301209
D55482.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D55482.diff
View Options
diff --git a/lib/libc/tests/stdlib/Makefile b/lib/libc/tests/stdlib/Makefile
--- a/lib/libc/tests/stdlib/Makefile
+++ b/lib/libc/tests/stdlib/Makefile
@@ -17,6 +17,7 @@
ATF_TESTS_C+= qsort_bench
ATF_TESTS_C+= set_constraint_handler_s_test
ATF_TESTS_C+= strfmon_test
+ATF_TESTS_C+= system_test
ATF_TESTS_C+= tsearch_test
ATF_TESTS_CXX+= cxa_thread_atexit_test
ATF_TESTS_CXX+= cxa_thread_atexit_nothr_test
@@ -44,7 +45,6 @@
NETBSD_ATF_TESTS_C+= random_test
NETBSD_ATF_TESTS_C+= strtod_test
NETBSD_ATF_TESTS_C+= strtol_test
-NETBSD_ATF_TESTS_C+= system_test
# TODO: need to come up with a correct explanation of what the patch pho does
# with h_atexit
@@ -78,6 +78,7 @@
LIBADD.libc_exit_test+= pthread
LIBADD.strtod_test+= m
+LIBADD.system_test+= pthread
SUBDIR+= dynthr_mod
SUBDIR+= libatexit
diff --git a/lib/libc/tests/stdlib/system_test.c b/lib/libc/tests/stdlib/system_test.c
new file mode 100644
--- /dev/null
+++ b/lib/libc/tests/stdlib/system_test.c
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 2026 Klara, Inc.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+ATF_TC(system_true);
+ATF_TC_HEAD(system_true, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "system(\"true\")");
+}
+ATF_TC_BODY(system_true, tc)
+{
+ ATF_REQUIRE_EQ(W_EXITCODE(0, 0), system("true"));
+}
+
+ATF_TC(system_false);
+ATF_TC_HEAD(system_false, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "system(\"false\")");
+}
+ATF_TC_BODY(system_false, tc)
+{
+ ATF_REQUIRE_EQ(W_EXITCODE(1, 0), system("false"));
+}
+
+ATF_TC(system_touch);
+ATF_TC_HEAD(system_touch, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "system(\"touch file\")");
+}
+ATF_TC_BODY(system_touch, tc)
+{
+ /* The file does not exist */
+ ATF_CHECK_ERRNO(ENOENT, unlink("file"));
+
+ /* Run a command that creates it */
+ ATF_REQUIRE_EQ(W_EXITCODE(0, 0), system("touch file"));
+
+ /* Now the file exists */
+ ATF_CHECK_EQ(0, unlink("file"));
+}
+
+ATF_TC(system_null);
+ATF_TC_HEAD(system_null, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "system(NULL)");
+}
+ATF_TC_BODY(system_null, tc)
+{
+ ATF_REQUIRE_EQ(1, system(NULL));
+}
+
+/*
+ * Define PROCMASK_IS_THREADMASK if sigprocmask() gets / sets the thread
+ * mask in multithreaded programs, which makes it impossible to verify
+ * that system(3) correctly blocks and unblocks SIGCHLD.
+ */
+#ifdef __FreeBSD__
+#define PROCMASK_IS_THREADMASK 1
+#endif
+
+static void *
+system_thread(void *arg)
+{
+ char cmd[64];
+ int i = (int)(intptr_t)arg;
+
+ snprintf(cmd, sizeof(cmd), "rm flag%d ; lockf -ns lock%d true", i, i);
+ return ((void *)(intptr_t)system(cmd));
+}
+
+ATF_TC(system_concurrent);
+ATF_TC_HEAD(system_concurrent, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Concurrent calls");
+}
+ATF_TC_BODY(system_concurrent, tc)
+{
+#define N 3
+ sigset_t normset, sigset;
+ pthread_t thr[N];
+ char fn[8];
+ int fd[N];
+ void *arg, *ret;
+
+ /* Create and lock the locks */
+ for (int i = 0; i < N; i++) {
+ snprintf(fn, sizeof(fn), "lock%d", i);
+ fd[i] = open(fn, O_CREAT|O_EXCL|O_EXLOCK|O_CLOEXEC, 0644);
+ ATF_REQUIRE_MSG(fd[i] >= 0, "%s: %m", fn);
+ }
+
+ /* Create the flags */
+ for (int i = 0; i < N; i++) {
+ snprintf(fn, sizeof(fn), "flag%d", i);
+ ATF_REQUIRE_EQ(0, symlink(fn, fn));
+ }
+
+ /* Get the current and expected signal mask */
+ sigprocmask(0, NULL, &normset);
+
+ /* Spawn threads which block on these files */
+ for (int i = 0; i < N; i++) {
+ arg = (void *)(intptr_t)i;
+ ATF_REQUIRE_INTEQ(0,
+ pthread_create(&thr[i], NULL, system_thread, arg));
+ }
+
+ /* Wait until the flags are gone */
+ for (int i = 0; i < N; i++) {
+ snprintf(fn, sizeof(fn), "flag%d", i);
+ while (readlink(fn, fn, sizeof(fn)) > 0)
+ usleep(10000);
+ ATF_REQUIRE_EQ(ENOENT, errno);
+ }
+
+ /* Release the locks */
+ for (int i = 0; i < N; i++) {
+ /* Check the signal dispositions */
+ ATF_CHECK_EQ(SIG_IGN, signal(SIGINT, SIG_IGN));
+ ATF_CHECK_EQ(SIG_IGN, signal(SIGQUIT, SIG_IGN));
+#ifndef PROCMASK_IS_THREADMASK
+ sigprocmask(0, NULL, &sigset);
+ ATF_CHECK(sigismember(&sigset, SIGCHLD));
+#endif
+
+ /* Close the file, releasing the lock */
+ ATF_REQUIRE_INTEQ(0, close(fd[i]));
+
+ /* Join the thread and check the return value */
+ ATF_CHECK_INTEQ(0, pthread_join(thr[i], &ret));
+ ATF_CHECK_INTEQ(W_EXITCODE(0, 0), (int)(intptr_t)ret);
+ }
+
+ /* Check the signal dispositions */
+ ATF_CHECK_EQ(SIG_DFL, signal(SIGINT, SIG_DFL));
+ ATF_CHECK_EQ(SIG_DFL, signal(SIGQUIT, SIG_DFL));
+ sigprocmask(0, NULL, &sigset);
+ ATF_CHECK_EQ(0, memcmp(&sigset, &normset, sizeof(sigset_t)));
+#undef N
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, system_true);
+ ATF_TP_ADD_TC(tp, system_false);
+ ATF_TP_ADD_TC(tp, system_touch);
+ ATF_TP_ADD_TC(tp, system_null);
+ ATF_TP_ADD_TC(tp, system_concurrent);
+ return (atf_no_error());
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jul 12, 8:36 PM (20 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35010840
Default Alt Text
D55482.diff (4 KB)
Attached To
Mode
D55482: system(3): Write our own tests
Attached
Detach File
Event Timeline
Log In to Comment