summaryrefslogtreecommitdiff
path: root/tests/strace--syscall-limit.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/strace--syscall-limit.c')
-rw-r--r--tests/strace--syscall-limit.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/tests/strace--syscall-limit.c b/tests/strace--syscall-limit.c
new file mode 100644
index 000000000..590ba6623
--- /dev/null
+++ b/tests/strace--syscall-limit.c
@@ -0,0 +1,107 @@
+/*
+ * Test -l/--syscall-limit options.
+ *
+ * Copyright (c) 2023 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#ifndef PRINT_VALID
+# define PRINT_VALID 1
+#endif
+
+static int
+write_status(const char *name, int value)
+{
+ FILE *fp = fopen(name, "w");
+ if (!fp)
+ perror_msg_and_fail("fopen: %s", name);
+ if (fprintf(fp, "%d\n", value) <= 0)
+ perror_msg_and_fail("fprintf: %s", name);
+ if (fclose(fp))
+ perror_msg_and_fail("fclose: %s", name);
+ fflush(stdout);
+ return value;
+}
+
+static const char valid_path[] = ".";
+static const char invalid_path[] = "invalid.dir";
+
+static void
+test_chdir(int pid, bool print)
+{
+ if (chdir(valid_path))
+ perror_msg_and_fail("chdir: %s", valid_path);
+
+ if (print) {
+#if PRINT_VALID
+ printf("%-5u chdir(\"%s\") = 0\n", pid, valid_path);
+#else
+ if (chdir(invalid_path) == 0)
+ error_msg_and_fail("chdir: %s", invalid_path);
+ printf("%-5u chdir(\"%s\") = %s\n", pid, invalid_path, sprintrc(-1));
+#endif
+ } else {
+ if (chdir(invalid_path) == 0)
+ error_msg_and_fail("chdir: %s", invalid_path);
+ }
+}
+
+static void
+test_rmdir(int pid, bool print)
+{
+ if (rmdir(invalid_path) == 0)
+ error_msg_and_fail("rmdir: %s", invalid_path);
+ if (print)
+ printf("%-5u rmdir(\"%s\") = %s\n", pid, invalid_path, sprintrc(-1));
+}
+
+int
+main(void)
+{
+ int pid = getpid();
+
+ test_chdir(pid, /* print */ true);
+
+ fflush(stdout);
+ pid_t child = fork();
+ if (child < 0)
+ perror_msg_and_fail("fork");
+
+ if (child == 0) {
+ int pid = getpid();
+
+ test_rmdir(pid, /* print */ true);
+ test_chdir(pid, /* print */ true);
+
+ /* the tracer is expected to detach at this point */
+
+ test_rmdir(pid, /* print */ false);
+
+ exit(0);
+ }
+
+ int status;
+ while ((waitpid(child, &status, 0)) != child) {
+ if (errno == EINTR)
+ continue;
+ perror_msg_and_fail("waitpid: %d", child);
+ }
+
+ /* the tracer is expected to detach at this point */
+
+ test_chdir(pid, /* print */ false);
+
+ return write_status("parent_status",
+ WIFEXITED(status) ? WEXITSTATUS(status) : 1);
+}