• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2016 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include "igt_core.h"
29 #include "drmtest.h"
30 
31 #include "igt_tests_common.h"
32 
33 int test;
34 int pipes[2];
35 
exit_handler1(int sig)36 static void exit_handler1(int sig)
37 {
38 	internal_assert(test == 1);
39 	test++;
40 }
41 
exit_handler2(int sig)42 static void exit_handler2(int sig)
43 {
44 	char tmp = 1;
45 
46 	/* ensure exit handlers are called in reverse */
47 	internal_assert(test == 0);
48 	test++;
49 
50 	/* we need to get a side effect to the parent to make sure exit handlers
51 	 * actually run. */
52 	internal_assert(write(pipes[1], &tmp, 1) == 1);
53 }
54 
55 enum test_type {
56 	SUC,
57 	NORMAL,
58 	FAIL,
59 	SKIP,
60 	SIG
61 };
62 
testfunc(enum test_type test_type)63 static int testfunc(enum test_type test_type)
64 {
65 	char prog[] = "igt_no_exit";
66 	char *fake_argv[] = {prog};
67 	int fake_argc = ARRAY_SIZE(fake_argv);
68 	pid_t pid;
69 	int status;
70 	char tmp = 0;
71 
72 	internal_assert(pipe2(pipes, O_NONBLOCK) == 0);
73 
74 	pid = fork();
75 
76 	if (pid == 0) {
77 		igt_subtest_init(fake_argc, fake_argv);
78 
79 		igt_fixture {
80 			/* register twice, should only be called once */
81 			igt_install_exit_handler(exit_handler1);
82 			igt_install_exit_handler(exit_handler1);
83 
84 			igt_install_exit_handler(exit_handler2);
85 		}
86 
87 		igt_subtest("subtest") {
88 			switch (test_type) {
89 			case SUC:
90 				igt_success();
91 			case FAIL:
92 				igt_fail(1);
93 			case SKIP:
94 				igt_skip("skip");
95 			case NORMAL:
96 				break;
97 			case SIG:
98 				raise(SIGTERM);
99 			}
100 		}
101 
102 		igt_exit();
103 	}
104 
105 	internal_assert(waitpid(pid, &status, 0) != -1);
106 
107 	internal_assert(read(pipes[0], &tmp, 1) == 1);
108 	internal_assert(tmp == 1);
109 
110 	return status;
111 }
112 
main(int argc,char ** argv)113 int main(int argc, char **argv)
114 {
115 	int status;
116 
117 	internal_assert(testfunc(SUC) == 0);
118 
119 	internal_assert(testfunc(NORMAL) == 0);
120 
121 	status = testfunc(FAIL);
122 	internal_assert_wexited(status, 1);
123 
124 	status = testfunc(SKIP);
125 	internal_assert_wexited(status, IGT_EXIT_SKIP);
126 
127 	status = testfunc(SIG);
128 	internal_assert_wsignaled(status, SIGTERM);
129 }
130