]> git.saurik.com Git - apple/security.git/blob - SecurityTests/regressions/test/testleaks.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / regressions / test / testleaks.c
1 /*
2 * Copyright (c) 2003-2006 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 *
23 * testleaks.c
24 */
25
26 #include <errno.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/wait.h>
31 #include <unistd.h>
32
33 #include "testleaks.h"
34 #include "testmore.h"
35
36 #if 0
37 static char *cf_user_text_encoding_var;
38 #endif
39
40 int
41 test_leaks(void)
42 {
43 return 0;
44 #if 0
45 int leaks = 0;
46 pid_t child;
47 pid_t parent;
48
49 setup("leaks");
50
51 /* Work around the fact that CF calls setenv, which leaks. */
52 cf_user_text_encoding_var = getenv("__CF_USER_TEXT_ENCODING");
53
54 ok_unix(parent = getpid(), "getpid");
55 int cld_stdout[2] = {};
56 ok_unix(child = pipe(cld_stdout), "pipe");
57 ok_unix(child = fork(), "fork");
58 switch (child)
59 {
60 case -1:
61 break;
62 case 0:
63 {
64 /* child. */
65
66 /* Set childs stdout and stderr to pipe. */
67 ok_unix(close(cld_stdout[0]), "close parent end of pipe");
68 ok_unix(dup2(cld_stdout[1], 1), "reopen stdout on pipe");
69 #if 0
70 ok_unix(dup2(cld_stdout[1], 2), "reopen stderr on pipe");
71 #endif
72
73 int argc = 0;
74 char *const *argv = NULL;
75 char **argvec = (char **)malloc((argc + 2) * sizeof(char *));
76 char pidstr[8];
77 int ix;
78
79 sprintf(pidstr, "%d", parent);
80 argvec[0] = "/usr/bin/leaks";
81 for (ix = 1; ix < argc; ++ix)
82 argvec[ix] = argv[ix];
83 argvec[ix] = pidstr;
84 argvec[ix + 1] = NULL;
85
86 ok_unix(execv(argvec[0], argvec), "execv");
87 _exit(1);
88 break;
89 }
90 default:
91 {
92 /* Parent. */
93 ok_unix(close(cld_stdout[1]), "close child end of pipe");
94
95 /* Set statemachine initial state to 0. */
96 int state = 0;
97 /* True iff the last char read was a newline. */
98 int newline = 1;
99 char buf[4098];
100 for (;;)
101 {
102 char *p = buf + 2;
103 ssize_t bytes_read;
104 bytes_read = read(cld_stdout[0], p, 4096);
105 if (bytes_read <= 0)
106 break;
107
108 int start = newline ? -2 : 0;
109 int ix = 0;
110 for (ix = 0; ix < bytes_read; ++ix)
111 {
112 /* Simple state machine for parsing leaks output.
113 * Looks for
114 * '[^\n]*\n[^:]*: ([0-9]*)'
115 * and sets leaks to atoi of the ([0-9]*) bit. */
116 switch (state)
117 {
118 case 0: if (p[ix] == '\n') state = 1; break;
119 case 1: if (p[ix] == ':') state = 2; break;
120 case 2: if (p[ix] == ' ') state = 3; break;
121 case 3:
122 if (p[ix] <= '0' || p[ix] >='9')
123 state = 4;
124 else
125 leaks = leaks * 10 + p[ix] - '0';
126 break;
127 case 4: break;
128 }
129
130 /* If there is a newline in the input or we are looking
131 at the last char of the buffer it's time to write the
132 output. */
133 if (p[ix] == '\n' || ix + 1 >= bytes_read)
134 {
135 /* If the previous char was a newline we prefix the
136 output with "# ". */
137 if (newline)
138 {
139 p[start] = '#';
140 p[start + 1] = ' ';
141 }
142 fwrite(p + start, ix + 1 - start, 1, stdout);
143 if (p[ix] == '\n')
144 {
145 start = ix - 1;
146 newline = 1;
147 }
148 else
149 newline = 0;
150 }
151 }
152 }
153
154 int status = 0;
155 for (;;)
156 {
157 /* Wait for the child to exit. */
158 pid_t waited_pid = waitpid(child, &status, 0);
159 if (waited_pid == -1)
160 {
161 int error = errno;
162 /* Keep going if we get interupted but bail out on any
163 other error. */
164 if (error == EINTR)
165 continue;
166
167 ok_unix(waited_pid, "waitpid");
168 break;
169 }
170
171 if (WIFEXITED(status))
172 {
173 is(WEXITSTATUS(status), 0, "leaks exit status");
174 break;
175 }
176 else if (WIFSIGNALED(status))
177 {
178 is(WTERMSIG(status), 0, "leaks terminated by");
179 break;
180 }
181 }
182 break;
183 }
184 }
185
186 return leaks;
187 #endif
188 }