xref: /linux/tools/testing/selftests/acct/acct_syscall.c (revision 566ab427f827b0256d3e8ce0235d088e6a9c28bd)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 /* kselftest for acct() system call
4  *  The acct() system call enables or disables process accounting.
5  */
6 
7 #include <stdio.h>
8 #include <errno.h>
9 #include <string.h>
10 #include <sys/wait.h>
11 
12 #include "../kselftest.h"
13 
14 int main(void)
15 {
16 	char filename[] = "process_log";
17 	FILE *fp;
18 	pid_t child_pid;
19 	int sz;
20 
21 	// Setting up kselftest framework
22 	ksft_print_header();
23 	ksft_set_plan(1);
24 
25 	// Check if test is run a root
26 	if (geteuid()) {
27 		ksft_test_result_skip("This test needs root to run!\n");
28 		return 1;
29 	}
30 
31 	// Create file to log closed processes
32 	fp = fopen(filename, "w");
33 
34 	if (!fp) {
35 		ksft_test_result_error("%s.\n", strerror(errno));
36 		ksft_finished();
37 		return 1;
38 	}
39 
40 	acct(filename);
41 
42 	// Handle error conditions
43 	if (errno) {
44 		ksft_test_result_error("%s.\n", strerror(errno));
45 		fclose(fp);
46 		ksft_finished();
47 		return 1;
48 	}
49 
50 	// Create child process and wait for it to terminate.
51 
52 	child_pid = fork();
53 
54 	if (child_pid < 0) {
55 		ksft_test_result_error("Creating a child process to log failed\n");
56 		acct(NULL);
57 		return 1;
58 	} else if (child_pid > 0) {
59 		wait(NULL);
60 		fseek(fp, 0L, SEEK_END);
61 		sz = ftell(fp);
62 
63 		acct(NULL);
64 
65 		if (sz <= 0) {
66 			ksft_test_result_fail("Terminated child process not logged\n");
67 			ksft_exit_fail();
68 			return 1;
69 		}
70 
71 		ksft_test_result_pass("Successfully logged terminated process.\n");
72 		fclose(fp);
73 		ksft_exit_pass();
74 		return 0;
75 	}
76 
77 	return 1;
78 }
79